Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 12 additions & 32 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,63 +1,43 @@
name: Release

# Publish only. Triggered by a tag (hand-pushed tags publish directly) or by a
# workflow_dispatch from versioning.yml (the automatic path, since a
# GITHUB_TOKEN-pushed tag cannot trigger push:tags). Stays named release.yml so
# the PyPI trusted-publisher (OIDC) binding is unchanged.
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: 'Tag to publish (e.g. v0.1.2)'
required: true

permissions:
contents: write
id-token: write

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
release:
name: Bump, build, publish
name: Build and publish
runs-on: ubuntu-latest
if: "!startsWith(github.event.head_commit.message, 'bump:')"
steps:
- uses: actions/checkout@v6
with:
ref: "${{ github.event.inputs.tag || github.ref }}"
fetch-depth: 0

- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- uses: astral-sh/setup-uv@v7
with:
python-version: "3.12"

- name: Bump version
id: bump
run: |
uvx --from commitizen cz bump --yes || EXIT=$?
if [ "${EXIT:-0}" -eq 21 ] || [ "${EXIT:-0}" -eq 6 ]; then
echo "No bumpable commits since last tag — skipping."
echo "skipped=true" >> "$GITHUB_OUTPUT"
exit 0
fi
[ "${EXIT:-0}" -eq 0 ] || exit $EXIT
VERSION=$(cat VERSION)
git push origin HEAD:main
git push origin "v${VERSION}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"

- name: Build
if: steps.bump.outputs.skipped != 'true'
run: uv build

- name: Create GitHub release
if: steps.bump.outputs.skipped != 'true'
uses: softprops/action-gh-release@v3
with:
tag_name: "v${{ steps.bump.outputs.version }}"
tag_name: "${{ github.event.inputs.tag || github.ref_name }}"
files: dist/*
generate_release_notes: false

- name: Publish to PyPI
if: steps.bump.outputs.skipped != 'true'
run: uv publish --trusted-publishing automatic
46 changes: 46 additions & 0 deletions .github/workflows/versioning.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Versioning

# Bump + tag only. Publishing is decoupled into release.yml (so OIDC stays bound
# to the release.yml filename, and a hand-pushed tag publishes too).
on:
push:
branches: [main]

permissions:
contents: write
actions: write # to dispatch release.yml

jobs:
version:
name: Bump and tag
runs-on: ubuntu-latest
# Skip the bump the bot itself just pushed (avoids a loop).
if: "!startsWith(github.event.head_commit.message, 'bump:')"
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Configure git identity
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- uses: astral-sh/setup-uv@v7

- name: Bump, tag, trigger release
env:
GH_TOKEN: ${{ github.token }}
run: |
uvx --from commitizen cz bump --yes || EXIT=$?
if [ "${EXIT:-0}" -eq 21 ]; then
echo "No bumpable commits since last tag — nothing to release."
exit 0
fi
[ "${EXIT:-0}" -eq 0 ] || exit $EXIT
VERSION="v$(cat VERSION)"
git push origin HEAD:main
git push origin "$VERSION"
# A GITHUB_TOKEN-pushed tag does NOT trigger release.yml's push:tags,
# so dispatch the publish explicitly for the automatic path.
gh workflow run release.yml -f tag="$VERSION"