From 6de4a9a6493fcab3d9d753c8ec5c643c60f22210 Mon Sep 17 00:00:00 2001 From: James Henry Date: Thu, 24 Nov 2022 03:28:44 +0400 Subject: [PATCH] chore: add automation for @nrwl + nx package updates (#5797) * chore: add automation for @nrwl + nx package updates * chore: fix formatting --- .github/renovate.json5 | 4 +- .github/workflows/nx-migrate.yml | 85 ++++++++++++++++++++++++++++++++ package.json | 3 +- tools/postinstall.ts | 34 +++++++++++++ yarn.lock | 2 +- 5 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/nx-migrate.yml create mode 100644 tools/postinstall.ts diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f5d016eb6db..0c18b35da84 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -5,14 +5,14 @@ 'globby', // this dep now uses package.json exports - we will be removing it next major 'eslint-scope', + // this dep is now ESM only + 'execa', // the nx packages get updated using the nx migrate CLI '@nrwl/cli', '@nrwl/devkit', '@nrwl/jest', '@nrwl/nx-cloud', '@nrwl/tao', - '@nrwl/workspace', - 'nx', ], ignorePaths: [ // integration test package.json's should never be updated as they're purposely fixed tests diff --git a/.github/workflows/nx-migrate.yml b/.github/workflows/nx-migrate.yml new file mode 100644 index 00000000000..af107f6c391 --- /dev/null +++ b/.github/workflows/nx-migrate.yml @@ -0,0 +1,85 @@ +# This workflow is used to augment the capabilities of the renovate GitHub app by running a full +# `nx migrate` when renovate opens a PR to change the version of @nrwl/workspace. +# +# You will therefore also notice that in the renovate configuration, we ignore any packages which +# Nx will manage for us as part of `nx migrate` such as the remaining @nrwl/* packages and jest. + +name: Nx Migrate + +on: + pull_request: + branches: [main] + paths: + - 'package.json' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true + +jobs: + maybe_nx_migrate: + # Only run if it was the renovate bot that triggered the workflow (otherwise we'll create a loop) + if: contains('["renovate[bot]"]', github.actor) == true + name: Run nx migrate if required + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + # To allow us to perform the git diff we need the git history + fetch-depth: 0 + # To ensure we can push from a different user (and therefore cause actions to rerun) + persist-credentials: false + + - name: Derive appropriate SHAs for base and head for `nx affected` commands + uses: nrwl/nx-set-shas@v3 + + - name: Check if @nrwl/workspace was changed as part of the latest commit on the PR + id: nrwl-workspace-package-check + run: | + git diff HEAD~1 -G"@nrwl/workspace" --exit-code package.json && echo "@nrwl/workspace unchanged" || echo "::set-output name=was-changed::true" + + - name: Run nx migrate if @nrwl/workspace changed and commit the results + if: ${{ steps.nrwl-workspace-package-check.outputs.was-changed == 'true' }} + env: + # We cannot use secrets.GITHUB_TOKEN for this because it is not permitted to kick off subsequent actions worfklow runs, so we use a PAT instead + GITHUB_TOKEN: ${{ secrets.JAMES_HENRY_GITHUB_TOKEN }} + # We don't want to run any of our postinstall logic when Nx is invoking install behind the scenes + SKIP_POSTINSTALL: 'true' + run: | + # Checkout the PR branch using the github CLI + gh pr checkout ${{ github.event.pull_request.number }} + + # Get the version of Nx we are migrating to + NX_VERSION=$(node -e "console.log(require('./package.json').devDependencies['@nrwl/workspace'])") + + # Revert renovate's changes to package.json and yarn.lock so that it is a clean migrate from the status quo + git checkout HEAD~1 -- package.json yarn.lock + + yarn --ignore-scripts + + npx nx migrate @nrwl/workspace@$NX_VERSION + + # Sometimes Nx can require config formatting changes after a migrate command + yarn --ignore-scripts + npx nx format + + # migrations.json may or may not exist after running nx migrate + if [ -f migrations.json ]; then + # This will also invoke yarn automatically + npx nx migrate --run-migrations=migrations.json + + # After we have run its migrations, we no longer need the migrations.json file + rm migrations.json + fi + + # Ensure all the changed files are formatted appropriately + yarn format + + # Commit all the changes to the PR (see note on not being able to use secrets.GITHUB_TOKEN for this) + git config --global user.email "james@henry.sc" + git config --global user.name "JamesHenry" + git remote set-url origin https://x-access-token:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git + + git add --all + git commit -m "chore: run nx migrate for @nrwl/workspace v$NX_VERSION" + git push diff --git a/package.json b/package.json index 30b2b224022..c5c7499365c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "lint-markdown-fix": "yarn lint-markdown --fix", "lint-markdown": "markdownlint \"**/*.md\" --config=.markdownlint.json --ignore-path=.markdownlintignore", "lint": "nx run-many --target=lint --all --parallel", - "postinstall": "yarn patch-package && yarn husky install && yarn build", + "postinstall": "yarn ts-node --transpile-only ./tools/postinstall.ts", "pre-commit": "yarn lint-staged", "start": "nx run website:start", "test": "nx run-many --target=test --all --parallel", @@ -86,6 +86,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^26.1.5", "eslint-plugin-simple-import-sort": "^8.0.0", + "execa": "5.1.1", "glob": "^8.0.1", "husky": "^8.0.1", "jest": "^29.0.3", diff --git a/tools/postinstall.ts b/tools/postinstall.ts new file mode 100644 index 00000000000..b222b290e68 --- /dev/null +++ b/tools/postinstall.ts @@ -0,0 +1,34 @@ +import * as execa from 'execa'; + +/** + * In certain circumstances we want to skip the below the steps and it may not always + * be possible to use --ignore-scripts (e.g. if another tool is what is invoking the + * install command, such as when nx migrate runs). We therefore use and env var for this. + */ + +if (process.env.SKIP_POSTINSTALL) { + console.log( + '\nSkipping postinstall script because $SKIP_POSTINSTALL is set...\n', + ); + // eslint-disable-next-line no-process-exit + process.exit(0); +} + +void (async function (): Promise { + // Apply patches to installed node_modules + await $`yarn patch-package`; + + // Install git hooks + await $`yarn husky install`; + + // // Build all the packages ready for use + await $`yarn build`; +})(); + +async function $(cmd: TemplateStringsArray): Promise { + const command = cmd.join(); + console.log(`\n$ ${command}`); + return execa.command(command, { + stdio: 'inherit', + }); +} diff --git a/yarn.lock b/yarn.lock index 3ca3e9af00c..2598bd29b00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7132,7 +7132,7 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: +execa@5.1.1, execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==