Skip to content

npm Release

npm Release #11

Workflow file for this run

name: "npm Release"
# Fork-specific workflow for publishing to npm with OIDC
# Separate from release.yaml to make merging upstream changes easier
#
# APPROACH: We bundle all platform binaries in a single npm package (like
# prebuildify) rather than using platform-specific optionalDependencies (like
# esbuild/swc). Rationale:
# - Simpler: one package to publish, not 5+ platform packages
# - More secure: avoids post-install scripts and dependency on npm registry
# - Reliable: works offline, with disabled scripts, and custom registries
# - Small overhead: sqlite-vec binaries are ~200KB each, so bundling all is
# fine
#
# FIRST-TIME SETUP (required before this workflow will work):
#
# 1. Build and publish the package locally to create it on npm:
# ```sh
# ./scripts/vendor.sh
# make loadable
# mkdir -p dist/$(node -p "process.platform + '-' + process.arch")
# cp dist/vec0.* dist/$(node -p "process.platform + '-' + process.arch")/
# npm login
# npm publish --access public --tag alpha # use --tag for prerelease versions
# ```
#
# 2. Configure OIDC trusted publishing on npmjs.com:
# - Go to https://www.npmjs.com/package/@USER/sqlite-vec/access
# - Under "Publishing access" click "Add a trusted publisher"
# - Repository: USER/sqlite-vec
# - Workflow: npm-release.yaml
# - Environment: (leave blank)
#
# 3. Now this workflow can publish subsequent versions automatically
#
# RELEASE FLOW:
# 1. Manually bump VERSION file and update CHANGELOG-mceachen.md on main
# 2. prepare-release: Creates a release branch, syncs VERSION to sqlite-vec.h/package.json
# 3. build-*: All builds run from the release branch (with correct version baked in)
# 4. publish-npm: Publishes to npm, then merges release branch to main on success
#
# If any step fails, main is untouched and the release branch can be deleted.
#
# BEFORE TRIGGERING THIS WORKFLOW:
# - Bump VERSION file (e.g., 0.4.0 → 0.4.1)
# - Update CHANGELOG-mceachen.md with release notes
# - Commit to main: git commit -am "release: prepare v0.4.1"
#
on:
workflow_dispatch:
permissions:
contents: read
jobs:
prepare-release:
runs-on: ubuntu-24.04
permissions:
contents: write
outputs:
release_branch: ${{ steps.prepare.outputs.branch }}
new_version: ${{ steps.prepare.outputs.version }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: "20"
- uses: photostructure/git-ssh-signing-action@fdd4b062a9ba41473f013258cc9c7eea1640f826 # v1.2.0
with:
ssh-signing-key: ${{ secrets.SSH_SIGNING_KEY }}
git-user-name: ${{ secrets.GIT_USER_NAME }}
git-user-email: ${{ secrets.GIT_USER_EMAIL }}
- name: Prepare release branch
id: prepare
run: ./scripts/prepare-release.sh
build-linux-x64:
needs: [prepare-release]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: ./scripts/vendor.sh
- run: make loadable
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: linux-x64
path: dist/vec0.so
build-linux-arm64:
needs: [prepare-release]
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: ./scripts/vendor.sh
- run: make loadable
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: linux-arm64
path: dist/vec0.so
build-linux-x64-musl:
needs: [prepare-release]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: |
docker run --rm -v $(pwd):/tmp/project --entrypoint /bin/sh --platform linux/amd64 node:20-alpine -c "\
apk add build-base bash curl unzip --update-cache && \
cd /tmp/project && \
./scripts/vendor.sh && \
make loadable"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: linux-x64-musl
path: dist/vec0.so
build-linux-arm64-musl:
needs: [prepare-release]
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: |
docker run --rm -v $(pwd):/tmp/project --entrypoint /bin/sh --platform linux/arm64 node:20-alpine -c "\
apk add build-base bash curl unzip --update-cache && \
cd /tmp/project && \
./scripts/vendor.sh && \
make loadable"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: linux-arm64-musl
path: dist/vec0.so
build-darwin-x64:
needs: [prepare-release]
runs-on: macos-15-intel
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: ./scripts/vendor.sh
- run: make loadable
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: darwin-x64
path: dist/vec0.dylib
build-darwin-arm64:
needs: [prepare-release]
runs-on: macos-14
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- run: ./scripts/vendor.sh
- run: make loadable
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: darwin-arm64
path: dist/vec0.dylib
build-win32-x64:
needs: [prepare-release]
runs-on: windows-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- run: ./scripts/vendor.sh
shell: bash
- run: mkdir dist
- run: cl.exe /fPIC -shared /W4 /Ivendor/ /O2 /LD sqlite-vec.c -o dist/vec0.dll
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: win32-x64
path: dist/vec0.dll
build-win32-arm64:
needs: [prepare-release]
runs-on: windows-11-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
with:
arch: arm64
- run: ./scripts/vendor.sh
shell: bash
- run: mkdir dist
- run: cl.exe /fPIC -shared /W4 /Ivendor/ /O2 /LD sqlite-vec.c -o dist/vec0.dll
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: win32-arm64
path: dist/vec0.dll
publish-npm:
runs-on: ubuntu-24.04
needs:
[
prepare-release,
build-linux-x64,
build-linux-arm64,
build-linux-x64-musl,
build-linux-arm64-musl,
build-darwin-x64,
build-darwin-arm64,
build-win32-x64,
build-win32-arm64,
]
permissions:
contents: write # Required to push version commits and tags
id-token: write # Required for npm OIDC trusted publishing
env:
NEW_VERSION: ${{ needs.prepare-release.outputs.new_version }}
RELEASE_BRANCH: ${{ needs.prepare-release.outputs.release_branch }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ needs.prepare-release.outputs.release_branch }}
fetch-depth: 0 # Full history for merging
# Download all artifacts into platform-specific subdirectories
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: linux-x64
path: dist/linux-x64
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: linux-arm64
path: dist/linux-arm64
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: linux-x64-musl
path: dist/linux-x64-musl
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: linux-arm64-musl
path: dist/linux-arm64-musl
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: darwin-x64
path: dist/darwin-x64
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: darwin-arm64
path: dist/darwin-arm64
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: win32-x64
path: dist/win32-x64
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: win32-arm64
path: dist/win32-arm64
- run: ls -laR dist/
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"
- uses: photostructure/git-ssh-signing-action@fdd4b062a9ba41473f013258cc9c7eea1640f826 # v1.2.0
with:
ssh-signing-key: ${{ secrets.SSH_SIGNING_KEY }}
git-user-name: ${{ secrets.GIT_USER_NAME }}
git-user-email: ${{ secrets.GIT_USER_EMAIL }}
- run: npm install -g npm@latest
- name: Publish to npm with OIDC
run: |
VERSION="${NEW_VERSION}"
# Extract prerelease identifier if present (e.g., "beta" from "1.0.0-beta.1")
if [[ "$VERSION" == *"-"* ]]; then
TAG=$(echo "$VERSION" | sed 's/.*-\([a-zA-Z]*\).*/\1/')
npm publish --provenance --access public --tag "$TAG"
else
npm publish --provenance --access public
fi
# Only after successful npm publish: merge to main, tag, and create release
- name: Merge release branch to main
run: |
git checkout main
git merge --ff-only "$RELEASE_BRANCH"
- name: Create signed tag
run: git tag -s "v${NEW_VERSION}" -m "v${NEW_VERSION}"
- name: Push to main with tag
run: git push origin main --follow-tags
- name: Delete release branch
run: git push origin --delete "$RELEASE_BRANCH"
- name: Create GitHub Release
run: gh release create "v${NEW_VERSION}" --generate-notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}