From 2b0f544f8ec876388a2595626fb2a5c93d8119c7 Mon Sep 17 00:00:00 2001 From: Elliot Taylor Date: Tue, 12 May 2026 15:40:07 +0100 Subject: [PATCH 1/4] Add GitHub Actions CI and publish workflows --- .github/workflows/ci.yml | 76 +++++++++++++++++++++++++++++++++++ .github/workflows/publish.yml | 62 ++++++++++++++++++++++++++++ README.md | 4 ++ 3 files changed, 142 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a2b9aef --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + validate: + name: Validate on Node ${{ matrix.node-version }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + node-version: + - 18.x + - 20.x + - 22.x + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Typecheck + run: npm run typecheck + + - name: Test + run: npm test + + - name: Build + run: npm run build + + - name: Verify committed dist is current + run: git diff --exit-code -- dist + + - name: Verify package contents + run: npm pack --dry-run + + production-audit: + name: Production dependency audit + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Audit published dependency tree + run: npm audit --omit=dev --audit-level=moderate diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..be912fa --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,62 @@ +name: Publish + +on: + release: + types: + - published + workflow_dispatch: + +permissions: + contents: read + id-token: write + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +jobs: + publish: + name: Publish package + runs-on: ubuntu-latest + environment: npm + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20.x + registry-url: https://registry.npmjs.org + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Typecheck + run: npm run typecheck + + - name: Test + run: npm test + + - name: Build + run: npm run build + + - name: Verify committed dist is current + run: git diff --exit-code -- dist + + - name: Verify package contents + run: npm pack --dry-run + + - name: Verify release tag matches package version + if: github.event_name == 'release' + run: node -e "const pkg = require('./package.json'); const expected = 'v' + pkg.version; if (process.env.GITHUB_REF_NAME !== expected) { console.error('Release tag ' + process.env.GITHUB_REF_NAME + ' does not match package version ' + expected); process.exit(1); }" + + - name: Dry-run publish + if: github.event_name == 'workflow_dispatch' + run: npm publish --access public --provenance --dry-run + + - name: Publish to npm + if: github.event_name == 'release' + run: npm publish --access public --provenance diff --git a/README.md b/README.md index f09b285..f0e3010 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,10 @@ npm test npm run build ``` +## Release process + +Pull requests run typecheck, tests, build, package verification, and a production dependency audit in GitHub Actions. Publishing runs when a GitHub Release is published and uses `npm publish --provenance --access public`, so configure npm trusted publishing for this repository before cutting a release. + ## License MIT From ccff23a1f7412032962cba70b7c268545ff17374 Mon Sep 17 00:00:00 2001 From: Elliot Taylor Date: Tue, 12 May 2026 15:49:19 +0100 Subject: [PATCH 2/4] Use Node 22 for trusted publishing --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index be912fa..756a865 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,7 +27,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x registry-url: https://registry.npmjs.org cache: npm From ed2dfd55c7271b661e0bc31732dba83d1be7443b Mon Sep 17 00:00:00 2001 From: Elliot Taylor Date: Tue, 12 May 2026 15:50:23 +0100 Subject: [PATCH 3/4] Upgrade npm before trusted publish --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 756a865..976b268 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,6 +31,9 @@ jobs: registry-url: https://registry.npmjs.org cache: npm + - name: Upgrade npm + run: npm install -g npm@latest + - name: Install dependencies run: npm ci From 9e15addbffad69391e3de521cde29a244ed59edd Mon Sep 17 00:00:00 2001 From: Elliot Taylor Date: Tue, 12 May 2026 15:53:50 +0100 Subject: [PATCH 4/4] Document npm trusted publishing setup --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f0e3010..c544645 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,31 @@ npm run build ## Release process -Pull requests run typecheck, tests, build, package verification, and a production dependency audit in GitHub Actions. Publishing runs when a GitHub Release is published and uses `npm publish --provenance --access public`, so configure npm trusted publishing for this repository before cutting a release. +Pull requests run typecheck, tests, build, package verification, and a production dependency audit in GitHub Actions. + +Publishing runs when a GitHub Release is published. The release tag must match the package version in `package.json` with a leading `v`. For example, `package.json` version `0.2.0` must be released with tag `v0.2.0`; otherwise the workflow fails before publishing. + +To publish a release: + +1. Bump the package version, for example `npm version 0.2.0 --no-git-tag-version`. +2. Commit `package.json` and `package-lock.json`. +3. Merge the version bump to `main`. +4. Create and publish a GitHub Release tagged `v0.2.0`. +5. The `Publish` workflow verifies the package, then runs `npm publish --provenance --access public`. + +Before the first release, configure npm trusted publishing for this package: + +1. Merge `.github/workflows/publish.yml` to `main`. +2. Open the `@patchstack/connect` package settings on npmjs.com. +3. In **Trusted publishing**, choose **GitHub Actions**. +4. Configure: + - Organization/user: `patchstack` + - Repository: `connect` + - Workflow filename: `publish.yml` + - Environment name: `npm` +5. In GitHub repository settings, create an `npm` environment. Optional but recommended: require reviewer approval for that environment. + +Do not add an npm publish token to GitHub secrets for this workflow. Trusted publishing uses GitHub OIDC short-lived credentials. After the first trusted publish succeeds, npm recommends setting package publishing access to require two-factor authentication and disallow tokens. ## License