Skip to content

Release

Release #73

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
version:
description: "Specific version to release (e.g. 1.2.3, 1.2.3-beta.1, 1.2.3-rc.1), or leave empty for auto-detect from conventional commits"
required: false
type: string
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.release_meta.outputs.version }}
prerelease: ${{ steps.release_meta.outputs.prerelease }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Determine next version (auto)
if: inputs.version == ''
id: semver
uses: ietf-tools/semver-action@v1
with:
token: ${{ github.token }}
noVersionBumpBehavior: patch
noNewCommitBehavior: patch
- name: Validate manual version
if: inputs.version != ''
run: |
if ! echo "${{ inputs.version }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-(beta|rc)\.[0-9]+)?$'; then
echo "::error::Invalid version format '${{ inputs.version }}'. Expected X.Y.Z, X.Y.Z-beta.N, or X.Y.Z-rc.N"
exit 1
fi
- name: Set release metadata
id: release_meta
env:
VERSION: ${{ inputs.version != '' && inputs.version || steps.semver.outputs.nextStrict }}
run: |
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+-(beta|rc)\.[0-9]+$'; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
- name: Create tag
env:
VERSION: ${{ steps.release_meta.outputs.version }}
run: |
git tag "$VERSION"
git push origin "$VERSION"
- name: Generate release notes
id: changelog
env:
VERSION: ${{ steps.release_meta.outputs.version }}
run: |
PREV_TAG=$(git tag --sort=-version:refname | grep -Fxv "$VERSION" | head -n 1 || true)
NOTES_FILE=$(mktemp)
if [ -n "$PREV_TAG" ]; then
git log --pretty=format:'- %s (%h)' "$PREV_TAG..$VERSION" > "$NOTES_FILE"
else
git log --pretty=format:'- %s (%h)' -n 20 "$VERSION" > "$NOTES_FILE"
fi
if [ ! -s "$NOTES_FILE" ]; then
echo "- No commit summary available for $VERSION." > "$NOTES_FILE"
fi
{
echo "changes<<EOF"
echo "## Changes"
echo ""
cat "$NOTES_FILE"
echo ""
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.release_meta.outputs.version }}
body: ${{ steps.changelog.outputs.changes }}
prerelease: ${{ steps.release_meta.outputs.prerelease == 'true' }}
desktop:
needs: release
permissions:
contents: write
uses: ./.github/workflows/release-desktop.yml
with:
version: ${{ needs.release.outputs.version }}
secrets: inherit
npm:
needs: release
permissions:
contents: read
id-token: write
# Trusted publishing validates the caller workflow for workflow_call jobs.
# Keep npm bound to release.yml as the production publish entrypoint.
uses: ./.github/workflows/npm-publish.yml
with:
version: ${{ needs.release.outputs.version }}
allow-publish: true
dry-run: false
homebrew:
needs: [release, desktop]
if: needs.release.outputs.prerelease == 'false'
uses: ./.github/workflows/release-cask.yml
with:
version: ${{ needs.release.outputs.version }}
secrets: inherit