Skip to content

Commit efbc72f

Browse files
committed
fix: address review findings in release automation
- release.yml: use RELEASE_TOKEN PAT for gh release create so the release:published event triggers npm-publish (GITHUB_TOKEN events don't cascade to other workflows) - release.yml: checkout merge_commit_sha in tag job instead of ref:main to avoid tagging later commits - release.yml: checkout ref:main in prepare job so dispatching from a feature branch doesn't pollute the release PR - release.yml: constrain preid to type:choice[beta] to match npm-publish.yml's tag detection - release.yml: drop -f on push so re-runs fail loudly instead of clobbering manual RELEASES.md edits; drop pr-edit fallback - release.yml: ensure release label exists before gh pr create - release.yml: make tag push idempotent for re-runs after partial failure - bump-version.mjs: update workspace dependency ranges so major bumps don't leave examples pointing at the old major - bump-version.mjs: run npm install --package-lock-only so npm ci on the release PR doesn't fail on lockfile mismatch - npm-publish.yml: add npm-tag detection to publish-examples so beta example releases don't overwrite latest - .github/release.yml: use [bot] suffix in author excludes so dependabot PRs are actually filtered from release notes - CONTRIBUTING.md: document RELEASE_TOKEN setup; fix npm run -- syntax
1 parent 86c2d93 commit efbc72f

5 files changed

Lines changed: 48 additions & 9 deletions

File tree

.github/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ changelog:
44
- ignore-for-release
55
- release
66
authors:
7-
- github-actions
8-
- dependabot
7+
- github-actions[bot]
8+
- dependabot[bot]
99
categories:
1010
- title: Breaking Changes
1111
labels:

.github/workflows/npm-publish.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,21 @@ jobs:
138138
- name: Build example
139139
run: npm run build --workspace examples/${{ matrix.example }}
140140

141+
- name: Determine npm tag
142+
id: npm-tag
143+
run: |
144+
VERSION=$(node -p "require('./package.json').version")
145+
if [[ "$VERSION" == *"-beta"* ]]; then
146+
echo "tag=--tag beta" >> $GITHUB_OUTPUT
147+
elif [[ "${{ github.event.release.target_commitish }}" != "main" ]]; then
148+
MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2)
149+
echo "tag=--tag release-${MAJOR_MINOR}" >> $GITHUB_OUTPUT
150+
else
151+
echo "tag=" >> $GITHUB_OUTPUT
152+
fi
153+
141154
- name: Publish example
142-
run: npm publish --workspace examples/${{ matrix.example }} --provenance --access public
155+
run: npm publish --workspace examples/${{ matrix.example }} --provenance --access public ${{ steps.npm-tag.outputs.tag }}
143156
env:
144157
NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET }}
145158

.github/workflows/release.yml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ on:
99
default: patch
1010
preid:
1111
description: "Prerelease identifier (only used with bump=prerelease)"
12-
required: false
12+
type: choice
13+
options: [beta]
1314
default: beta
1415
pull_request:
1516
types: [closed]
@@ -30,6 +31,8 @@ jobs:
3031
runs-on: ubuntu-latest
3132
steps:
3233
- uses: actions/checkout@v6
34+
with:
35+
ref: main
3336

3437
- uses: actions/setup-node@v6
3538
with:
@@ -50,12 +53,13 @@ jobs:
5053
git checkout -b "$BRANCH"
5154
git add -u
5255
git commit -m "chore: release v$VERSION"
53-
git push -f -u origin "$BRANCH"
56+
git push -u origin "$BRANCH"
57+
gh label create release --color B60205 --description "Release PR" 2>/dev/null || true
5458
gh pr create \
5559
--title "chore: release v$VERSION" \
5660
--body "Bumps all packages to \`$VERSION\`. Add release notes to \`RELEASES.md\` before merging. Merging this PR will automatically tag and create the GitHub Release, which triggers npm-publish." \
5761
--label release \
58-
--base main || gh pr edit "$BRANCH" --title "chore: release v$VERSION"
62+
--base main
5963
6064
# When a release PR is merged, tag the commit and create the GitHub Release.
6165
# This triggers the npm-publish workflow.
@@ -68,9 +72,13 @@ jobs:
6872
steps:
6973
- uses: actions/checkout@v6
7074
with:
71-
ref: main
75+
ref: ${{ github.event.pull_request.merge_commit_sha }}
7276

7377
- name: Create tag and release
78+
env:
79+
# PAT so the `release: published` event triggers npm-publish
80+
# (events from GITHUB_TOKEN don't cascade to other workflows)
81+
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
7482
run: |
7583
VERSION=$(node -p "require('./package.json').version")
7684
TAG="v$VERSION"
@@ -79,7 +87,7 @@ jobs:
7987
exit 0
8088
fi
8189
git tag "$TAG"
82-
git push origin "$TAG"
90+
git push origin "$TAG" || echo "tag already on remote"
8391
PRERELEASE=""
8492
[[ "$VERSION" == *-* ]] && PRERELEASE="--prerelease"
8593
gh release create "$TAG" --title "$TAG" --generate-notes $PRERELEASE

CONTRIBUTING.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,11 @@ Before publishing releases, ensure the following are configured:
529529
- Name it `Release`
530530
- Add required reviewers or other protection rules as needed
531531

532+
3. **`RELEASE_TOKEN` secret**: The release workflow creates GitHub Releases that must trigger the npm-publish workflow. Events from the default `GITHUB_TOKEN` don't cascade to other workflows, so a separate token is needed.
533+
- Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) scoped to this repository with **Contents: write** permission
534+
- Go to Settings > Secrets and variables > Actions > New repository secret
535+
- Name: `RELEASE_TOKEN`, value: the PAT
536+
532537
### Publishing a Release
533538

534539
Releases are automated via the [Release workflow](https://github.com/modelcontextprotocol/ext-apps/actions/workflows/release.yml).
@@ -544,6 +549,7 @@ Releases are automated via the [Release workflow](https://github.com/modelcontex
544549
- The workflow bumps the version across all packages and opens a PR labeled `release`
545550
- Add release notes to `RELEASES.md` in the PR
546551
- Approve and merge the PR
552+
- _Note: re-running the workflow for the same version fails if the branch already exists. Delete the `release/vX.Y.Z` branch first if you need to redo the bump._
547553

548554
3. **Done** — merging the PR automatically tags the commit and creates the GitHub Release (with auto-generated notes), which triggers the [npm-publish workflow](https://github.com/modelcontextprotocol/ext-apps/actions/workflows/npm-publish.yml). Approve the deployment once when prompted.
549555

@@ -552,7 +558,7 @@ Releases are automated via the [Release workflow](https://github.com/modelcontex
552558
You can also bump versions locally:
553559

554560
```bash
555-
npm run bump patch # or minor, major, prerelease --preid=beta
561+
npm run bump -- patch # or: minor | major | prerelease --preid=beta
556562
```
557563

558564
Then commit, push, and create a GitHub Release manually — the npm-publish workflow triggers on release creation.

scripts/bump-version.mjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
import { execSync } from "node:child_process";
17+
import { readFileSync } from "node:fs";
1718

1819
const args = process.argv.slice(2);
1920
if (!args[0]) {
@@ -28,10 +29,21 @@ const exec = (cmd) =>
2829
.toString()
2930
.trim();
3031

32+
const pkgName = JSON.parse(readFileSync("package.json", "utf-8")).name;
33+
3134
const newVersion = exec(
3235
`npm version ${args.join(" ")} --no-git-tag-version`,
3336
).replace(/^v/, "");
3437
exec(`npm pkg set version=${newVersion} --workspaces`);
3538

39+
// Keep workspace dependency ranges compatible (needed on major bumps)
40+
const [major, minor] = newVersion.split(".");
41+
exec(
42+
`npm pkg set "dependencies.${pkgName}=^${major}.${minor}.0" --workspaces`,
43+
);
44+
45+
// Sync package-lock.json so `npm ci` doesn't reject the release PR
46+
exec("npm install --package-lock-only --ignore-scripts");
47+
3648
console.error(`Bumped root + workspaces to ${newVersion}`);
3749
console.log(newVersion);

0 commit comments

Comments
 (0)