Browse Source

ci: skip build on doc only changes (#20717)

* ci: skip build on doc only changes

* Try using exit codes on doc-only-change

* Fixup

* Fixup circleci doc-only check

* Update appveyor.yml

Co-Authored-By: Samuel Attard <[email protected]>

* Properly detect doc only change on Windows

* Flip exit code per review

* build: fix doc only change when there isn't a PR (#20749)

* build: fix doc only change when there isn't a PR

Fixes issue where CI was mistakenly marking a PR as a doc only change because the CI was kicked off before the PR was created.

(cherry picked from commit 73da4b721513f3d947746371e20e782603b1eaab)
trop[bot] 5 years ago
parent
commit
a8e7696674
3 changed files with 170 additions and 0 deletions
  1. 106 0
      .circleci/config.yml
  2. 6 0
      appveyor.yml
  3. 58 0
      script/doc-only-change.js

+ 106 - 0
.circleci/config.yml

@@ -704,6 +704,51 @@ step-save-src-cache: &step-save-src-cache
     key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
     name: Persisting src cache
 
+# Check for doc only change
+step-check-for-doc-only-change: &step-check-for-doc-only-change
+  run:
+    name: Check if commit is doc only change
+    command: |
+      cd src/electron
+      node script/yarn install --frozen-lockfile
+      if node script/doc-only-change.js --prNumber=$CIRCLE_PR_NUMBER --prURL=$CIRCLE_PULL_REQUEST; then
+        #PR is doc only change; save file with value true to indicate doc only change
+        echo "true" > .skip-ci-build
+      else
+        #PR is not a doc only change; create empty file to indicate check has been done
+        touch .skip-ci-build
+      fi
+
+step-persist-doc-only-change: &step-persist-doc-only-change
+  persist_to_workspace:
+    root: .
+    paths:
+      - src/electron/.skip-ci-build
+
+step-maybe-early-exit-doc-only-change: &step-maybe-early-exit-doc-only-change
+  run:
+    name: Shortcircuit build if doc only change
+    command: |
+      if [ -s src/electron/.skip-ci-build ]; then
+        circleci-agent step halt
+      fi
+
+step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
+  run:
+    name: Shortcircuit job if change is not doc only
+    command: |
+      if [ ! -s src/electron/.skip-ci-build ]; then
+        circleci-agent step halt
+      fi
+
+step-ts-compile: &step-ts-compile
+  run:
+    name: Run TS/JS compile on doc only change
+    command: |
+      cd src
+      ninja -C out/Default electron:default_app_js -j $NUMBER_OF_NINJA_PROCESSES
+      ninja -C out/Default electron:atom_js2c -j $NUMBER_OF_NINJA_PROCESSES
+
 # Lists of steps.
 steps-lint: &steps-lint
   steps:
@@ -752,6 +797,9 @@ steps-lint: &steps-lint
 steps-checkout-fast: &steps-checkout-fast
   steps:
     - *step-checkout-electron
+    - *step-check-for-doc-only-change
+    - *step-persist-doc-only-change
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-get
     - *step-depot-tools-add-to-path
     - *step-restore-brew-cache
@@ -783,6 +831,9 @@ steps-checkout-fast: &steps-checkout-fast
 steps-checkout-and-save-cache: &steps-checkout-and-save-cache
   steps:
     - *step-checkout-electron
+    - *step-check-for-doc-only-change
+    - *step-persist-doc-only-change
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-get
     - *step-depot-tools-add-to-path
     - *step-restore-brew-cache
@@ -813,6 +864,7 @@ steps-electron-gn-check: &steps-electron-gn-check
   steps:
     - attach_workspace:
         at: .
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-add-to-path
     - *step-setup-env-for-build
     - *step-gn-gen-default
@@ -822,6 +874,7 @@ steps-electron-build: &steps-electron-build
   steps:
     - attach_workspace:
         at: .
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-add-to-path
     - *step-setup-env-for-build
     - *step-restore-brew-cache
@@ -875,6 +928,9 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
   steps:
     # Checkout - Copied ffrom steps-checkout
     - *step-checkout-electron
+    - *step-check-for-doc-only-change
+    - *step-persist-doc-only-change
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-get
     - *step-depot-tools-add-to-path
     - *step-restore-brew-cache
@@ -946,6 +1002,45 @@ steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-
 
     - *step-maybe-notify-slack-failure
 
+steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
+  steps:
+    # Checkout - Copied ffrom steps-checkout
+    - *step-checkout-electron
+    - *step-check-for-doc-only-change
+    - *step-maybe-early-exit-no-doc-change
+    - *step-depot-tools-get
+    - *step-depot-tools-add-to-path
+    - *step-restore-brew-cache
+    - *step-get-more-space-on-mac
+    - *step-install-gnutar-on-mac
+    - *step-generate-deps-hash
+    - *step-touch-sync-done
+    - *step-maybe-restore-src-cache
+    - *step-maybe-restore-git-cache
+    - *step-set-git-cache-path
+    # This sync call only runs if .circle-sync-done is an EMPTY file
+    - *step-gclient-sync
+    # These next few steps reset Electron to the correct commit regardless of which cache was restored
+    - run:
+        name: Wipe Electron
+        command: rm -rf src/electron
+    - *step-checkout-electron
+    - *step-run-electron-only-hooks
+    - *step-generate-deps-hash-cleanly
+    - *step-mark-sync-done
+    - *step-minimize-workspace-size-from-checkout
+
+    - *step-depot-tools-add-to-path
+    - *step-setup-env-for-build
+    - *step-restore-brew-cache
+    - *step-get-more-space-on-mac
+    - *step-install-npm-deps-on-mac
+    - *step-fix-sync-on-mac
+    - *step-gn-gen-default
+
+    #Compile ts/js to verify doc change didn't break anything
+    - *step-ts-compile
+
 steps-electron-build-for-publish: &steps-electron-build-for-publish
   steps:
     - *step-checkout-electron
@@ -1064,6 +1159,7 @@ steps-tests: &steps-tests
   steps:
     - attach_workspace:
         at: .
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-add-to-path
     - *step-electron-dist-unzip
     - *step-mksnapshot-unzip
@@ -1106,6 +1202,7 @@ steps-test-nan: &steps-test-nan
   steps:
     - attach_workspace:
           at: .
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-add-to-path
     - *step-electron-dist-unzip
     - *step-setup-linux-for-headless-testing
@@ -1121,6 +1218,7 @@ steps-test-node: &steps-test-node
   steps:
     - attach_workspace:
           at: .
+    - *step-maybe-early-exit-doc-only-change
     - *step-depot-tools-add-to-path
     - *step-electron-dist-unzip
     - *step-setup-linux-for-headless-testing
@@ -1146,6 +1244,13 @@ jobs:
       <<: *env-linux-medium
     <<: *steps-lint
 
+  ts-compile-doc-change:
+    <<: *machine-linux-medium
+    environment:
+      <<: *env-linux-medium
+      <<: *env-testing-build
+    <<: *steps-electron-ts-compile-for-doc-change
+
   # Layer 1: Checkout.
   linux-checkout-fast:
     <<: *machine-linux-2xlarge
@@ -1917,6 +2022,7 @@ workflows:
       - linux-arm64-testing-gn-check:
           requires:
             - linux-checkout-fast
+      - ts-compile-doc-change
 
   build-mac:
     when: << pipeline.parameters.run-build-mac >>

+ 6 - 0
appveyor.yml

@@ -50,6 +50,12 @@ build_script:
   - ps: >-
       if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
         Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
+      } else {
+        node script/yarn.js install --frozen-lockfile
+
+        if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
+          Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
+        }
       }
   - echo "Building $env:GN_CONFIG build"
   - git config --global core.longpaths true

+ 58 - 0
script/doc-only-change.js

@@ -0,0 +1,58 @@
+const args = require('minimist')(process.argv.slice(2))
+const octokit = require('@octokit/rest')()
+const path = require('path')
+
+const SOURCE_ROOT = path.normalize(path.dirname(__dirname))
+
+async function checkIfDocOnlyChange () {
+  if (args.prNumber || args.prBranch || args.prURL) {
+    try {
+      let pullRequestNumber = args.prNumber
+      if (!pullRequestNumber || isNaN(pullRequestNumber)) {
+        if (args.prBranch) {
+          // AppVeyor doesn't provide a PR number for branch builds - figure it out from the branch
+          const prsForBranch = await octokit.pulls.list({
+            owner: 'electron',
+            repo: 'electron',
+            state: 'open',
+            head: `electron:${args.prBranch}`
+          })
+          if (prsForBranch.data.length === 1) {
+            pullRequestNumber = prsForBranch.data[0].number
+          } else {
+            // If there are 0 PRs or more than one PR on a branch, just assume that this is more than a doc change
+            process.exit(1)
+          }
+        } else if (args.prURL) {
+          // CircleCI doesn't provide the PR number for branch builds, but it does provide the PR URL
+          const pullRequestParts = args.prURL.split('/')
+          pullRequestNumber = pullRequestParts[pullRequestParts.length - 1]
+        }
+      }
+      const filesChanged = await octokit.pulls.listFiles({
+        owner: 'electron', repo: 'electron', pull_number: pullRequestNumber
+      })
+
+      const nonDocChange = filesChanged.data.find((fileInfo) => {
+        const fileDirs = fileInfo.filename.split('/')
+        if (fileDirs[0] !== 'docs') {
+          return true
+        }
+      })
+      if (nonDocChange) {
+        process.exit(1)
+      } else {
+        process.exit(0)
+      }
+    } catch (ex) {
+      console.error('Error getting list of files changed: ', ex)
+      process.exit(-1)
+    }
+  } else {
+    console.error(`Check if only the docs were changed for a commit.
+    Usage: doc-only-change.js --prNumber=PR_NUMBER || --prBranch=PR_BRANCH || --prURL=PR_URL`)
+    process.exit(-1)
+  }
+}
+
+checkIfDocOnlyChange()