Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
669c76d
馃懛 ci(release): rehearse pre-commit-uv releases
gaborbernat Oct 20, 2026
98cbc2c
馃悰 fix(release): hide CalVer bump
gaborbernat Oct 20, 2026
234e546
馃敡 build(deps): lock all project groups
gaborbernat Oct 20, 2026
df8683f
馃懛 ci: remove temporary release jobs
gaborbernat Oct 20, 2026
e74b6da
馃敡 chore: ignore uv lock files
gaborbernat Oct 20, 2026
ebfe543
馃悰 fix(readme): link PyPI files
gaborbernat Oct 20, 2026
5dd941a
馃悰 fix(meta): correct package metadata
gaborbernat Oct 20, 2026
ff765e6
馃摑 docs: recast release history
gaborbernat Oct 21, 2026
15898a7
馃懛 ci: refresh shared release actions
gaborbernat Oct 21, 2026
840aa12
馃懛 ci: scope bot label token to job
gaborbernat Oct 21, 2026
cba64b6
馃懛 ci: isolate release App key from tools
gaborbernat Oct 21, 2026
5eef476
馃懛 ci: wait seven days for Action updates
gaborbernat Oct 21, 2026
020049f
馃懛 ci: isolate release write jobs
gaborbernat Oct 21, 2026
7f5d874
馃摑 docs: explain news and release steps
gaborbernat Oct 21, 2026
aa01002
馃懛 ci: align news tool and release order
gaborbernat Oct 21, 2026
e1d9128
馃敡 build(deps): update mdformat hook plugin
gaborbernat Oct 21, 2026
1623e8c
馃摑 docs(changelog): split Python support notes
gaborbernat Oct 21, 2026
0c6240a
馃悰 fix(sdist): include docs and tox config
gaborbernat Oct 21, 2026
3c6e0c6
馃敡 build(lock): apply dependency age cutoff
gaborbernat Oct 21, 2026
25bb2f5
馃悰 fix(tox): make formatting task runnable
gaborbernat Oct 21, 2026
bc38803
馃悰 fix(release): set repository for GH CLI
gaborbernat Oct 21, 2026
c529a9c
馃敡 build: enforce seven-day lock cutoff
gaborbernat Oct 21, 2026
a230266
馃懛 ci(release): resume matching GitHub releases
gaborbernat Oct 21, 2026
9bd3e07
馃懛 ci(release): verify partial uploads
gaborbernat Oct 21, 2026
b34252a
馃懛 ci(release): stage GitHub draft first
gaborbernat Oct 21, 2026
75edb83
ci: require hook update cooldown
gaborbernat Oct 21, 2026
21b1618
馃拕 style(ci): format release shell blocks
gaborbernat Oct 21, 2026
40336d5
馃懛 ci: use named shared Action steps
gaborbernat Oct 21, 2026
4196290
馃敡 chore(release): use live workflow
gaborbernat Oct 22, 2026
8dc9294
馃懛 ci(release): use published tooling
gaborbernat Oct 22, 2026
5acf3b7
馃懛 ci: adopt shared release controls
gaborbernat Oct 22, 2026
5812dea
馃悰 fix(release): lock caller build backends
gaborbernat Oct 22, 2026
665d0f0
馃悰 fix(release): pin corrected shared actions
gaborbernat Oct 22, 2026
b142f30
馃悰 fix(release): pin portable shared actions
gaborbernat Oct 22, 2026
29c4296
馃懛 ci: narrow release tool installs
gaborbernat Oct 22, 2026
356a63d
馃懛 ci: adopt shared release pipeline
gaborbernat Oct 23, 2026
c937f59
馃懛 ci: run news checks separately
gaborbernat Oct 23, 2026
f0d7c50
馃懛 ci: align release jobs with shared actions
gaborbernat Oct 23, 2026
6aaf6b5
馃懛 ci: pin released release tools
gaborbernat Oct 23, 2026
676d14e
馃懛 ci: remove duplicate release PATH setup
gaborbernat Oct 23, 2026
d65fadd
馃懛 ci: reuse previous tag for release notes
gaborbernat Oct 23, 2026
c2458de
build: adopt released workflow actions
gaborbernat Oct 23, 2026
c9123b9
馃敡 build: adopt release tooling 2.0.0
gaborbernat Oct 24, 2026
e5b9591
馃懛 ci: pin shared release and full lock
gaborbernat Oct 24, 2026
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
14 changes: 14 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,21 @@ updates:
schedule:
interval: "weekly"
day: "tuesday"
cooldown:
default-days: 7
groups:
github-actions:
patterns:
- "*"
- package-ecosystem: "pre-commit"
directory: "/"
allow:
- dependency-name: mdformat-gfm
labels:
- dependencies
- skip news
schedule:
interval: "weekly"
day: "tuesday"
cooldown:
default-days: 7
43 changes: 20 additions & 23 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ on:
branches: ["main"]
tags-ignore: ["**"]
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
types: [opened, synchronize, reopened]
schedule:
- cron: "0 8 * * *"

concurrency:
group: check-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-26.04
Expand All @@ -40,6 +37,7 @@ jobs:
- name: Install the latest version of uv
uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
with:
version: latest-known
python-version: "3.15"
enable-cache: false
cache-dependency-glob: "pyproject.toml"
Expand All @@ -54,34 +52,33 @@ jobs:
run: tox run --skip-pkg-install -e ${{ matrix.env }}
env:
PYTEST_ADDOPTS: "-vv --durations=5"

changelog:
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip news')
hook-update-cooldown:
if: github.event_name == 'pull_request'
runs-on: ubuntu-26.04
permissions:
actions: read
contents: read
pull-requests: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
- uses: tox-dev/github-workflows/check-hook-update-cooldown@55f51f9b5cc0b40f280155a95de2d4f0ecbf7be1 # v3.0.0
with:
python-version: "3.15"
enable-cache: false
- run: uvx towncrier check --compare-with "origin/${GITHUB_BASE_REF}"

release-app-client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
env:
GH_TOKEN: ${{ github.token }}
gate:
name: Required checks pass
if: always()
needs: [test, changelog]
runs-on: ubuntu-26.04
name: ${{ github.event_name == 'pull_request' && 'Required checks pass' || 'Non-PR checks pass' }}
if: ${{ !cancelled() }} # codespell:ignore cancelled
needs: [test, hook-update-cooldown]
runs-on: ubuntu-24.04
steps:
- env:
NEEDS_JSON: ${{ toJSON(needs) }}
EVENT_NAME: ${{ github.event_name }}
run: |
jq -e '
jq -e --arg event "$EVENT_NAME" '
all(
to_entries[];
.value.result == "success" or
(.key == "changelog" and .value.result == "skipped")
(.key == "hook-update-cooldown" and .value.result == "skipped" and $event != "pull_request")
)
' <<< "$NEEDS_JSON"
' <<<"$NEEDS_JSON"
29 changes: 29 additions & 0 deletions .github/workflows/news.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Changelog
on:
pull_request:
types: [opened, reopened, synchronize, labeled, unlabeled]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
jobs:
changelog:
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
with:
version: latest-known
python-version: "3.15"
enable-cache: false
- name: Install locked release tools
uses: tox-dev/github-workflows/install-locked-tools@55f51f9b5cc0b40f280155a95de2d4f0ecbf7be1 # v3.0.0
with:
groups: release-news
venv: ${{ runner.temp }}/release-tools
- uses: tox-dev/github-workflows/validate-news@55f51f9b5cc0b40f280155a95de2d4f0ecbf7be1 # v3.0.0
114 changes: 17 additions & 97 deletions .github/workflows/prepare-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,25 @@ name: Prepare release
on:
workflow_dispatch:
inputs:
version:
description: Version to release, without a v prefix
bump:
description: Version bump strategy
required: true
type: choice
options:
- auto
- major
- minor
- patch
default: auto
permissions: {}
concurrency:
group: prepare-release
cancel-in-progress: false
jobs:
assemble:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-26.04
prepare:
uses: tox-dev/github-workflows/.github/workflows/prepare-towncrier-release.yaml@55f51f9b5cc0b40f280155a95de2d4f0ecbf7be1 # v3.0.0
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
with:
python-version: "3.15"
enable-cache: false
- name: Build release patch
env:
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::expected a major.minor.patch version"
exit 1
fi
latest=$(git tag --list '[0-9]*' | sort -V | tail -n 1)
if [[ "$(printf '%s\n' "$latest" "$VERSION" | sort -V | tail -n 1)" != "$VERSION" || "$latest" == "$VERSION" ]]; then
echo "::error::$VERSION must be newer than $latest"
exit 1
fi
if ! compgen -G 'changelog.d/*.md' > /dev/null; then
echo "::error::no changelog fragments to release"
exit 1
fi
uvx towncrier build --yes --version "$VERSION"
git diff HEAD --binary > "$RUNNER_TEMP/release.patch"
test -s "$RUNNER_TEMP/release.patch"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-patch
path: ${{ runner.temp }}/release.patch
if-no-files-found: error
push:
needs: assemble
runs-on: ubuntu-26.04
environment: release-auth
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: release-patch
path: ${{ runner.temp }}/release-patch
- name: Validate release patch
env:
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
git fetch origin main
git reset --hard origin/main
git apply --check "$RUNNER_TEMP/release-patch/release.patch"
git apply --index "$RUNNER_TEMP/release-patch/release.patch"
while IFS= read -r path; do
case "$path" in
CHANGELOG.md|changelog.d/*.md) ;;
*) echo "::error::unexpected release path: $path"; exit 1 ;;
esac
done < <(git diff --cached --name-only)
grep -Fq "## $VERSION (" CHANGELOG.md
git diff --cached --check
- id: token
uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
with:
client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: ${{ github.event.repository.name }}
permission-contents: write
- name: Commit and tag the release
env:
VERSION: ${{ inputs.version }}
GH_TOKEN: ${{ steps.token.outputs.token }}
APP_SLUG: ${{ steps.token.outputs.app-slug }}
run: |
set -euo pipefail
app_user_id=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
git config user.name "${APP_SLUG}[bot]"
git config user.email "${app_user_id}+${APP_SLUG}[bot]@users.noreply.github.com"
git commit -m "chore: prepare $VERSION"
git tag "$VERSION"
gh auth setup-git --hostname github.com --force
git push --atomic origin HEAD:main "refs/tags/$VERSION"
pull-requests: read
with:
bump: ${{ inputs.bump }}
release-auth-deployment: false
secrets:
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
18 changes: 18 additions & 0 deletions .github/workflows/recheck-hook-cooldown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Recheck hook cooldown
on:
schedule:
- cron: "17 7 * * *"
workflow_dispatch:
permissions: {}
jobs:
recheck:
runs-on: ubuntu-26.04
permissions:
actions: write
contents: read
pull-requests: read
steps:
- uses: tox-dev/github-workflows/recheck-hook-update-cooldown@55f51f9b5cc0b40f280155a95de2d4f0ecbf7be1 # v3.0.0
with:
workflow: check.yaml
job-name: hook-update-cooldown
Loading
Loading