Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8971121167 | |||
| 7cd22a77ce |
@@ -0,0 +1,20 @@
|
||||
name: Setup uv + sync deps
|
||||
description: >-
|
||||
Install uv, point its cache at the runner-local mount, and sync the
|
||||
project with the cpu + dev extras. Every CI job does this identically;
|
||||
the caller must still mount /srv/act-runner-cache/uv:/uv-cache on its
|
||||
own container (a composite action can't set that) and check out the
|
||||
repo before this runs.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- shell: bash
|
||||
run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- shell: bash
|
||||
run: uv sync --extra cpu --extra dev
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build one complete release commit: version bump (or sync to a given
|
||||
# version, or no bump at all), changelog entry, and refreshed README
|
||||
# badges — all in a single commit, tagged at the end. Used by both the
|
||||
# merge-to-master release job and the hand-pushed-tag sync job, so "the
|
||||
# tag == a complete release commit" holds either way a release gets made.
|
||||
#
|
||||
# Usage: release-commit.sh [--no-bump|VERSION]
|
||||
# (no argument) bump the current patch version (normal merge path).
|
||||
# --no-bump don't touch the version — the branch already bumped it
|
||||
# (e.g. a manual minor/major bump); just build the
|
||||
# changelog/badge commit for whatever version is current.
|
||||
# VERSION sync the project to this exact version (tag-sync path).
|
||||
#
|
||||
# Preconditions: repo is checked out with full history (fetch-depth: 0),
|
||||
# `uv` is available and synced, and git user.name/user.email are configured.
|
||||
# Idempotent: if the resulting tag already exists, this is a no-op.
|
||||
set -euo pipefail
|
||||
|
||||
VERSION_ARG="${1:-}"
|
||||
|
||||
if [ "$VERSION_ARG" = "--no-bump" ]; then
|
||||
echo "Version already bumped by this branch; using current version as-is"
|
||||
elif [ -n "$VERSION_ARG" ]; then
|
||||
echo "Syncing project version to $VERSION_ARG"
|
||||
uv version "$VERSION_ARG" --no-sync
|
||||
uv lock
|
||||
else
|
||||
CURRENT_VERSION=$(uv version --short)
|
||||
echo "Bumping patch version from $CURRENT_VERSION"
|
||||
uv run bump-my-version bump patch --current-version "$CURRENT_VERSION" --no-commit --no-tag
|
||||
# bump-my-version's pre_commit_hooks (uv lock + git add uv.lock) only run
|
||||
# on its own commit path, which we skipped with --no-commit — so do it here.
|
||||
uv lock
|
||||
fi
|
||||
|
||||
VERSION=$(uv version --short)
|
||||
TAG="v$VERSION"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists; nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
uv run git-cliff --tag "$TAG" --unreleased --prepend CHANGELOG.md
|
||||
|
||||
TEST_COUNT=$(uv run pytest --collect-only -q 2>/dev/null | grep -oE '^[0-9]+ tests? collected' | grep -oE '^[0-9]+')
|
||||
sed -i -E "s|badge/version-[^-]+-informational|badge/version-${VERSION}-informational|" README.md
|
||||
sed -i -E "s|badge/tests-[0-9]+%20passing-brightgreen|badge/tests-${TEST_COUNT}%20passing-brightgreen|" README.md
|
||||
|
||||
# .bumpversion.toml stores its own current_version, which bump-my-version
|
||||
# rewrites even with --no-commit — must be staged or the next run sees a
|
||||
# dirty tree and bump-my-version refuses (allow_dirty = false).
|
||||
git add pyproject.toml .bumpversion.toml uv.lock CHANGELOG.md README.md
|
||||
if git diff --cached --quiet; then
|
||||
echo "Nothing changed; skipping release commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git commit -m "chore: release $TAG"
|
||||
git tag -a "$TAG" -m "$TAG"
|
||||
|
||||
echo "Created release commit and tag $TAG"
|
||||
+41
-126
@@ -12,6 +12,7 @@ env:
|
||||
jobs:
|
||||
ruff-check:
|
||||
name: Lint (ruff check)
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
@@ -19,17 +20,12 @@ jobs:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- uses: ./.gitea/actions/setup
|
||||
- run: uv run ruff check .
|
||||
|
||||
ruff-format:
|
||||
name: Format (ruff format)
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
@@ -37,17 +33,12 @@ jobs:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- uses: ./.gitea/actions/setup
|
||||
- run: uv run ruff format --check .
|
||||
|
||||
type-check:
|
||||
name: Type check (ty)
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
@@ -55,18 +46,13 @@ jobs:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- uses: ./.gitea/actions/setup
|
||||
- run: uv run ty check .
|
||||
|
||||
test:
|
||||
name: Tests
|
||||
needs: [ruff-check, type-check]
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
needs: [ruff-check, ruff-format, type-check]
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
@@ -74,21 +60,15 @@ jobs:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- uses: ./.gitea/actions/setup
|
||||
- run: uv run pytest --cov --cov-report=term-missing --cov-report=xml
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: coverage.xml
|
||||
|
||||
bump-version:
|
||||
name: Bump version, tag, and update changelog on merge to master
|
||||
release:
|
||||
name: Release (bump, changelog, badges, tag) on merge to master
|
||||
needs: [ruff-check, ruff-format, type-check, test]
|
||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -98,7 +78,7 @@ jobs:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
# CI_TOKEN needs write:repository scope (not just read) — this job
|
||||
# pushes commits and tags to master, unlike ruff-check/ruff-format/
|
||||
# pushes a commit and a tag to master, unlike ruff-check/ruff-format/
|
||||
# type-check/test above, which only need to check out the repo.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -114,22 +94,14 @@ jobs:
|
||||
else
|
||||
echo "is_merge=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- uses: ./.gitea/actions/setup
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
- name: Configure git identity
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
run: |
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "actions@git.larsbogner.de"
|
||||
- name: Bump patch version if this merge didn't already bump it
|
||||
- name: Build the release commit
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
run: |
|
||||
OLD_VERSION=$(git show "${{ github.event.before }}:pyproject.toml" 2>/dev/null | grep -m1 '^version = ' | sed -E 's/version = "(.*)"/\1/')
|
||||
@@ -140,116 +112,64 @@ jobs:
|
||||
fi
|
||||
if [ "$OLD_VERSION" = "$CURRENT_VERSION" ]; then
|
||||
echo "Version unchanged by this merge ($CURRENT_VERSION); bumping patch"
|
||||
uv run bump-my-version bump patch --current-version "$CURRENT_VERSION"
|
||||
.gitea/scripts/release-commit.sh
|
||||
else
|
||||
echo "Branch already bumped the version ($OLD_VERSION -> $CURRENT_VERSION); skipping auto-bump"
|
||||
echo "Branch already bumped the version ($OLD_VERSION -> $CURRENT_VERSION); building release commit without bumping"
|
||||
.gitea/scripts/release-commit.sh --no-bump
|
||||
fi
|
||||
- name: Update changelog for the current version if not already tagged
|
||||
- name: Push the release commit and its tag together
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
run: |
|
||||
VERSION=$(uv version --short)
|
||||
TAG="v$VERSION"
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists; skipping changelog update"
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1 && [ "$(git rev-parse "$TAG")" = "$(git rev-parse HEAD)" ]; then
|
||||
git push --atomic origin HEAD:master "refs/tags/$TAG"
|
||||
else
|
||||
uv run git-cliff --tag "$TAG" --unreleased --prepend CHANGELOG.md
|
||||
git add CHANGELOG.md
|
||||
if ! git diff --cached --quiet -- CHANGELOG.md; then
|
||||
git commit -m "chore: update changelog for $TAG"
|
||||
else
|
||||
git restore --staged CHANGELOG.md
|
||||
fi
|
||||
fi
|
||||
- name: Push commits and tag the current version
|
||||
if: steps.merge_check.outputs.is_merge == 'true'
|
||||
run: |
|
||||
git push origin HEAD:master
|
||||
VERSION=$(uv version --short)
|
||||
TAG="v$VERSION"
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
echo "Tag $TAG already exists"
|
||||
else
|
||||
git tag -a "$TAG" -m "$TAG"
|
||||
git push origin "refs/tags/$TAG"
|
||||
echo "No new release commit/tag to push (already released, or nothing changed)"
|
||||
git push origin HEAD:master
|
||||
fi
|
||||
|
||||
update-badges:
|
||||
name: Update README badges (version, test count)
|
||||
needs: [ruff-check, ruff-format, type-check, test, bump-version]
|
||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
sync-version-on-tag:
|
||||
name: Sync project version with tag (hand-pushed tags only)
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
volumes:
|
||||
- /srv/act-runner-cache/uv:/uv-cache
|
||||
steps:
|
||||
# ref: master (not the triggering SHA) so this picks up whatever
|
||||
# bump-version just pushed, rather than badging the pre-bump commit.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.CI_TOKEN }}
|
||||
ref: master
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- run: uv sync --extra cpu --extra dev
|
||||
- name: Compute version and test count
|
||||
id: stats
|
||||
fetch-depth: 0
|
||||
- name: Require the tagged commit to already be on master
|
||||
run: |
|
||||
VERSION=$(uv version --short)
|
||||
TEST_COUNT=$(uv run pytest --collect-only -q 2>/dev/null | grep -oE '^[0-9]+ tests? collected' | grep -oE '^[0-9]+')
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "test_count=$TEST_COUNT" >> "$GITHUB_OUTPUT"
|
||||
- name: Rewrite badge lines in README.md
|
||||
run: |
|
||||
sed -i -E "s|badge/version-[^-]+-informational|badge/version-${{ steps.stats.outputs.version }}-informational|" README.md
|
||||
sed -i -E "s|badge/tests-[0-9]+%20passing-brightgreen|badge/tests-${{ steps.stats.outputs.test_count }}%20passing-brightgreen|" README.md
|
||||
- name: Commit and push if the badges actually changed
|
||||
run: |
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "actions@git.larsbogner.de"
|
||||
git add README.md
|
||||
if ! git diff --cached --quiet -- README.md; then
|
||||
git commit -m "chore: update README badges (version ${{ steps.stats.outputs.version }}, ${{ steps.stats.outputs.test_count }} tests)"
|
||||
git push origin HEAD:master
|
||||
else
|
||||
echo "Badges already up to date"
|
||||
git fetch origin master
|
||||
if ! git merge-base --is-ancestor "${{ github.sha }}" origin/master; then
|
||||
echo "::error::Tag ${GITHUB_REF_NAME} points at a commit not on master; refusing to publish an unreviewed tree. Push the commit to master first, or delete and re-push the tag once it is."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sync-version-on-tag:
|
||||
name: Sync project version with tag
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.CI_TOKEN }}
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
- name: Check tag against project version, update if they differ
|
||||
- uses: ./.gitea/actions/setup
|
||||
- name: Check tag against project version, build a release commit if they differ
|
||||
run: |
|
||||
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
||||
CURRENT_VERSION=$(uv version --short)
|
||||
if [ "$TAG_VERSION" != "$CURRENT_VERSION" ]; then
|
||||
echo "Tag version ($TAG_VERSION) != project version ($CURRENT_VERSION); updating pyproject.toml"
|
||||
uv version "$TAG_VERSION" --no-sync
|
||||
if [ "$TAG_VERSION" = "$CURRENT_VERSION" ]; then
|
||||
echo "Tag version matches project version ($CURRENT_VERSION)"
|
||||
else
|
||||
echo "Tag version ($TAG_VERSION) != project version ($CURRENT_VERSION); building a release commit"
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "actions@git.larsbogner.de"
|
||||
git add pyproject.toml uv.lock
|
||||
git commit -m "chore: sync project version to tag ${GITHUB_REF_NAME}"
|
||||
.gitea/scripts/release-commit.sh "$TAG_VERSION"
|
||||
git push origin HEAD:master
|
||||
git push origin ":refs/tags/${GITHUB_REF_NAME}"
|
||||
git tag -f "${GITHUB_REF_NAME}" HEAD
|
||||
git push origin "refs/tags/${GITHUB_REF_NAME}"
|
||||
else
|
||||
echo "Tag version matches project version ($CURRENT_VERSION)"
|
||||
fi
|
||||
|
||||
publish-package:
|
||||
name: Publish package to Gitea package registry
|
||||
needs: [ruff-check, ruff-format, type-check, test, sync-version-on-tag]
|
||||
needs: [sync-version-on-tag]
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
@@ -262,12 +182,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref_name }}
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: false
|
||||
- run: |
|
||||
echo "UV_CACHE_DIR=/uv-cache" >> "$GITHUB_ENV"
|
||||
echo "UV_LINK_MODE=copy" >> "$GITHUB_ENV"
|
||||
- uses: ./.gitea/actions/setup
|
||||
- run: uv build
|
||||
# CI_TOKEN needs write:package scope (in addition to write:repository,
|
||||
# used elsewhere) for this upload to authenticate.
|
||||
|
||||
@@ -10,8 +10,8 @@ calorimeter showers.
|
||||
|
||||
[](pyproject.toml)
|
||||
[](pyproject.toml)
|
||||
[](CHANGELOG.md)
|
||||
[](tests/)
|
||||
[](CHANGELOG.md)
|
||||
[](tests/)
|
||||
[](https://git.larsbogner.de/lars/giant/actions)
|
||||
[](#license)
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ commit_preprocessors = [
|
||||
protect_breaking_commits = false
|
||||
commit_parsers = [
|
||||
{ message = "^Merge ", skip = true },
|
||||
{ message = "^chore: (bump version|update changelog|sync project version)", skip = true },
|
||||
{ message = "^chore: (release|bump version|update changelog|sync project version)", skip = true },
|
||||
{ message = "^Add", group = "<!-- 0 -->Added" },
|
||||
{ message = "^(Fix|Clamp|Clip)", group = "<!-- 1 -->Fixed" },
|
||||
{ message = "^(Remove|Drop|Deprecate)", group = "<!-- 2 -->Removed" },
|
||||
|
||||
Reference in New Issue
Block a user