diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index fc81e1f..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Publish - -on: - push: - tags: - - 'v*' - -permissions: - contents: read - -jobs: - npm: - name: Publish to npm - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - uses: pnpm/action-setup@v2 - with: - version: 10 - - - uses: actions/setup-node@v4 - with: - node-version: '20' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - name: Install - run: pnpm install --frozen-lockfile - - - name: Verify tag matches package.json version - run: node scripts/ci/ensure-tag-matches-package.mjs - env: - GITHUB_REF_NAME: ${{ github.ref_name }} - - - name: Check if version already published - run: | - VERSION="$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json','utf8')).version)")" - if npm view "codebase-context@${VERSION}" version >/dev/null 2>&1; then - echo "Version ${VERSION} already exists on npm; skipping publish." - echo "SKIP_PUBLISH=true" >> "$GITHUB_ENV" - else - echo "Version ${VERSION} not found on npm; will publish." - fi - - - name: Quality gates - if: env.SKIP_PUBLISH != 'true' - run: | - pnpm lint - pnpm format:check - pnpm type-check - pnpm test - pnpm build - - - name: Publish - if: env.SKIP_PUBLISH != 'true' - run: pnpm publish --access public --no-git-checks - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index b1a0138..972018d 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -11,10 +11,56 @@ permissions: jobs: release-please: - name: Create/Update Release PR + name: Release PR + Publish runs-on: ubuntu-latest steps: - uses: googleapis/release-please-action@v4 + id: release with: config-file: release-please-config.json manifest-file: .release-please-manifest.json + + - uses: actions/checkout@v4 + if: ${{ steps.release.outputs.release_created }} + + - uses: pnpm/action-setup@v2 + if: ${{ steps.release.outputs.release_created }} + with: + version: 10 + + - uses: actions/setup-node@v4 + if: ${{ steps.release.outputs.release_created }} + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install + if: ${{ steps.release.outputs.release_created }} + run: pnpm install --frozen-lockfile + + - name: Check if version already published + if: ${{ steps.release.outputs.release_created }} + run: | + VERSION="$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json','utf8')).version)")" + if npm view "codebase-context@${VERSION}" version >/dev/null 2>&1; then + echo "Version ${VERSION} already exists on npm; skipping publish." + echo "SKIP_PUBLISH=true" >> "$GITHUB_ENV" + else + echo "Version ${VERSION} not found on npm; will publish." + fi + + - name: Quality gates + if: ${{ steps.release.outputs.release_created && env.SKIP_PUBLISH != 'true' }} + run: | + pnpm lint + pnpm format:check + pnpm type-check + pnpm test + pnpm build + + - name: Publish + if: ${{ steps.release.outputs.release_created && env.SKIP_PUBLISH != 'true' }} + run: pnpm publish --access public --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/RELEASING.md b/RELEASING.md index 721eb82..0785536 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,7 +7,7 @@ We use a clean OSS-style flow: - PRs merge into `master` (nothing publishes on merge) - A release is created by a dedicated **Release PR** opened/updated automatically - When the Release PR is merged, CI creates a git tag like `v1.2.3` -- Tag pushes trigger CI to publish to npm +- When a release tag is created, CI publishes to npm automatically ## One-time setup (maintainers) @@ -37,9 +37,8 @@ We use a clean OSS-style flow: 3. When you're ready to ship, merge the Release PR. - This creates a git tag `vX.Y.Z` and a GitHub Release - - The `Publish` workflow runs on the tag and publishes to npm + - The `Release Please` workflow publishes to npm as part of the same run ## Notes -- Publishing is triggered only by `v*` tags. -- The publish workflow verifies `tag == v${package.json.version}` and fails fast if they don't match. +- If a version is already published on npm, CI skips the publish step (useful when seeding historical tags). diff --git a/scripts/ci/ensure-tag-matches-package.mjs b/scripts/ci/ensure-tag-matches-package.mjs deleted file mode 100644 index 8fd2a5f..0000000 --- a/scripts/ci/ensure-tag-matches-package.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import fs from 'node:fs'; - -const tag = process.env.GITHUB_REF_NAME; -if (!tag) { - console.error('Missing GITHUB_REF_NAME'); - process.exit(1); -} - -if (!tag.startsWith('v')) { - console.error(`Expected tag like v1.2.3, got: ${tag}`); - process.exit(1); -} - -const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); -const version = pkg?.version; -if (!version || typeof version !== 'string') { - console.error('Missing package.json version'); - process.exit(1); -} - -const expectedTag = `v${version}`; -if (tag !== expectedTag) { - console.error( - `Tag/package.json version mismatch. Tag is ${tag}, but package.json is ${version} (expected ${expectedTag}).` - ); - process.exit(1); -} - -console.log(`OK: ${tag} matches package.json version ${version}`);