Skip to content

Release

Release #197

Workflow file for this run

name: Release
# Automated releases trigger after CI completes on main. Release commits
# contain [skip ci] so GitHub skips CI for them entirely, breaking the loop
# without any extra condition needed.
#
# A single file calls _release.reusable.yml so that npm OIDC trusted
# publishing can be configured against one workflow filename.
on:
workflow_run:
workflows: [CI]
types: [completed]
branches: [main]
workflow_dispatch:
inputs:
packages:
description: Packages to release
type: choice
options:
- all
- version
- notes
- publish
- release
default: all
bump:
description: Version bump type
type: choice
options:
- auto
- patch
- minor
- major
- prerelease
- prepatch
- preminor
- premajor
default: auto
npm_auth:
description: NPM auth method
type: choice
options:
- auto
- oidc
- token
default: oidc
sync:
description: Use synchronized versioning across all packages
type: boolean
default: true
dry_run:
description: Dry run (no publish, no push)
type: boolean
default: true
concurrency:
group: release
cancel-in-progress: false
jobs:
check-labels:
name: Check Release Labels
runs-on: ubuntu-latest
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push'
outputs:
should_release: ${{ steps.check.outputs.should_release }}
bump: ${{ steps.check.outputs.bump }}
steps:
- name: Check for release labels
id: check
env:
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
# Helper function to safely call gh API and capture output
gh_api() {
local result
result=$(gh api "$1" 2>&1) || true
echo "$result"
}
# Get PRs that were merged with this commit (includes labels)
PRS_OUTPUT=$(gh_api "repos/$REPO/commits/$COMMIT_SHA/pulls")
PRS=$(echo "$PRS_OUTPUT" | jq -r '.[].number' 2>/dev/null | tr '\n' ' ') || PRS=""
if [ -z "$PRS" ]; then
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "No PRs found for commit, skipping release"
[ -n "$PRS_OUTPUT" ] && echo "Debug: $PRS_OUTPUT"
exit 0
fi
# Extract the release label and derive the bump type from it.
# 'stable' maps to 'auto' (conventional commits determine type, no prerelease).
# All other labels map 1:1 to their bump type.
LABELS=$(echo "$PRS_OUTPUT" | jq -r '.[].labels[].name' 2>/dev/null)
RELEASE_LABEL=$(echo "$LABELS" | grep -E "^release:(patch|minor|major|prerelease|stable)$" | head -1)
if [ -n "$RELEASE_LABEL" ]; then
BUMP_TYPE="${RELEASE_LABEL#release:}"
[ "$BUMP_TYPE" = "stable" ] && BUMP_TYPE="auto"
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "bump=$BUMP_TYPE" >> "$GITHUB_OUTPUT"
echo "Release label '${RELEASE_LABEL}' found — bump: ${BUMP_TYPE}"
exit 0
fi
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "No release label found on merged PRs, skipping release"
release-auto:
name: Auto Release
needs: check-labels
if: needs.check-labels.outputs.should_release == 'true'
uses: ./.github/workflows/_release.reusable.yml
permissions:
id-token: write
contents: write
with:
packages: all
bump: ${{ needs.check-labels.outputs.bump || 'auto' }}
sync: true
dry_run: false
npm_auth: oidc
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
OLLAMA_API_KEY: ${{ secrets.OLLAMA_API_KEY }}
release-manual:
name: Manual Release
if: github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/_release.reusable.yml
permissions:
id-token: write
contents: write
with:
packages: ${{ inputs.packages }}
bump: ${{ inputs.bump }}
npm_auth: ${{ inputs.npm_auth }}
sync: ${{ inputs.sync }}
dry_run: ${{ inputs.dry_run }}
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
OLLAMA_API_KEY: ${{ secrets.OLLAMA_API_KEY }}
build-action-manual:
name: Build and tag action dist
needs: release-manual
if: ${{ github.event_name == 'workflow_dispatch' && needs.release-manual.outputs.action_tag != '' }}
uses: ./.github/workflows/_action-release.reusable.yml
permissions:
contents: write
with:
tag: ${{ needs.release-manual.outputs.action_tag }}
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
build-action-auto:
name: Build and tag action dist
needs: release-auto
if: ${{ github.event_name == 'workflow_run' && needs.release-auto.outputs.action_tag != '' }}
uses: ./.github/workflows/_action-release.reusable.yml
permissions:
contents: write
with:
tag: ${{ needs.release-auto.outputs.action_tag }}
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}