Skip to content

Commit 3ab649e

Browse files
feat(mcp): add automated release workflow (#839)
* feat(mcp): add automated release workflow Add GitHub Actions workflow for releasing @sourcebot/mcp to npm. The workflow supports manual dispatch with version bump selection (patch, minor, major), updates CHANGELOG.md and package.json, builds and publishes to npm. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: use npm trusted publishing with OIDC Replace NPM_TOKEN with OIDC-based trusted publishing. Requires Node.js 24 for npm >= 11.5.1 support. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 0f21016 commit 3ab649e

File tree

2 files changed

+205
-0
lines changed

2 files changed

+205
-0
lines changed

.github/workflows/release-mcp.yml

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
name: Release MCP Package
2+
3+
permissions:
4+
contents: write
5+
id-token: write
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
bump_type:
11+
description: "Type of version bump to apply"
12+
required: true
13+
type: choice
14+
options:
15+
- patch
16+
- minor
17+
- major
18+
19+
concurrency:
20+
group: release-mcp
21+
cancel-in-progress: false
22+
23+
jobs:
24+
release:
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- name: Generate GitHub App token
29+
id: generate_token
30+
uses: actions/create-github-app-token@v1
31+
with:
32+
app-id: ${{ secrets.RELEASE_APP_ID }}
33+
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
34+
35+
- name: Checkout repository
36+
uses: actions/checkout@v4
37+
with:
38+
ref: main
39+
fetch-depth: 0
40+
token: ${{ steps.generate_token.outputs.token }}
41+
42+
- name: Setup Node.js
43+
uses: actions/setup-node@v4
44+
with:
45+
node-version: "24"
46+
registry-url: "https://registry.npmjs.org"
47+
48+
- name: Calculate new version
49+
id: calculate_version
50+
run: |
51+
# Extract current version from package.json
52+
CURRENT_VERSION=$(node -p "require('./packages/mcp/package.json').version")
53+
54+
if [ -z "$CURRENT_VERSION" ]; then
55+
echo "Error: Could not extract current version from package.json"
56+
exit 1
57+
fi
58+
59+
echo "Current version: $CURRENT_VERSION"
60+
61+
# Parse version components
62+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
63+
64+
# Apply bump based on input
65+
BUMP_TYPE="${{ inputs.bump_type }}"
66+
case "$BUMP_TYPE" in
67+
major)
68+
MAJOR=$((MAJOR + 1))
69+
MINOR=0
70+
PATCH=0
71+
;;
72+
minor)
73+
MINOR=$((MINOR + 1))
74+
PATCH=0
75+
;;
76+
patch)
77+
PATCH=$((PATCH + 1))
78+
;;
79+
*)
80+
echo "Error: Invalid bump type: $BUMP_TYPE"
81+
exit 1
82+
;;
83+
esac
84+
85+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
86+
echo "New version: $NEW_VERSION"
87+
88+
# Export to GITHUB_ENV for use in subsequent steps
89+
echo "VERSION=$NEW_VERSION" >> $GITHUB_ENV
90+
91+
# Export to GITHUB_OUTPUT for use in other jobs
92+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
93+
94+
- name: Check if version already exists
95+
run: |
96+
if grep -q "## \[$VERSION\]" packages/mcp/CHANGELOG.md; then
97+
echo "Error: Version $VERSION already exists in CHANGELOG.md"
98+
exit 1
99+
fi
100+
if git tag | grep -q "^mcp-v$VERSION$"; then
101+
echo "Error: Tag mcp-v$VERSION already exists"
102+
exit 1
103+
fi
104+
105+
- name: Update CHANGELOG.md
106+
run: |
107+
DATE=$(date +%Y-%m-%d)
108+
109+
# Insert the new version header after the [Unreleased] line
110+
sed -i "/## \[Unreleased\]/a\\
111+
\\
112+
## [$VERSION] - $DATE" packages/mcp/CHANGELOG.md
113+
114+
echo "Updated CHANGELOG.md with version $VERSION"
115+
cat packages/mcp/CHANGELOG.md | head -n 20
116+
117+
- name: Update package.json version
118+
run: |
119+
cd packages/mcp
120+
npm version $VERSION --no-git-tag-version
121+
echo "Updated package.json to version $VERSION"
122+
cat package.json | head -n 5
123+
124+
- name: Configure git
125+
run: |
126+
git config user.name "github-actions[bot]"
127+
git config user.email "github-actions[bot]@users.noreply.github.com"
128+
129+
- name: Commit changes
130+
run: |
131+
git add packages/mcp/CHANGELOG.md packages/mcp/package.json
132+
git commit -m "Release @sourcebot/mcp v$VERSION"
133+
134+
- name: Push to temporary branch
135+
id: push_temp_branch
136+
env:
137+
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
138+
run: |
139+
TEMP_BRANCH="release-mcp-v$VERSION"
140+
git push origin HEAD:refs/heads/$TEMP_BRANCH
141+
echo "Pushed commit to temporary branch: $TEMP_BRANCH"
142+
echo "temp_branch=$TEMP_BRANCH" >> $GITHUB_OUTPUT
143+
144+
- name: Install dependencies
145+
run: yarn install --frozen-lockfile
146+
147+
- name: Build MCP package
148+
run: yarn workspace @sourcebot/mcp build
149+
150+
- name: Publish to npm
151+
run: |
152+
cd packages/mcp
153+
npm publish --provenance --access public
154+
155+
- name: Fast-forward main to temporary branch
156+
env:
157+
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
158+
TEMP_BRANCH: ${{ steps.push_temp_branch.outputs.temp_branch }}
159+
run: |
160+
# Fetch main branch
161+
git fetch origin main:main
162+
git checkout main
163+
164+
# Check if fast-forward is possible
165+
if ! git merge-base --is-ancestor main "$TEMP_BRANCH"; then
166+
echo "❌ ERROR: Cannot fast-forward main branch to release commit"
167+
echo ""
168+
echo "This means new commits were pushed to main after the release process started."
169+
echo ""
170+
echo "Recent commits on main that caused the conflict:"
171+
git log --oneline $TEMP_BRANCH..main | head -5
172+
exit 1
173+
fi
174+
175+
# Fast-forward main to release commit
176+
git merge --ff-only "$TEMP_BRANCH"
177+
178+
echo "✓ Successfully fast-forwarded main to release commit"
179+
180+
- name: Push main
181+
env:
182+
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
183+
run: |
184+
git push origin main
185+
echo "Pushed main branch"
186+
187+
- name: Delete temporary branch
188+
if: always()
189+
env:
190+
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
191+
TEMP_BRANCH: ${{ steps.push_temp_branch.outputs.temp_branch }}
192+
run: |
193+
if [ -n "$TEMP_BRANCH" ]; then
194+
# Check if branch exists before attempting to delete
195+
if git ls-remote --heads origin "$TEMP_BRANCH" | grep -q "$TEMP_BRANCH"; then
196+
git push origin --delete "$TEMP_BRANCH"
197+
echo "✓ Deleted temporary branch: $TEMP_BRANCH"
198+
else
199+
echo "ℹ Temporary branch $TEMP_BRANCH does not exist (may have been already deleted)"
200+
fi
201+
fi

packages/mcp/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"url": "https://github.com/sourcebot-dev/sourcebot.git",
3333
"directory": "packages/mcp"
3434
},
35+
"publishConfig": {
36+
"access": "public",
37+
"registry": "https://registry.npmjs.org/"
38+
},
3539
"keywords": [
3640
"mcp",
3741
"modelcontextprotocol",

0 commit comments

Comments
 (0)