Release #217
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: 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. | |
| # Only bump:* labels are supported (release:* labels are deprecated). | |
| LABELS=$(echo "$PRS_OUTPUT" | jq -r '.[].labels[].name' 2>/dev/null) | |
| # Check for release:stable first (takes precedence over bump:* per ci-setup.md) | |
| if echo "$LABELS" | grep -qE "^release:stable$"; then | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| echo "bump=auto" >> "$GITHUB_OUTPUT" | |
| echo "release:stable label found — promoting prerelease to stable" | |
| exit 0 | |
| fi | |
| # Check for release:prerelease + bump:* (creates prerelease) | |
| if echo "$LABELS" | grep -qE "^release:prerelease$"; then | |
| # Map bump label to prerelease bump type | |
| PRERELEASE_BUMP="prerelease" | |
| if echo "$LABELS" | grep -qE "^bump:patch$"; then | |
| PRERELEASE_BUMP="prepatch" | |
| elif echo "$LABELS" | grep -qE "^bump:minor$"; then | |
| PRERELEASE_BUMP="preminor" | |
| elif echo "$LABELS" | grep -qE "^bump:major$"; then | |
| PRERELEASE_BUMP="premajor" | |
| fi | |
| if echo "$LABELS" | grep -qE "^bump:(patch|minor|major)$"; then | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| echo "bump=$PRERELEASE_BUMP" >> "$GITHUB_OUTPUT" | |
| echo "release:prerelease + bump:* label found — creating $PRERELEASE_BUMP prerelease" | |
| exit 0 | |
| else | |
| echo "should_release=false" >> "$GITHUB_OUTPUT" | |
| echo "release:prerelease requires a bump:* label — skipping release" | |
| exit 0 | |
| fi | |
| fi | |
| # Check for bump:* labels | |
| BUMP_LABEL=$(echo "$LABELS" | grep -E "^bump:(patch|minor|major)$" | head -1) | |
| if [ -n "$BUMP_LABEL" ]; then | |
| BUMP_TYPE="${BUMP_LABEL#bump:}" | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| echo "bump=$BUMP_TYPE" >> "$GITHUB_OUTPUT" | |
| echo "Bump label '${BUMP_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: | |
| ssh_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: | |
| ssh_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: | |
| ssh_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: | |
| ssh_key: ${{ secrets.DEPLOY_KEY }} |