From e5f7599eabbc7d21badeaccf30d7f80c249f0beb Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 11:36:07 +0000 Subject: [PATCH] Automate npm releases with trusted publishing - Add a release workflow that publishes to npm (with provenance via OIDC) when the version in package.json on main is not on the registry yet, then creates the vX.Y.Z GitHub release. - Point repository, bugs and homepage URLs at learn-tamil/script, which npm provenance verification requires. - Add CLAUDE.md describing how an agent cuts a release. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01SUZwZNHq5MTwxkdGyJg6Sn --- .github/workflows/release.yml | 64 +++++++++++++++++++++++++++++++++++ CLAUDE.md | 23 +++++++++++++ package.json | 6 ++-- 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 CLAUDE.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7239ea7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,64 @@ +name: Release + +# Publishes to npm whenever the version in package.json on main is not yet on +# the registry. Authentication uses npm trusted publishing (OIDC), so no npm +# token is stored in this repository. +on: + push: + branches: + - main + paths: + - package.json + workflow_dispatch: + +concurrency: + group: release + cancel-in-progress: false + +permissions: + contents: write + id-token: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout codebase + uses: actions/checkout@v4 + - name: Enable Corepack + run: corepack enable + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: pnpm + registry-url: https://registry.npmjs.org + - name: Update npm (trusted publishing needs npm >= 11.5.1) + run: npm install -g npm@latest + - name: Check whether this version is already published + id: version + run: | + name=$(node -p "require('./package.json').name") + version=$(node -p "require('./package.json').version") + echo "version=$version" >> "$GITHUB_OUTPUT" + if npm view "$name@$version" version > /dev/null 2>&1; then + echo "$name@$version is already on npm, nothing to release." + echo "publish=false" >> "$GITHUB_OUTPUT" + else + echo "Releasing $name@$version." + echo "publish=true" >> "$GITHUB_OUTPUT" + fi + - name: Install dependencies + if: steps.version.outputs.publish == 'true' + run: pnpm install --frozen-lockfile + - name: Run tests + if: steps.version.outputs.publish == 'true' + run: pnpm test + - name: Publish to npm + if: steps.version.outputs.publish == 'true' + # prepack builds lib/ and the type declarations + run: npm publish --provenance --access public + - name: Create GitHub release + if: steps.version.outputs.publish == 'true' + env: + GH_TOKEN: ${{ github.token }} + run: gh release create "v${{ steps.version.outputs.version }}" --target "$GITHUB_SHA" --generate-notes diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..0ce67a9 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,23 @@ +# CLAUDE.md + +## Development + +- Package manager: pnpm (`corepack enable`, then `pnpm install --frozen-lockfile`) +- Tests: `pnpm test` (update snapshots with `pnpm jest -u` when a data change is intended) +- Lint and types: `pnpm eslint`, `pnpm tsc --noEmit`, `pnpm format --check` + +## Releasing a new version to npm + +Publishing is automated by `.github/workflows/release.yml`. It runs on every push to `main` that touches +`package.json` and publishes when that version is not on npm yet, then creates the `vX.Y.Z` tag and a GitHub +release. Never run `npm publish` yourself and never create the tag by hand. + +To release: + +1. Pick the version. Follow semver: patch for fixes (including data corrections), minor for new features, major for + breaking changes. If the person asking did not say, check the commits since the last `v*` tag and propose one. +2. On a branch from the latest `main`, bump the version without tagging: + `npm version --no-git-tag-version`. This only changes `version` in `package.json`. +3. Commit as `X.Y.Z`, push, and open a pull request titled `Release X.Y.Z` that lists the changes since the last tag. +4. Once CI is green, merge it. The release workflow then publishes to npm. +5. Check that the `Release` workflow run on `main` succeeded and that the GitHub release `vX.Y.Z` exists. diff --git a/package.json b/package.json index 5e624d4..157cf3c 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,12 @@ "sideEffects": false, "repository": { "type": "git", - "url": "git+https://github.com/learn-tamil/tamil-script.git" + "url": "git+https://github.com/learn-tamil/script.git" }, "bugs": { - "url": "https://github.com/learn-tamil/tamil-script/issues" + "url": "https://github.com/learn-tamil/script/issues" }, - "homepage": "https://github.com/learn-tamil/tamil-script#readme", + "homepage": "https://github.com/learn-tamil/script#readme", "author": "Rathes Sachchithananthan ", "license": "MIT", "devDependencies": {