Browse Source

Release process updates for 1-7-x (#10643)

* Add prerelease script

* Update CircleCI for releases

* Rerun builds
John Kleinschmidt 7 years ago
parent
commit
1d0dfd590b
3 changed files with 277 additions and 3 deletions
  1. 162 3
      .circleci/config.yml
  2. 3 0
      package.json
  3. 112 0
      script/prerelease.js

+ 162 - 3
.circleci/config.yml

@@ -6,27 +6,186 @@ jobs:
       - image: electronbuilds/electron:0.0.3
         environment:
           TARGET_ARCH: arm
+    resource_class: xlarge
     steps:
       - checkout
-      - run: script/cibuild
+      - run: sh -e /etc/init.d/xvfb start
+      - run:
+          name: Check for release
+          command: |
+            MESSAGE="$(git log --format=%B -n 1 HEAD)"
+            case ${MESSAGE} in
+              Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
+            esac
+      - run:
+         name: Bootstrap
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Bootstrapping Electron for release build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH
+           else
+              echo 'Bootstrapping Electron for debug build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH --dev
+           fi
+      - run: npm run lint
+      - run:
+         name: Build
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Building Electron for release'
+              script/build.py -c R
+           else
+              echo 'Building Electron for debug'
+              script/build.py -c D
+           fi
+      - run:
+          name: Create distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Creating Electron release distribution'
+                script/create-dist.py
+             else
+                echo 'Skipping create distribution because build is not for release'
+             fi
+      - run:
+          name: Upload distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Uploading Electron release distribution'
+                script/upload.py
+             else
+                echo 'Skipping upload distribution because build is not for release'
+             fi
 
   electron-linux-ia32:
     docker:
       - image: electronbuilds/electron:0.0.3
         environment:
           TARGET_ARCH: ia32
+    resource_class: xlarge
     steps:
       - checkout
-      - run: script/cibuild
+      - run: sh -e /etc/init.d/xvfb start
+      - run:
+          name: Check for release
+          command: |
+            MESSAGE="$(git log --format=%B -n 1 HEAD)"
+            case ${MESSAGE} in
+              Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
+            esac
+      - run:
+         name: Bootstrap
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Bootstrapping Electron for release build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH
+           else
+              echo 'Bootstrapping Electron for debug build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH --dev
+           fi
+      - run: npm run lint
+      - run:
+         name: Build
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Building Electron for release'
+              script/build.py -c R
+           else
+              echo 'Building Electron for debug'
+              script/build.py -c D
+           fi
+      - run:
+          name: Create distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Creating Electron release distribution'
+                script/create-dist.py
+             else
+                echo 'Skipping create distribution because build is not for release'
+             fi
+      - run:
+          name: Upload distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Uploading Electron release distribution'
+                script/upload.py
+             else
+                echo 'Skipping upload distribution because build is not for release'
+             fi
 
   electron-linux-x64:
     docker:
       - image: electronbuilds/electron:0.0.3
         environment:
           TARGET_ARCH: x64
+    resource_class: xlarge
     steps:
       - checkout
-      - run: script/cibuild
+      - run: sh -e /etc/init.d/xvfb start
+      - run:
+          name: Check for release
+          command: |
+            MESSAGE="$(git log --format=%B -n 1 HEAD)"
+            case ${MESSAGE} in
+              Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
+            esac
+      - run:
+         name: Bootstrap
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Bootstrapping Electron for release build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH
+           else
+              echo 'Bootstrapping Electron for debug build'
+              script/bootstrap.py --target_arch=$TARGET_ARCH --dev
+           fi
+      - run: npm run lint
+      - run:
+         name: Build
+         command: |
+           if [ "$ELECTRON_RELEASE" == "1" ]; then
+              echo 'Building Electron for release'
+              script/build.py -c R
+           else
+              echo 'Building Electron for debug'
+              script/build.py -c D
+           fi
+      - run:
+          name: Create distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Creating Electron release distribution'
+                script/create-dist.py
+             else
+                echo 'Skipping create distribution because build is not for release'
+             fi
+      - run:
+          name: Upload distribution
+          command: |
+             if [ "$ELECTRON_RELEASE" == "1" ]; then
+                echo 'Uploading Electron release distribution'
+                script/upload.py
+             else
+                echo 'Skipping upload distribution because build is not for release'
+             fi
+      - run:
+          name: Test
+          command: |
+             if [ "$ELECTRON_RELEASE" != "1" ]; then
+                echo 'Testing Electron debug build'
+                script/test.py --ci --rebuild_native_modules
+             else
+                echo 'Skipping testing on release build'
+             fi
+      - run:
+          name: Verify FFmpeg
+          command: |
+             if [ "$ELECTRON_RELEASE" != "1" ]; then
+                echo 'Verifying ffmpeg on debug build'
+                script/verify-ffmpeg.py
+             else
+                echo 'Skipping verify ffmpeg on release build'
+             fi
 
 workflows:
   version: 2

+ 3 - 0
package.json

@@ -6,12 +6,14 @@
   "devDependencies": {
     "asar": "^0.11.0",
     "browserify": "^13.1.0",
+    "colors": "^1.1.2",
     "check-for-leaks": "^1.0.2",
     "dotenv-safe": "^4.0.4",
     "electabul": "~0.0.4",
     "electron-docs-linter": "^2.3.3",
     "electron-typescript-definitions": "^1.2.7",
     "github": "^9.2.0",
+    "heads": "^1.3.0",
     "husky": "^0.14.3",
     "request": "^2.68.0",
     "standard": "^8.4.0",
@@ -48,6 +50,7 @@
     "create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version",
     "create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts",
     "preinstall": "node -e 'process.exit(0)'",
+    "prerelease": "node ./script/prerelease",
     "publish-to-npm": "node ./script/publish-to-npm.js",
     "prepack": "check-for-leaks",
     "prepush": "check-for-leaks",

+ 112 - 0
script/prerelease.js

@@ -0,0 +1,112 @@
+#!/usr/bin/env node
+
+require('colors')
+const assert = require('assert')
+const GitHub = require('github')
+const heads = require('heads')
+const pkg = require('../package.json')
+const pass = '\u2713'.green
+const fail = '\u2717'.red
+let failureCount = 0
+
+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment')
+
+const github = new GitHub()
+github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
+github.repos.getReleases({owner: 'electron', repo: 'electron'})
+  .then(res => {
+    const releases = res.data
+    const drafts = releases
+      .filter(release => release.draft) // comment out for testing
+      // .filter(release => release.tag_name === 'v1.7.5') // uncomment for testing
+
+    check(drafts.length === 1, 'one draft exists', true)
+    const draft = drafts[0]
+
+    check(draft.tag_name === `v${pkg.version}`, `draft release version matches local package.json (v${pkg.version})`)
+    check(draft.prerelease, 'draft is a prerelease')
+    check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes')
+
+    const requiredAssets = assetsForVersion(draft.tag_name).sort()
+    const extantAssets = draft.assets.map(asset => asset.name).sort()
+
+    requiredAssets.forEach(asset => {
+      check(extantAssets.includes(asset), asset)
+    })
+
+    const s3Urls = s3UrlsForVersion(draft.tag_name)
+    heads(s3Urls)
+      .then(results => {
+        results.forEach((result, i) => {
+          check(result === 200, s3Urls[i])
+        })
+
+        process.exit(failureCount > 0 ? 1 : 0)
+      })
+      .catch(err => {
+        console.error('Error making HEAD requests for S3 assets')
+        console.error(err)
+        process.exit(1)
+      })
+  })
+
+function check (condition, statement, exitIfFail = false) {
+  if (condition) {
+    console.log(`${pass} ${statement}`)
+  } else {
+    failureCount++
+    console.log(`${fail} ${statement}`)
+    if (exitIfFail) process.exit(1)
+  }
+}
+
+function assetsForVersion (version) {
+  const patterns = [
+    'electron-{{VERSION}}-darwin-x64-dsym.zip',
+    'electron-{{VERSION}}-darwin-x64-symbols.zip',
+    'electron-{{VERSION}}-darwin-x64.zip',
+    'electron-{{VERSION}}-linux-arm-symbols.zip',
+    'electron-{{VERSION}}-linux-arm.zip',
+    'electron-{{VERSION}}-linux-armv7l-symbols.zip',
+    'electron-{{VERSION}}-linux-armv7l.zip',
+    'electron-{{VERSION}}-linux-ia32-symbols.zip',
+    'electron-{{VERSION}}-linux-ia32.zip',
+    'electron-{{VERSION}}-linux-x64-symbols.zip',
+    'electron-{{VERSION}}-linux-x64.zip',
+    'electron-{{VERSION}}-mas-x64-dsym.zip',
+    'electron-{{VERSION}}-mas-x64-symbols.zip',
+    'electron-{{VERSION}}-mas-x64.zip',
+    'electron-{{VERSION}}-win32-ia32-pdb.zip',
+    'electron-{{VERSION}}-win32-ia32-symbols.zip',
+    'electron-{{VERSION}}-win32-ia32.zip',
+    'electron-{{VERSION}}-win32-x64-pdb.zip',
+    'electron-{{VERSION}}-win32-x64-symbols.zip',
+    'electron-{{VERSION}}-win32-x64.zip',
+    'electron-api.json',
+    'electron.d.ts',
+    'ffmpeg-{{VERSION}}-darwin-x64.zip',
+    'ffmpeg-{{VERSION}}-linux-arm.zip',
+    'ffmpeg-{{VERSION}}-linux-armv7l.zip',
+    'ffmpeg-{{VERSION}}-linux-ia32.zip',
+    'ffmpeg-{{VERSION}}-linux-x64.zip',
+    'ffmpeg-{{VERSION}}-mas-x64.zip',
+    'ffmpeg-{{VERSION}}-win32-ia32.zip',
+    'ffmpeg-{{VERSION}}-win32-x64.zip'
+  ]
+  return patterns.map(pattern => pattern.replace(/{{VERSION}}/g, version))
+}
+
+function s3UrlsForVersion (version) {
+  const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/'
+  const patterns = [
+    'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}-headers.tar.gz',
+    'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}.tar.gz',
+    'atom-shell/dist/{{VERSION}}/node-{{VERSION}}.tar.gz',
+    'atom-shell/dist/{{VERSION}}/node.lib',
+    'atom-shell/dist/{{VERSION}}/win-x64/iojs.lib',
+    'atom-shell/dist/{{VERSION}}/win-x86/iojs.lib',
+    'atom-shell/dist/{{VERSION}}/x64/node.lib',
+    'atom-shell/dist/index.json'
+  ]
+  return patterns.map(pattern => bucket + pattern.replace(/{{VERSION}}/g, version))
+}