Skip to content

Manual Release

Manual Release #17

name: Manual Release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (for example 0.5.4 or v0.5.4)'
required: true
type: string
release_notes:
description: 'Operator-focused Markdown release notes'
required: true
type: string
concurrency:
group: manual-release
cancel-in-progress: false
jobs:
prepare-release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Generate bot token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ secrets.BOT_CLIENT_ID }}
private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
- name: Checkout main
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: main
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '24'
cache: 'npm'
- name: Normalize and validate version
id: version
env:
RAW_VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
VERSION="${RAW_VERSION#v}"
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid version: $RAW_VERSION"
exit 1
fi
if git rev-parse "refs/tags/v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Bump version
env:
VERSION: ${{ steps.version.outputs.version }}
run: npm version "$VERSION" --no-git-tag-version
- name: Commit and push release branch
id: branch
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
BRANCH="chore/release-v${VERSION}-${GITHUB_RUN_ID}"
git config user.name "smurf-bot[bot]"
git config user.email "smurf-bot[bot]@users.noreply.github.com"
git add package.json package-lock.json
git commit -m "chore(release): bump version to ${VERSION}"
git push origin "HEAD:refs/heads/${BRANCH}"
echo "name=$BRANCH" >> "$GITHUB_OUTPUT"
- name: Open release PR and enable auto-merge
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
BRANCH: ${{ steps.branch.outputs.name }}
VERSION: ${{ steps.version.outputs.version }}
RELEASE_NOTES: ${{ inputs.release_notes }}
run: |
set -euo pipefail
BODY=$(printf 'Version bump for release v%s. The release will be published after this PR passes the required checks and merges.\n\n<!-- release-notes -->\n%s\n' "$VERSION" "$RELEASE_NOTES")
PR_URL=$(gh pr create --repo "$GITHUB_REPOSITORY" --base main --head "$BRANCH" --title "chore(release): bump version to ${VERSION}" --body "$BODY")
gh pr merge "$PR_URL" --repo "$GITHUB_REPOSITORY" --auto --squash --delete-branch
echo "Release PR: $PR_URL"