Skip to content

Commit 6d06b7d

Browse files
committed
feat(npm-release): implement prepare-release job for automated versioning and publishing
1 parent 267b859 commit 6d06b7d

1 file changed

Lines changed: 118 additions & 11 deletions

File tree

.github/workflows/npm-release.yaml

Lines changed: 118 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ name: "npm Release"
3636
#
3737
# 3. Now this workflow can publish subsequent versions automatically
3838

39+
#
40+
# RELEASE FLOW:
41+
# 1. prepare-release: Creates a release branch, bumps VERSION/sqlite-vec.h/package.json
42+
# 2. build-*: All builds run from the release branch (with correct version baked in)
43+
# 3. publish-npm: Publishes to npm, then merges release branch to main on success
44+
#
45+
# If any step fails, main is untouched and the release branch can be deleted.
46+
#
47+
3948
on:
4049
workflow_dispatch:
4150
inputs:
@@ -53,10 +62,70 @@ permissions:
5362
contents: read
5463

5564
jobs:
65+
prepare-release:
66+
runs-on: ubuntu-24.04
67+
permissions:
68+
contents: write
69+
outputs:
70+
release_branch: ${{ steps.prepare.outputs.branch }}
71+
new_version: ${{ steps.prepare.outputs.version }}
72+
steps:
73+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
74+
with:
75+
fetch-depth: 0
76+
77+
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
78+
with:
79+
node-version: "20"
80+
81+
- uses: photostructure/git-ssh-signing-action@fdd4b062a9ba41473f013258cc9c7eea1640f826 # v1.2.0
82+
with:
83+
ssh-signing-key: ${{ secrets.SSH_SIGNING_KEY }}
84+
git-user-name: ${{ secrets.GIT_USER_NAME }}
85+
git-user-email: ${{ secrets.GIT_USER_EMAIL }}
86+
87+
- name: Prepare release branch
88+
id: prepare
89+
run: |
90+
# Get current version from VERSION file (source of truth)
91+
CURRENT=$(cat VERSION | tr -d '[:space:]')
92+
echo "Current version: $CURRENT"
93+
94+
# Calculate new version using npm's semver
95+
# Strip any prerelease suffix for the bump, then we'll keep it simple (no prerelease)
96+
BASE_VERSION=$(echo "$CURRENT" | sed 's/-.*//')
97+
NEW_VERSION=$(npx semver -i ${{ github.event.inputs.version }} "$BASE_VERSION")
98+
echo "New version: $NEW_VERSION"
99+
100+
# Create release branch
101+
BRANCH="release/v${NEW_VERSION}"
102+
git checkout -b "$BRANCH"
103+
104+
# Update VERSION file
105+
echo "$NEW_VERSION" > VERSION
106+
107+
# Regenerate sqlite-vec.h from template
108+
make sqlite-vec.h
109+
110+
# Update package.json (without creating git commit/tag)
111+
npm version "$NEW_VERSION" --no-git-tag-version
112+
113+
# Commit all version changes
114+
git add VERSION sqlite-vec.h package.json package-lock.json
115+
git commit -S -m "release: v${NEW_VERSION}"
116+
git push origin "$BRANCH"
117+
118+
# Output for subsequent jobs
119+
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
120+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
121+
56122
build-linux-x64:
123+
needs: [prepare-release]
57124
runs-on: ubuntu-24.04
58125
steps:
59126
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
127+
with:
128+
ref: ${{ needs.prepare-release.outputs.release_branch }}
60129
- run: ./scripts/vendor.sh
61130
- run: make loadable
62131
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -65,21 +134,26 @@ jobs:
65134
path: dist/vec0.so
66135

67136
build-linux-arm64:
137+
needs: [prepare-release]
68138
runs-on: ubuntu-24.04-arm
69139
steps:
70140
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
141+
with:
142+
ref: ${{ needs.prepare-release.outputs.release_branch }}
71143
- run: ./scripts/vendor.sh
72-
- run: make sqlite-vec.h
73144
- run: make loadable
74145
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
75146
with:
76147
name: linux-arm64
77148
path: dist/vec0.so
78149

79150
build-linux-x64-musl:
151+
needs: [prepare-release]
80152
runs-on: ubuntu-24.04
81153
steps:
82154
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
155+
with:
156+
ref: ${{ needs.prepare-release.outputs.release_branch }}
83157
- run: |
84158
docker run --rm -v $(pwd):/tmp/project --entrypoint /bin/sh --platform linux/amd64 node:20-alpine -c "\
85159
apk add build-base bash curl unzip --update-cache && \
@@ -92,9 +166,12 @@ jobs:
92166
path: dist/vec0.so
93167

94168
build-linux-arm64-musl:
169+
needs: [prepare-release]
95170
runs-on: ubuntu-24.04-arm
96171
steps:
97172
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
173+
with:
174+
ref: ${{ needs.prepare-release.outputs.release_branch }}
98175
- run: |
99176
docker run --rm -v $(pwd):/tmp/project --entrypoint /bin/sh --platform linux/arm64 node:20-alpine -c "\
100177
apk add build-base bash curl unzip --update-cache && \
@@ -107,9 +184,12 @@ jobs:
107184
path: dist/vec0.so
108185

109186
build-darwin-x64:
187+
needs: [prepare-release]
110188
runs-on: macos-15-intel
111189
steps:
112190
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
191+
with:
192+
ref: ${{ needs.prepare-release.outputs.release_branch }}
113193
- run: ./scripts/vendor.sh
114194
- run: make loadable
115195
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -118,9 +198,12 @@ jobs:
118198
path: dist/vec0.dylib
119199

120200
build-darwin-arm64:
201+
needs: [prepare-release]
121202
runs-on: macos-14
122203
steps:
123204
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
205+
with:
206+
ref: ${{ needs.prepare-release.outputs.release_branch }}
124207
- run: ./scripts/vendor.sh
125208
- run: make loadable
126209
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -129,13 +212,15 @@ jobs:
129212
path: dist/vec0.dylib
130213

131214
build-win32-x64:
215+
needs: [prepare-release]
132216
runs-on: windows-latest
133217
steps:
134218
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
219+
with:
220+
ref: ${{ needs.prepare-release.outputs.release_branch }}
135221
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
136222
- run: ./scripts/vendor.sh
137223
shell: bash
138-
- run: make sqlite-vec.h
139224
- run: mkdir dist
140225
- run: cl.exe /fPIC -shared /W4 /Ivendor/ /O2 /LD sqlite-vec.c -o dist/vec0.dll
141226
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -144,15 +229,17 @@ jobs:
144229
path: dist/vec0.dll
145230

146231
build-win32-arm64:
232+
needs: [prepare-release]
147233
runs-on: windows-11-arm
148234
steps:
149235
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
236+
with:
237+
ref: ${{ needs.prepare-release.outputs.release_branch }}
150238
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
151239
with:
152240
arch: arm64
153241
- run: ./scripts/vendor.sh
154242
shell: bash
155-
- run: make sqlite-vec.h
156243
- run: mkdir dist
157244
- run: cl.exe /fPIC -shared /W4 /Ivendor/ /O2 /LD sqlite-vec.c -o dist/vec0.dll
158245
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
@@ -164,6 +251,7 @@ jobs:
164251
runs-on: ubuntu-24.04
165252
needs:
166253
[
254+
prepare-release,
167255
build-linux-x64,
168256
build-linux-arm64,
169257
build-linux-x64-musl,
@@ -176,10 +264,14 @@ jobs:
176264
permissions:
177265
contents: write # Required to push version commits and tags
178266
id-token: write # Required for npm OIDC trusted publishing
267+
env:
268+
NEW_VERSION: ${{ needs.prepare-release.outputs.new_version }}
269+
RELEASE_BRANCH: ${{ needs.prepare-release.outputs.release_branch }}
179270
steps:
180271
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
181272
with:
182-
fetch-depth: 0 # Full history for version tags
273+
ref: ${{ needs.prepare-release.outputs.release_branch }}
274+
fetch-depth: 0 # Full history for merging
183275

184276
# Download all artifacts into platform-specific subdirectories
185277
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
@@ -233,12 +325,7 @@ jobs:
233325
- name: Bump version and create signed tag
234326
run: |
235327
npm version ${{ github.event.inputs.version }} --sign-git-tag -m "release: %s"
236-
NEW_VERSION=$(npm pkg get version | tr -d '"')
237-
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
238-
# Keep VERSION file in sync with package.json
239-
echo "$NEW_VERSION" > VERSION
240-
git add VERSION
241-
git commit --amend --no-edit
328+
echo "NEW_VERSION=$(npm pkg get version | tr -d '\"')" >> $GITHUB_ENV
242329
243330
- name: Push version commit and tag
244331
run: git push origin main --follow-tags
@@ -250,11 +337,31 @@ jobs:
250337

251338
- name: Publish to npm with OIDC
252339
run: |
253-
VERSION="${{ env.NEW_VERSION }}"
340+
VERSION="${NEW_VERSION}"
254341
# Extract prerelease identifier if present (e.g., "beta" from "1.0.0-beta.1")
255342
if [[ "$VERSION" == *"-"* ]]; then
256343
TAG=$(echo "$VERSION" | sed 's/.*-\([a-zA-Z]*\).*/\1/')
257344
npm publish --provenance --access public --tag "$TAG"
258345
else
259346
npm publish --provenance --access public
260347
fi
348+
349+
# Only after successful npm publish: merge to main, tag, and create release
350+
- name: Merge release branch to main
351+
run: |
352+
git checkout main
353+
git merge --ff-only "$RELEASE_BRANCH"
354+
355+
- name: Create signed tag
356+
run: git tag -s "v${NEW_VERSION}" -m "v${NEW_VERSION}"
357+
358+
- name: Push to main with tag
359+
run: git push origin main --follow-tags
360+
361+
- name: Delete release branch
362+
run: git push origin --delete "$RELEASE_BRANCH"
363+
364+
- name: Create GitHub Release
365+
run: gh release create "v${NEW_VERSION}" --generate-notes
366+
env:
367+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)