name: 'Release: NPM Package'
on:
workflow_dispatch:
inputs:
releaseMode:
description: 'Release mode'
required: true
type: choice
default: 'prod'
options:
- 'prod' # Production release with @latest tag
- 'dev' # Dev release with @dev tag
releaseType:
description: 'Semver release type (prod only)'
required: false
type: choice
default: 'patch'
options:
- 'patch' # bug fixes
- 'minor' # new features, backwards compatible
- 'major' # breaking changes
ref:
description: 'Branch name or SHA to release from (defaults to current branch)'
required: false
type: string
default: ''
# allow parallel releases of different modes, queue releases of the same mode
concurrency:
group: npm-release-${{ github.event.inputs.releaseMode }}
cancel-in-progress: false
permissions:
contents: write
id-token: write # Required for OIDC authentication with npm trusted publishing
jobs:
version-and-release:
name: Release to NPM
runs-on: ubuntu-latest
environment: npm-publish
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref != '' && inputs.ref || github.ref }}
- name: Validate ref is a branch for prod releases
if: inputs.releaseMode == 'prod' && inputs.ref != ''
shell: bash
run: |
if ! git symbolic-ref --short HEAD > /dev/null 2>&1; then
echo "Error: For prod releases, ref must be a valid branch name, not a SHA. Provided ref: ${{ inputs.ref }}. Current HEAD is detached."
exit 1
fi
- name: Setup
uses: ./.github/actions/setup
with:
node_version: '24.x'
git_email: 'clients@pinecone.io'
git_username: ${{ github.actor }}
##### VERSION BUMP #####
- name: 'Bump version for production release'
if: inputs.releaseMode == 'prod'
shell: bash
id: version-bump-prod
run: |
npm version ${{ inputs.releaseType }} --no-git-tag-version
newVersion=$(jq -r '.version' package.json)
echo "version=$newVersion" >> $GITHUB_OUTPUT
echo "Bumped version to $newVersion (prod release)"
- name: 'Bump version for dev release'
if: inputs.releaseMode == 'dev'
shell: bash
id: version-bump-dev
run: |
currentVersion=$(jq -r '.version' package.json)
timestamp=$(date +%Y%m%d%H%M%S)
newVersion="$currentVersion-dev.$timestamp"
npm version "$newVersion" --no-git-tag-version
echo "Bumped version to $newVersion (dev release)"
echo "version=$newVersion" >> $GITHUB_OUTPUT
##### COMMIT AND TAG VERSION CHANGES (prod) #####
- name: Commit and tag version changes for prod
if: github.event.inputs.releaseMode == 'prod'
shell: bash
run: |
git add . # commit version.json changes
newVersion="${{ steps.version-bump-prod.outputs.version }}"
git commit -m "[skip ci] Publish release v$newVersion"
git tag "v$newVersion"
##### NPM PUBLISH #####
- name: Publish to npm (prod)
if: github.event.inputs.releaseMode == 'prod'
run: npm publish --provenance --tag latest
shell: bash
- name: Publish to npm (dev)
if: github.event.inputs.releaseMode == 'dev'
run: npm publish --provenance --tag dev
shell: bash
##### GIT PUSH COMMIT AND TAG (prod) #####
- name: Push commit and tag (prod)
if: github.event.inputs.releaseMode == 'prod'
shell: bash
run: |
newVersion="${{ steps.version-bump-prod.outputs.version }}"
if [ -n "${{ github.event.inputs.ref }}" ]; then
git push origin "${{ github.event.inputs.ref }}" --follow-tags
git push origin "v$newVersion"
else
git push --follow-tags
git push origin "v$newVersion"
fi
##### CREATE DRAFT RELEASE (prod) #####
- name: Create draft release with notes (prod)
if: github.event.inputs.releaseMode == 'prod'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "v${{ steps.version-bump-prod.outputs.version }}" \
--draft \
--generate-notes \
--title "Release v${{ steps.version-bump-prod.outputs.version }}"