From 14447a99b319ab295e2198844e3ccd6badb1cd2c Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 31 Aug 2020 01:37:02 +0200 Subject: [PATCH 01/12] Create CI workflow with GH Actions (#188) --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8d60e42 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +# This workflow will install the node_modules, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Continuous Integration + +on: + - push + - pull_request + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [8.x, 14.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Configure yarn cache path + run: yarn config set cache-folder ~/.yarn-cache + - name: Restore yarn cache + uses: actions/cache@v2 + with: + path: ~/.yarn-cache + key: yarn-cache-${{ matrix.node-version }} + restore-keys: | + yarn-cache- + - name: Restore node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node-modules-${{ matrix.node-version }}-${{ hashFiles('yarn.lock') }} + restore-keys: | + node-modules-${{ matrix.node-version }}- + node-modules- + - name: Install dependencies + run: yarn + - name: Run linter, concat, minifier and tests + run: yarn dist From d10c99de8b8a5342125928cfd265d418149838e1 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 31 Aug 2020 01:45:06 +0200 Subject: [PATCH 02/12] Install node_modules with --ignore-engines (#188) This prevents backwards-incompatible devDependencies from breaking the build. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d60e42..86497b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,6 @@ jobs: node-modules-${{ matrix.node-version }}- node-modules- - name: Install dependencies - run: yarn + run: yarn --ignore-engines - name: Run linter, concat, minifier and tests run: yarn dist From 242a640a130768b1331fbb93d3e05f449f50260d Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 31 Aug 2020 02:28:28 +0200 Subject: [PATCH 03/12] Raise the bar (replace node 8 by node 10) (#188) I'd prefer node 8 for checking backwards-compatibility, but our devDependencies really won't have it. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86497b8..65b0b44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: - node-version: [8.x, 14.x] + node-version: [10.x, 14.x] steps: - uses: actions/checkout@v2 @@ -40,6 +40,6 @@ jobs: node-modules-${{ matrix.node-version }}- node-modules- - name: Install dependencies - run: yarn --ignore-engines + run: yarn - name: Run linter, concat, minifier and tests run: yarn dist From 83249d73bb3abd647ed92e784bd2784b8383190e Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 31 Aug 2020 02:32:41 +0200 Subject: [PATCH 04/12] Drop the .travis.yml (#188) --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f714fc0..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js - -node_js: - - "0.10" \ No newline at end of file From 2ecfd1a89a0a70d819b47ad4ff5b9c84e64ce0ed Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 26 Oct 2020 17:07:02 +0100 Subject: [PATCH 05/12] Factor out the bootstrapping steps into a reusable action (#188) --- .github/actions/bootstrap/action.yml | 31 ++++++++++++++++++++++++++++ .github/workflows/ci.yml | 22 +------------------- 2 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 .github/actions/bootstrap/action.yml diff --git a/.github/actions/bootstrap/action.yml b/.github/actions/bootstrap/action.yml new file mode 100644 index 0000000..ee425cb --- /dev/null +++ b/.github/actions/bootstrap/action.yml @@ -0,0 +1,31 @@ +name: CI/CD Base Setup +description: Perform basic cache restoration and node+yarn install steps +inputs: + node-version: + description: Node.js version to run with + required: true + default: 14.x +runs: + - name: Use Node.js ${{ inputs.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ inputs.node-version }} + - name: Configure yarn cache path + run: yarn config set cache-folder ~/.yarn-cache + - name: Restore yarn cache + uses: actions/cache@v2 + with: + path: ~/.yarn-cache + key: yarn-cache-${{ inputs.node-version }} + restore-keys: | + yarn-cache- + - name: Restore node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node-modules-${{ inputs.node-version }}-${{ hashFiles('yarn.lock') }} + restore-keys: | + node-modules-${{ inputs.node-version }}- + node-modules- + - name: Install dependencies + run: yarn diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65b0b44..3d4cd1c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,28 +18,8 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: ./.github/actions/bootstrap with: node-version: ${{ matrix.node-version }} - - name: Configure yarn cache path - run: yarn config set cache-folder ~/.yarn-cache - - name: Restore yarn cache - uses: actions/cache@v2 - with: - path: ~/.yarn-cache - key: yarn-cache-${{ matrix.node-version }} - restore-keys: | - yarn-cache- - - name: Restore node_modules - uses: actions/cache@v2 - with: - path: node_modules - key: node-modules-${{ matrix.node-version }}-${{ hashFiles('yarn.lock') }} - restore-keys: | - node-modules-${{ matrix.node-version }}- - node-modules- - - name: Install dependencies - run: yarn - name: Run linter, concat, minifier and tests run: yarn dist From 9f9f7d3c2a112cfbe142f69cb676353e48b7193d Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 26 Oct 2020 17:12:22 +0100 Subject: [PATCH 06/12] Fix the action syntax (#188) --- .github/actions/bootstrap/action.yml | 48 +++++++++++++++------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/.github/actions/bootstrap/action.yml b/.github/actions/bootstrap/action.yml index ee425cb..ecbb11f 100644 --- a/.github/actions/bootstrap/action.yml +++ b/.github/actions/bootstrap/action.yml @@ -6,26 +6,28 @@ inputs: required: true default: 14.x runs: - - name: Use Node.js ${{ inputs.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ inputs.node-version }} - - name: Configure yarn cache path - run: yarn config set cache-folder ~/.yarn-cache - - name: Restore yarn cache - uses: actions/cache@v2 - with: - path: ~/.yarn-cache - key: yarn-cache-${{ inputs.node-version }} - restore-keys: | - yarn-cache- - - name: Restore node_modules - uses: actions/cache@v2 - with: - path: node_modules - key: node-modules-${{ inputs.node-version }}-${{ hashFiles('yarn.lock') }} - restore-keys: | - node-modules-${{ inputs.node-version }}- - node-modules- - - name: Install dependencies - run: yarn + using: composite + steps: + - name: Use Node.js ${{ inputs.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ inputs.node-version }} + - name: Configure yarn cache path + run: yarn config set cache-folder ~/.yarn-cache + - name: Restore yarn cache + uses: actions/cache@v2 + with: + path: ~/.yarn-cache + key: yarn-cache-${{ inputs.node-version }} + restore-keys: | + yarn-cache- + - name: Restore node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node-modules-${{ inputs.node-version }}-${{ hashFiles('yarn.lock') }} + restore-keys: | + node-modules-${{ inputs.node-version }}- + node-modules- + - name: Install dependencies + run: yarn From fe7c0430010566a070b216ef0299227a3586ed59 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 26 Oct 2020 17:31:01 +0100 Subject: [PATCH 07/12] Revert "Factor out the bootstrapping steps into a reusable action (#188)" This reverts the previous two commits, because I learned the hard way that actions cannot be composed out of other actions. --- .github/actions/bootstrap/action.yml | 33 ---------------------------- .github/workflows/ci.yml | 22 ++++++++++++++++++- 2 files changed, 21 insertions(+), 34 deletions(-) delete mode 100644 .github/actions/bootstrap/action.yml diff --git a/.github/actions/bootstrap/action.yml b/.github/actions/bootstrap/action.yml deleted file mode 100644 index ecbb11f..0000000 --- a/.github/actions/bootstrap/action.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CI/CD Base Setup -description: Perform basic cache restoration and node+yarn install steps -inputs: - node-version: - description: Node.js version to run with - required: true - default: 14.x -runs: - using: composite - steps: - - name: Use Node.js ${{ inputs.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ inputs.node-version }} - - name: Configure yarn cache path - run: yarn config set cache-folder ~/.yarn-cache - - name: Restore yarn cache - uses: actions/cache@v2 - with: - path: ~/.yarn-cache - key: yarn-cache-${{ inputs.node-version }} - restore-keys: | - yarn-cache- - - name: Restore node_modules - uses: actions/cache@v2 - with: - path: node_modules - key: node-modules-${{ inputs.node-version }}-${{ hashFiles('yarn.lock') }} - restore-keys: | - node-modules-${{ inputs.node-version }}- - node-modules- - - name: Install dependencies - run: yarn diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d4cd1c..65b0b44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,28 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: ./.github/actions/bootstrap + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} + - name: Configure yarn cache path + run: yarn config set cache-folder ~/.yarn-cache + - name: Restore yarn cache + uses: actions/cache@v2 + with: + path: ~/.yarn-cache + key: yarn-cache-${{ matrix.node-version }} + restore-keys: | + yarn-cache- + - name: Restore node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node-modules-${{ matrix.node-version }}-${{ hashFiles('yarn.lock') }} + restore-keys: | + node-modules-${{ matrix.node-version }}- + node-modules- + - name: Install dependencies + run: yarn - name: Run linter, concat, minifier and tests run: yarn dist From e8430a9716fe3d0f8e1d326391bb7f16daf81ef5 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Mon, 26 Oct 2020 17:39:59 +0100 Subject: [PATCH 08/12] Use the push event to trigger CI only on master (#188) On other branches, CI will either trigger anyway because of the PR event, or be redundant because of the upcoming CD workflow (on prepublish and gh-pages). --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65b0b44..971c9d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,8 +4,9 @@ name: Continuous Integration on: - - push - - pull_request + push: + branches: [master] + pull_request: jobs: build: From bdece4d9aba58d18a241b0182d955a78b1177df1 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Thu, 29 Oct 2020 22:37:01 +0100 Subject: [PATCH 09/12] Add the continuous deployment workflow (#188 #228) --- .github/workflows/cd.yml | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..5debe80 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,64 @@ +# This workflow is like CI, but also builds the documentation and deploys to NPM +# and gh-pages. + +name: Continuous Deployment + +on: + push: + branches: [prepublish] + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: Configure yarn cache path + run: yarn config set cache-folder ~/.yarn-cache + - name: Restore yarn cache + uses: actions/cache@v2 + with: + path: ~/.yarn-cache + key: yarn-cache-14.x + restore-keys: | + yarn-cache- + - name: Restore node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node-modules-14.x-${{ hashFiles('yarn.lock') }} + restore-keys: | + node-modules-14.x- + node-modules- + - name: Install dependencies + run: yarn + - name: Build dist files and docs and run the tests + run: yarn grunt dist docco tocdoc + - name: Commit the build output + uses: EndBug/add-and-commit@v5 + with: + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Publish to NPM + run: yarn publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Merge into gh-pages + uses: devmasx/merge-branch@v1.3.0 + with: + type: now + target_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2 + with: + ref: gh-pages + - name: Tag the release + uses: Klemensas/action-autotag@stable + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + tag_prefix: v From 92cf2629a2cf2988d3b11666b38990c324284ee1 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Fri, 30 Oct 2020 00:58:53 +0100 Subject: [PATCH 10/12] Add an experimental workflow for automatic prepublish staging #188 #228 --- .github/workflows/cd.yml | 3 +++ .github/workflows/prepublish.yml | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 .github/workflows/prepublish.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 5debe80..6e33d53 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -6,6 +6,9 @@ name: Continuous Deployment on: push: branches: [prepublish] + workflow_run: + workflows: [Prepublication staging] + types: [completed] jobs: deploy: diff --git a/.github/workflows/prepublish.yml b/.github/workflows/prepublish.yml new file mode 100644 index 0000000..dba07e1 --- /dev/null +++ b/.github/workflows/prepublish.yml @@ -0,0 +1,22 @@ +# As an alternative to a manual push to the prepublish branch, this workflow can +# be triggered on a release branch by assigning a special label to its pull +# request in order to set the CD circus in motion. + +name: Prepublication staging + +on: + pull_request: + types: [labeled] + branches: [release/*] + +jobs: + stage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Merge into prepublish + uses: devmasx/merge-branch@v1.3.0 + with: + label_name: ready to launch + target_branch: prepublish + github_token: ${{ secrets.GITHUB_TOKEN }} From 5ee33d9377c31b615d5bef89d4b43960efa3e9ea Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Fri, 30 Oct 2020 01:59:44 +0100 Subject: [PATCH 11/12] Include hotfix branches in the prepublish workflow (#188 #228) --- .github/workflows/prepublish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/prepublish.yml b/.github/workflows/prepublish.yml index dba07e1..25eeffc 100644 --- a/.github/workflows/prepublish.yml +++ b/.github/workflows/prepublish.yml @@ -7,7 +7,9 @@ name: Prepublication staging on: pull_request: types: [labeled] - branches: [release/*] + branches: + - release/* + - hotfix/* jobs: stage: From 880af8293c83e80ece32dee5862390825beb4d7c Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Fri, 30 Oct 2020 03:06:07 +0100 Subject: [PATCH 12/12] Document the new release workflow (#188 #228) --- DEPLOYING.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 DEPLOYING.md diff --git a/DEPLOYING.md b/DEPLOYING.md new file mode 100644 index 0000000..8148e18 --- /dev/null +++ b/DEPLOYING.md @@ -0,0 +1,49 @@ +# How to cut a new release for Underscore-contrib + +This is a checklist for repository maintainers. It covers all the steps involved in releasing a new version, including publishing to NPM and updating the `gh-pages` branch. We have tried to automate as many of these steps as possible using GitHub Actions. The workflows involved are in the (hidden) `.github` directory. + +A "regular" release includes new changes that were introduced to the `master` branch since the previous release. A *hotfix* release instead skips any such changes and only addresses urgent problems with the previous release. + + +## Steps + +1. Ensure your local `master` branch descends from the previous release branch and that it is in a state that you want to release. **Exception:** for hotfixes, ensure you have an up-to-date local copy of the previous release branch instead. +2. Decide on the next version number, respecting [semver][semver]. For the sake of example we'll use `1.2.3` as a placeholder version throughout this checklist. +3. Create a `release/1.2.3` branch based on `master`. **Exception:** if this is a hotfix, start from the previous release branch instead and call it `hotfix/1.2.3`. +4. Bump the version number in the `package.json` and the `yarn.lock` by running the command `yarn version --no-git-tag-version`, with the extra flag `--major`, `--minor` or `--patch` depending on which part of the version number you're incrementing (e.g., `--patch` if you're bumping from 1.2.2 to 1.2.3). Note that you can configure `yarn` to always include the `--no-git-tag-version` flag so you don't have to type it every time. +5. Bump the version number in the source code and in `docs/index.md` accordingly. +6. Commit the changes from steps 4 and 5 with a commit message of the format `Bump the version to 1.2.3`. +7. Add more commits to extend the change log and to update any other documentation that might require it. Ensure that all documentation looks good. +8. Push the release branch and create a pull request against `master` (also if it is a hotfix). +9. At your option, have the release branch reviewed and add more commits to satisfy any change requests. +10. The "Continuous Integration" workflow will trigger automatically on the pull request. This runs the test suite against multiple environments. Wait for all checks to complete. +11. If any checks fail, add more commits to fix and repeat from step 10. +12. When all reviewers are satisfied and all checks pass, apply the "ready to launch" label to the pull request. This will trigger the "Prepublication staging" workflow, which will merge the release branch into the `prepublish` branch. Merge manually if the workflow fails for whatever reason. **Note:** do *not* merge into `master` yet. +13. The merging of new changes into `prepublish` will trigger the "Continuous Deployment" workflow, which is documented below. **Pay attention as the deployment workflow progresses.** +14. If the deployment workflow fails, identify the failing step and address as quickly as possible. Possible solution steps include: + - Adding new commits to the release branch and repeating from step 12 (most likely if the docs fail to build for some reason). + - Manually pushing new commits to the `prepublish` branch and repeating from step 13 (this might be needed in case of merge conflicts, although this is highly unlikely). + - Manually running `yarn publish` (if something is wrong with the NPM registry or the authentication credentials). + - Manually merging `prepublish` into `gh-pages` (in unlikely case of merge conflicts). + - Manually tagging the release on `gh-pages`. +15. When the deployment workflow has completed, double-check that the new version was published to NPM, that the website was updated and that the repository contains a tag for the new release. +16. Finally merge the release branch into `master`, but keep the branch around for a few days in case you need to do a hotfix. +17. Delete the release branch. You can still restore it if necessary, by tracing the history graph two commits back from the release tag. + + +## Automated continuous deployment workflow + +This workflow is defined in `.github/workflows/cd.yml`. Note that roughly the first half of the steps in that file consists of basic boilerplate to check out the source and install dependencies. + +The publishing to NPM depends on a [secret][secrets] named `NPM_TOKEN`, representing the API token of the NPM account that owns the `underscore-contrib` package. Only admins of the documentcloud organization can access this setting. + +1. Checkout the source, restore caches and install the dependencies. +2. Run `yarn grunt dist docco tocdoc`. +3. Commit the output of the previous step to the `prepublish` branch. +4. Publish to NPM. +5. Merge the `prepublish` branch into `gh-pages`. +6. Tag the tip of `gh-pages` with the version number in the `package.json`. + + +[semver]: https://semver.org +[secrets]: https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets