Skip to content

fix: release workflow poetry setup and Node 24 opt-in #2

fix: release workflow poetry setup and Node 24 opt-in

fix: release workflow poetry setup and Node 24 opt-in #2

Workflow file for this run

# Release workflow.
# Trigger model: only when a PR to main is closed and merged.
name: Release
on:
pull_request:
# Closed event is filtered below to merged-only.
types: [closed]
branches: [main]
permissions:
# Needed for creating tags and GitHub releases.
contents: write
env:
# Shared interpreter version for build and metadata steps.
PYTHON_VERSION: "3.11"
# Opt in to Node.js 24 for JavaScript-based actions ahead of runner defaults.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
version-and-release:
# Computes semantic version, creates git tag, and publishes GitHub release.
name: Compute Version and Tag
runs-on: ubuntu-latest
# Guard: run only for merged PRs.
if: github.event.pull_request.merged == true
outputs:
changed: ${{ steps.semver.outputs.changed }}
version: ${{ steps.semver.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
# Full history is required by semantic-version to inspect commit history.
fetch-depth: 0
ref: ${{ github.event.pull_request.merge_commit_sha }}
- name: Compute semantic version from commits
id: semver
uses: paulhatch/semantic-version@v5.4.0
with:
tag_prefix: ""
version_format: "${major}.${minor}.${patch}"
major_pattern: "(BREAKING CHANGE|!:)"
minor_pattern: "^feat"
search_commit_body: true
bump_each_commit: false
- name: Show computed version
run: |
echo "changed=${{ steps.semver.outputs.changed }}"
echo "version=${{ steps.semver.outputs.version }}"
- name: Enforce no-v SemVer tags
if: steps.semver.outputs.changed == 'true'
run: |
VERSION="${{ steps.semver.outputs.version }}"
# Repository policy: tags must be plain SemVer (for example 1.0.0), never v1.0.0.
if [[ "$VERSION" =~ ^v ]]; then
echo "ERROR: release tag must not start with 'v' (got '$VERSION')."
exit 1
fi
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: release tag must match X.Y.Z (got '$VERSION')."
exit 1
fi
- name: Create and push git tag
if: steps.semver.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git rev-parse "${{ steps.semver.outputs.version }}" >/dev/null 2>&1 && {
echo "ERROR: tag '${{ steps.semver.outputs.version }}' already exists.";
exit 1;
}
git tag -a "${{ steps.semver.outputs.version }}" -m "release ${{ steps.semver.outputs.version }}"
git push origin "${{ steps.semver.outputs.version }}"
- name: Create GitHub release
if: steps.semver.outputs.changed == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.semver.outputs.version }}
name: ${{ steps.semver.outputs.version }}
generate_release_notes: true
build-artifacts:
# Build distributions only when semantic-version reports a new release.
name: Build Package Artifacts
runs-on: ubuntu-latest
needs: version-and-release
if: github.event.pull_request.merged == true && needs.version-and-release.outputs.changed == 'true'
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
- name: Install Poetry
run: pipx install poetry
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: poetry
cache-dependency-path: poetry.lock
- name: Build distributions
run: poetry build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: python-dist
path: dist/