npm Release #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. prepare-release: Creates a release branch, bumps VERSION/sqlite-vec.h/package.json | |
| # 2. build-*: All builds run from the release branch (with correct version baked in) | |
| # 3. 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. | |
| # | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Version bump type" | |
| required: false | |
| type: choice | |
| default: "patch" | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| 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: | | |
| # Get current version from VERSION file (source of truth) | |
| CURRENT=$(cat VERSION | tr -d '[:space:]') | |
| echo "Current version: $CURRENT" | |
| # Calculate new version using npm's semver | |
| # Strip any prerelease suffix for the bump, then we'll keep it simple (no prerelease) | |
| BASE_VERSION=$(echo "$CURRENT" | sed 's/-.*//') | |
| NEW_VERSION=$(npx semver -i ${{ github.event.inputs.version }} "$BASE_VERSION") | |
| echo "New version: $NEW_VERSION" | |
| # Create release branch | |
| BRANCH="release/v${NEW_VERSION}" | |
| git checkout -b "$BRANCH" | |
| # Update VERSION file | |
| echo "$NEW_VERSION" > VERSION | |
| # Regenerate sqlite-vec.h from template | |
| make sqlite-vec.h | |
| # Update package.json (without creating git commit/tag) | |
| npm version "$NEW_VERSION" --no-git-tag-version | |
| # Commit all version changes | |
| git add VERSION sqlite-vec.h package.json package-lock.json | |
| git commit -S -m "release: v${NEW_VERSION}" | |
| git push origin "$BRANCH" | |
| # Output for subsequent jobs | |
| echo "branch=$BRANCH" >> $GITHUB_OUTPUT | |
| echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| 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: Bump version and create signed tag | |
| run: | | |
| npm version ${{ github.event.inputs.version }} --sign-git-tag -m "release: %s" | |
| echo "NEW_VERSION=$(npm pkg get version | tr -d '\"')" >> $GITHUB_ENV | |
| - name: Push version commit and tag | |
| run: git push origin main --follow-tags | |
| - name: Create GitHub Release | |
| run: gh release create "v${{ env.NEW_VERSION }}" --generate-notes | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - 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 }} |