From a7f006f3e266d727b4da31fbcf7f5f405bbc0170 Mon Sep 17 00:00:00 2001 From: murat Date: Thu, 23 Apr 2026 12:49:37 -0500 Subject: [PATCH 1/2] chore: update publish --- .github/workflows/manual-release.yaml | 216 -------------------------- .github/workflows/publish.yaml | 167 ++++++++++++++++++++ README.md | 124 ++++++++------- package.json | 9 +- 4 files changed, 238 insertions(+), 278 deletions(-) delete mode 100644 .github/workflows/manual-release.yaml create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/manual-release.yaml b/.github/workflows/manual-release.yaml deleted file mode 100644 index 06643b0..0000000 --- a/.github/workflows/manual-release.yaml +++ /dev/null @@ -1,216 +0,0 @@ -name: Manual Release - -on: - workflow_dispatch: - inputs: - version_bump: - description: Version bump type - required: true - default: beta - type: choice - options: - - beta - - alpha - - patch - - minor - - major - -permissions: - contents: write - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - registry-url: "https://registry.npmjs.org" - - - name: Install dependencies - run: npm ci - - - name: Verify npm credentials - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - if [ -z "$NODE_AUTH_TOKEN" ]; then - echo "NPM_TOKEN secret is not configured." >&2 - exit 1 - fi - - - name: Run tests and validation - run: npm test - - - name: Configure Git - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - - name: Bump version - run: | - case "${{ github.event.inputs.version_bump }}" in - alpha|beta) npm version prerelease --no-git-tag-version --preid=${{ github.event.inputs.version_bump }} ;; - *) npm version ${{ github.event.inputs.version_bump }} --no-git-tag-version ;; - esac - - - name: Sync marketplace version - run: | - node <<'NODE' - const fs = require('node:fs'); - - const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); - const marketplacePath = '.claude-plugin/marketplace.json'; - const marketplace = JSON.parse(fs.readFileSync(marketplacePath, 'utf8')); - const plugin = (marketplace.plugins || []).find((entry) => entry && entry.name === packageJson.name); - - if (!plugin) { - throw new Error(`Marketplace entry not found for ${packageJson.name}`); - } - - plugin.version = packageJson.version; - fs.writeFileSync(marketplacePath, `${JSON.stringify(marketplace, null, 2)}\n`); - NODE - - - name: Validate release metadata - run: npm run test:release-metadata - - - name: Get new version and release metadata - id: version - run: | - NEW_VERSION=$(node -p "require('./package.json').version") - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "previous_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo 'v0.0.0')" >> $GITHUB_OUTPUT - case "$NEW_VERSION" in - *-alpha.*) echo "npm_tag=alpha" >> $GITHUB_OUTPUT ;; - *-beta.*) echo "npm_tag=beta" >> $GITHUB_OUTPUT ;; - *) echo "npm_tag=latest" >> $GITHUB_OUTPUT ;; - esac - - - name: Commit version bump - run: | - git add package.json package-lock.json .claude-plugin/marketplace.json - git commit -m "release: bump to v${{ steps.version.outputs.new_version }}" - - - name: Create and push tag - run: | - # Check if tag already exists - if git rev-parse "v${{ steps.version.outputs.new_version }}" >/dev/null 2>&1; then - echo "Tag v${{ steps.version.outputs.new_version }} already exists, skipping tag creation" - else - git tag -a "v${{ steps.version.outputs.new_version }}" -m "Release v${{ steps.version.outputs.new_version }}" - git push origin "v${{ steps.version.outputs.new_version }}" - fi - - - name: Publish to npm - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - if [ "${{ steps.version.outputs.npm_tag }}" = "latest" ]; then - npm publish - else - npm publish --tag "${{ steps.version.outputs.npm_tag }}" - fi - - - name: Generate release notes - id: release_notes - run: | - # Get commits since last tag (or all commits if no tags exist) - if [ "${{ steps.version.outputs.previous_tag }}" = "v0.0.0" ]; then - COMMITS=$(git log --pretty=format:"- %s" --reverse) - else - COMMITS=$(git log ${{ steps.version.outputs.previous_tag }}..HEAD --pretty=format:"- %s" --reverse) - fi - - # Categorize commits - FEATURES=$(echo "$COMMITS" | grep -E "^- (feat|Feature)" || true) - FIXES=$(echo "$COMMITS" | grep -E "^- (fix|Fix)" || true) - CHORES=$(echo "$COMMITS" | grep -E "^- (chore|Chore)" || true) - OTHERS=$(echo "$COMMITS" | grep -v -E "^- (feat|Feature|fix|Fix|chore|Chore|release:|Release:)" || true) - - # Build release notes - cat > release_notes.md << 'EOF' - ## 🚀 What's New in v${{ steps.version.outputs.new_version }} - - EOF - - if [ ! -z "$FEATURES" ]; then - echo "### ✨ New Features" >> release_notes.md - echo "$FEATURES" >> release_notes.md - echo "" >> release_notes.md - fi - - if [ ! -z "$FIXES" ]; then - echo "### 🐛 Bug Fixes" >> release_notes.md - echo "$FIXES" >> release_notes.md - echo "" >> release_notes.md - fi - - if [ ! -z "$OTHERS" ]; then - echo "### 📦 Other Changes" >> release_notes.md - echo "$OTHERS" >> release_notes.md - echo "" >> release_notes.md - fi - - if [ ! -z "$CHORES" ]; then - echo "### 🔧 Maintenance" >> release_notes.md - echo "$CHORES" >> release_notes.md - echo "" >> release_notes.md - fi - - cat >> release_notes.md << 'EOF' - - ## 📦 Installation - - ```bash - npx bmad-method install - # Select "Test Architect" from module menu - ``` - EOF - - # Add changelog link only if there was a previous tag - if [ "${{ steps.version.outputs.previous_tag }}" != "v0.0.0" ]; then - echo "" >> release_notes.md - echo "**Full Changelog**: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/compare/${{ steps.version.outputs.previous_tag }}...v${{ steps.version.outputs.new_version }}" >> release_notes.md - fi - - # Output for GitHub Actions - echo "RELEASE_NOTES<> $GITHUB_OUTPUT - cat release_notes.md >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Push changes to release branch - run: | - if git push origin HEAD:${GITHUB_REF_NAME} 2>/dev/null; then - echo "✅ Successfully pushed to ${GITHUB_REF_NAME} branch" - else - echo "⚠️ Could not push to ${GITHUB_REF_NAME} (protected branch). This is expected." - echo "📝 Version bump and tag were created successfully." - fi - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - tag_name: v${{ steps.version.outputs.new_version }} - name: "Test Architect v${{ steps.version.outputs.new_version }}" - body: | - ${{ steps.release_notes.outputs.RELEASE_NOTES }} - draft: false - prerelease: ${{ contains(steps.version.outputs.new_version, 'alpha') || contains(steps.version.outputs.new_version, 'beta') }} - - - name: Summary - run: | - echo "## 🎉 Successfully released v${{ steps.version.outputs.new_version }}!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### 📦 Distribution" >> $GITHUB_STEP_SUMMARY - echo "- **NPM Package**: https://www.npmjs.com/package/bmad-method-test-architecture-enterprise" >> $GITHUB_STEP_SUMMARY - echo "- **NPM Dist-tag**: \`${{ steps.version.outputs.npm_tag }}\`" >> $GITHUB_STEP_SUMMARY - echo "- **GitHub Release**: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/releases/tag/v${{ steps.version.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..d0fbf97 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,167 @@ +name: Publish + +on: + push: + branches: [main] + paths: + - "src/**" + - "package.json" + - "package-lock.json" + workflow_dispatch: + inputs: + channel: + description: "Publish channel" + required: true + default: "latest" + type: choice + options: + - latest + - next + bump: + description: "Version bump type (latest channel only)" + required: false + default: "patch" + type: choice + options: + - patch + - minor + - major + +concurrency: + group: publish + cancel-in-progress: ${{ github.event_name == 'push' }} + +permissions: + id-token: write + contents: write + +jobs: + publish: + if: github.repository == 'bmad-code-org/bmad-method-test-architecture-enterprise' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/main') + runs-on: ubuntu-latest + steps: + - name: Generate GitHub App token + id: app-token + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "npm" + + - name: Ensure trusted publishing toolchain + run: | + # npm trusted publishing requires modern npm on the runner. + npm install --global npm@11.6.2 + + - name: Configure git user + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + - name: Derive next prerelease version + if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'next') + run: | + NEXT_VER=$(npm view bmad-method-test-architecture-enterprise@next version 2>/dev/null || echo "") + LATEST_VER=$(npm view bmad-method-test-architecture-enterprise@latest version 2>/dev/null || echo "") + + BASE=$(node -e " + const semver = require('semver'); + const next = process.argv[1] || null; + const latest = process.argv[2] || null; + if (!next && !latest) process.exit(0); + if (!next) { console.log(latest); process.exit(0); } + if (!latest) { console.log(next); process.exit(0); } + const nextBase = next.replace(/-next\.\d+$/, ''); + console.log(semver.gt(latest, nextBase) ? latest : next); + " "$NEXT_VER" "$LATEST_VER") + + if [ -n "$BASE" ]; then + npm version "$BASE" --no-git-tag-version --allow-same-version + fi + npm version prerelease --preid=next --no-git-tag-version + + - name: Bump stable version + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: npm version "${{ inputs.bump }}" --no-git-tag-version + + - name: Sync marketplace version + run: | + node <<'NODE' + const fs = require('node:fs'); + + const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); + const marketplacePath = '.claude-plugin/marketplace.json'; + const marketplace = JSON.parse(fs.readFileSync(marketplacePath, 'utf8')); + const plugin = (marketplace.plugins || []).find((entry) => entry && entry.name === packageJson.name); + + if (!plugin) { + throw new Error(`Marketplace entry not found for ${packageJson.name}`); + } + + plugin.version = packageJson.version; + fs.writeFileSync(marketplacePath, `${JSON.stringify(marketplace, null, 2)}\n`); + NODE + + - name: Validate release metadata + run: npm run test:release-metadata + + - name: Publish prerelease to npm + if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'next') + run: npm publish --tag next --provenance + + - name: Publish stable release to npm + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: npm publish --tag latest --provenance + + - name: Commit version bump + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: | + VERSION=$(node -p 'require("./package.json").version') + git add package.json package-lock.json .claude-plugin/marketplace.json + git commit -m "release: bump to v${VERSION}" + git tag -a "v${VERSION}" -m "Release v${VERSION}" + + - name: Push version commit and tag + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: git push origin main --follow-tags + + - name: Create GitHub Release + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: | + TAG="v$(node -p 'require("./package.json").version')" + VERSION="${TAG#v}" + BODY=$(awk -v ver="$VERSION" ' + /^## / { + if (found) exit + if ($0 ~ "^## \\[" ver "\\]" || $0 ~ "^## v" ver) found=1 + next + } + found { print } + ' CHANGELOG.md) + if [ -z "$BODY" ]; then + echo "::warning::No CHANGELOG.md entry for $TAG — falling back to auto-generated notes" + gh release create "$TAG" --generate-notes + else + gh release create "$TAG" --notes "$BODY" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index e838064..d5b9b45 100644 --- a/README.md +++ b/README.md @@ -216,17 +216,28 @@ See `CONTRIBUTING.md` for guidelines. ## Publishing TEA to NPM -TEA uses an automated release workflow that handles versioning, metadata sync, tagging, NPM publishing, and GitHub releases. +TEA uses an automated publish workflow modeled after the main `BMAD-METHOD` repo. It supports: + +- `next` prereleases published automatically from `main` +- manual stable releases on the `latest` dist-tag +- trusted npm publishing (no `NPM_TOKEN` secret) +- metadata sync for `package.json`, `package-lock.json`, and `.claude-plugin/marketplace.json` ### Prerequisites (One-Time Setup) -1. **NPM Token Configuration:** - - Generate NPM automation token: [npmjs.com/settings/tokens](https://www.npmjs.com/settings/your-username/tokens) - - Add to GitHub Secrets: `Settings` → `Secrets and variables` → `Actions` → `New repository secret` - - Name: `NPM_TOKEN` - - Value: [your token] +1. **npm Trusted Publishing:** + - In npm package settings for `bmad-method-test-architecture-enterprise`, configure Trusted Publishers for this GitHub repository + - Allow publishes from the `bmad-code-org/bmad-method-test-architecture-enterprise` repo and the `.github/workflows/publish.yaml` workflow + - GitHub Actions must be able to request an OIDC token (`id-token: write`), which the workflow already does + +2. **GitHub App Secrets for Stable Releases:** + - Add `RELEASE_APP_ID` + - Add `RELEASE_APP_PRIVATE_KEY` + - Install the corresponding GitHub App on this repository with contents write access + - If `main` is protected, ensure the app is allowed to push the release commit and tag + - These are used only for manual stable releases so the workflow can push the version bump commit and tag back to `main` -2. **Verify Package Configuration:** +3. **Verify Package Configuration:** ```bash # Check package.json settings cat package.json | grep -A 3 "publishConfig" @@ -242,71 +253,61 @@ TEA uses an automated release workflow that handles versioning, metadata sync, t #### Option 1: Using npm Scripts (Recommended) -From your local terminal after merging to the release branch you want to publish, typically `main`: +From your local terminal after merging to `main`: ```bash -# Beta release (first release or testing) -npm run release:beta - -# Alpha release (early testing) -npm run release:alpha +# Publish the next prerelease from current main +npm run release:next -# Patch release (bug fixes) +# Publish a stable patch release npm run release:patch -# Minor release (new features, backwards compatible) +# Publish a stable minor release npm run release:minor -# Major release (breaking changes) +# Publish a stable major release npm run release:major ``` #### Option 2: Manual Workflow Trigger 1. Go to **Actions** tab in GitHub -2. Click **"Manual Release"** workflow +2. Click **"Publish"** workflow 3. Click **"Run workflow"** 4. Choose the branch to release, typically `main` -5. Select version bump type (alpha, beta, patch, minor, major) -6. Click **"Run workflow"** +5. Select channel: + - `next` for a prerelease publish + - `latest` for a stable release +6. If using `latest`, choose the bump type (`patch`, `minor`, `major`) +7. Click **"Run workflow"** ### What Happens Automatically The workflow performs these steps: 1. ✅ **Validation**: Runs the full `npm test` suite, including schema checks, install tests, knowledge checks, linting, markdown linting, formatting, and release metadata validation -2. ✅ **Version Bump**: Updates `package.json`, `package-lock.json`, and `.claude-plugin/marketplace.json` - - `beta`: 1.12.3 → 1.12.4-beta.0 - - `alpha`: 1.12.3 → 1.12.4-alpha.0 - - `patch`: 1.12.3 → 1.12.4 - - `minor`: 1.12.3 → 1.13.0 - - `major`: 1.12.3 → 2.0.0 -3. ✅ **Commit**: Creates version bump commit -4. ✅ **Tag**: Creates git tag (e.g., v1.12.4-beta.0) -5. ✅ **Publish**: Publishes to NPM registry - - Alpha → dist-tag `alpha` (`npm install bmad-method-test-architecture-enterprise@alpha`) - - Beta → dist-tag `beta` (`npm install bmad-method-test-architecture-enterprise@beta`) - - Stable → dist-tag `latest` (`npm install bmad-method-test-architecture-enterprise`) -6. ✅ **Push**: Pushes the version bump commit back to the selected branch when permitted, and always pushes the tag -7. ✅ **GitHub Release**: Creates release with auto-generated notes -8. ✅ **Summary**: Displays installation instructions and distribution links - -### Version Bump Strategy - -**For TEA Module:** - -- **Beta (`1.12.x-beta.x`)**: Release candidate testing on the next patch line -- **Alpha (`1.12.x-alpha.x`)**: Early development and experimental validation -- **Patch (`1.12.x`)**: Bug fixes, no breaking changes -- **Minor (`1.x.0`)**: New features, backwards compatible -- **Major (`x.0.0`)**: Breaking changes +2. ✅ **Version Bump**: + - `next`: derives the next prerelease version and publishes it with dist-tag `next` + - `latest`: bumps the stable version (`patch`, `minor`, or `major`) +3. ✅ **Metadata Sync**: Updates `.claude-plugin/marketplace.json` to match the package version before publishing +4. ✅ **Publish**: Publishes to npm with provenance enabled + - `next` → `npm publish --tag next --provenance` + - `latest` → `npm publish --tag latest --provenance` +5. ✅ **Stable Release Finalization**: For `latest`, creates a version bump commit, tags it, pushes it to `main`, and creates a GitHub Release + +### Channel Strategy + +- **`next`**: prerelease channel for the newest merged changes +- **`latest`**: stable channel for intentional releases +- **`patch`**: bug fixes, no breaking changes +- **`minor`**: new features, backwards compatible +- **`major`**: breaking changes **Recommended Release Path:** -1. `1.12.3` → `1.12.4-beta.0` (first beta) -2. Test beta with early adopters -3. `1.12.4-beta.0` → `1.12.4-beta.1` (fixes) -4. When stable: `1.12.4-beta.1` → `1.12.4` +1. Merge releasable work to `main` +2. Let `next` publish for early validation +3. When ready, cut a stable `latest` release via `patch`, `minor`, or `major` ### Verify Publication @@ -314,6 +315,7 @@ The workflow performs these steps: ```bash npm view bmad-method-test-architecture-enterprise +npm view bmad-method-test-architecture-enterprise dist-tags ``` **Install TEA:** @@ -337,24 +339,31 @@ If you need to unpublish a version: ```bash # Unpublish specific version (within 72 hours) -npm unpublish bmad-method-test-architecture-enterprise@1.12.4-beta.0 +npm unpublish bmad-method-test-architecture-enterprise@1.13.2-next.0 # Deprecate version (preferred for older releases) -npm deprecate bmad-method-test-architecture-enterprise@1.12.4-beta.0 "Use version X.Y.Z instead" +npm deprecate bmad-method-test-architecture-enterprise@1.13.2-next.0 "Use version X.Y.Z instead" ``` ### Troubleshooting -**"NPM_TOKEN not found":** +**Trusted publishing failed:** -- Verify secret is set: GitHub repo → Settings → Secrets and variables → Actions -- Secret name must be exactly: `NPM_TOKEN` +- Verify npm Trusted Publishing is configured for this repository and workflow +- Verify the workflow has `id-token: write` +- Confirm the publish is running from the canonical repository, not a fork **"Package already exists":** - Check if package name is already taken on NPM - Update `name` in `package.json` if needed +**"Version push failed":** + +- Verify `RELEASE_APP_ID` and `RELEASE_APP_PRIVATE_KEY` are configured +- Verify the GitHub App is installed on this repository with contents write access +- If branch protection is enabled on `main`, verify the app is allowed to push the release commit and tag + **"Tests failed":** - Fix failing tests before release @@ -362,9 +371,9 @@ npm deprecate bmad-method-test-architecture-enterprise@1.12.4-beta.0 "Use versio **"Git push failed (protected branch)":** -- This is expected for a protected release branch -- The tag and version bump are still created -- You may need to manually merge the version bump commit +- This is not expected once the release GitHub App is configured correctly +- Verify branch protection allows the app to push the release commit and tag +- If needed, create the GitHub Release manually after resolving the app permissions ### Release Checklist @@ -375,7 +384,8 @@ Before releasing: - [ ] CHANGELOG.md updated - [ ] No uncommitted changes - [ ] On `main` branch -- [ ] NPM token configured in GitHub Secrets +- [ ] npm Trusted Publishing configured +- [ ] `RELEASE_APP_ID` and `RELEASE_APP_PRIVATE_KEY` configured - [ ] Package name available on NPM After releasing: diff --git a/package.json b/package.json index 13252ff..ab3eee6 100644 --- a/package.json +++ b/package.json @@ -33,11 +33,10 @@ "lint:fix": "eslint . --fix", "lint:md": "markdownlint-cli2 '**/*.md'", "prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0", - "release:alpha": "gh workflow run manual-release.yaml -f version_bump=alpha", - "release:beta": "gh workflow run manual-release.yaml -f version_bump=beta", - "release:major": "gh workflow run manual-release.yaml -f version_bump=major", - "release:minor": "gh workflow run manual-release.yaml -f version_bump=minor", - "release:patch": "gh workflow run manual-release.yaml -f version_bump=patch", + "release:major": "gh workflow run publish.yaml -f channel=latest -f bump=major", + "release:minor": "gh workflow run publish.yaml -f channel=latest -f bump=minor", + "release:next": "gh workflow run publish.yaml -f channel=next", + "release:patch": "gh workflow run publish.yaml -f channel=latest -f bump=patch", "test": "npm run test:schemas && npm run test:install && npm run test:knowledge && npm run test:release-metadata && npm run test:tea-workflow-descriptions && npm run validate:schemas && npm run lint && npm run lint:md && npm run format:check", "test:coverage": "c8 npm test", "test:install": "node test/test-installation-components.js", From 76c7bbabc1f390f1e8f213ad1257184233077427 Mon Sep 17 00:00:00 2001 From: murat Date: Thu, 23 Apr 2026 12:59:03 -0500 Subject: [PATCH 2/2] chore: addressed PR comments --- .github/workflows/publish.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index d0fbf97..a5b7b07 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -28,7 +28,7 @@ on: - major concurrency: - group: publish + group: publish-${{ github.event_name }}-${{ github.ref_name }}-${{ inputs.channel || 'push' }} cancel-in-progress: ${{ github.event_name == 'push' }} permissions: @@ -59,6 +59,7 @@ jobs: with: node-version-file: ".nvmrc" cache: "npm" + registry-url: "https://registry.npmjs.org" - name: Ensure trusted publishing toolchain run: | @@ -91,7 +92,7 @@ jobs: if (!next) { console.log(latest); process.exit(0); } if (!latest) { console.log(next); process.exit(0); } const nextBase = next.replace(/-next\.\d+$/, ''); - console.log(semver.gt(latest, nextBase) ? latest : next); + console.log(semver.gte(latest, nextBase) ? latest : next); " "$NEXT_VER" "$LATEST_VER") if [ -n "$BASE" ]; then @@ -128,22 +129,22 @@ jobs: if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'next') run: npm publish --tag next --provenance - - name: Publish stable release to npm - if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' - run: npm publish --tag latest --provenance - - name: Commit version bump if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' run: | VERSION=$(node -p 'require("./package.json").version') git add package.json package-lock.json .claude-plugin/marketplace.json - git commit -m "release: bump to v${VERSION}" + git commit -m "release: bump to v${VERSION} [skip ci]" git tag -a "v${VERSION}" -m "Release v${VERSION}" - name: Push version commit and tag if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' run: git push origin main --follow-tags + - name: Publish stable release to npm + if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' + run: npm publish --tag latest --provenance + - name: Create GitHub Release if: github.event_name == 'workflow_dispatch' && inputs.channel == 'latest' run: | @@ -152,7 +153,7 @@ jobs: BODY=$(awk -v ver="$VERSION" ' /^## / { if (found) exit - if ($0 ~ "^## \\[" ver "\\]" || $0 ~ "^## v" ver) found=1 + if ($0 ~ ("^##[[:space:]]*\\[?[[:space:]]*v?" ver "[[:space:]]*\\]?([[:space:]]*-[[:space:]].*)?$")) found=1 next } found { print }