From 0ebe33869ba8ff99218c3d1d82febbd1db5fbdfa Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Wed, 10 Jun 2026 18:48:37 +0000 Subject: [PATCH] ci(release): add daily automated version bump and changelog workflow Add version-bump.yml: daily git-cliff semver bump on dev (version files, uv.lock, prepended CHANGELOG entry, tag). Switch release.yml gate to compare against latest GitHub release instead of latest tag, since every bump is now tagged. Allow .github/ through the hidden-dir gitignore rule. --- .github/workflows/release.yml | 8 ++-- .github/workflows/version-bump.yml | 72 ++++++++++++++++++++++++++++++ .gitignore | 1 + 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/version-bump.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bfbc3d1..5aaf241 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,15 +23,17 @@ jobs: - name: Check for major/minor version bump id: version_check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | NEW_VERSION=$(grep -m1 '^version' pyproject.toml | sed 's/version = "\(.*\)"/\1/') echo "Detected version in pyproject.toml: $NEW_VERSION" - LATEST_TAG=$(git tag --list | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1) - echo "Latest git tag: $LATEST_TAG" + LATEST_TAG=$(gh release list --limit 1 --json tagName -q '.[0].tagName' || true) + echo "Latest GitHub release: $LATEST_TAG" if [ -z "$LATEST_TAG" ]; then - echo "No previous tag found, treating as new release" + echo "No previous release found, treating as new release" echo "should_release=true" >> "$GITHUB_OUTPUT" echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT" exit 0 diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml new file mode 100644 index 0000000..6e35cb1 --- /dev/null +++ b/.github/workflows/version-bump.yml @@ -0,0 +1,72 @@ +name: Version Bump + +on: + schedule: + - cron: "0 8 * * *" # daily 08:00 UTC + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: version-bump + cancel-in-progress: false + +jobs: + bump: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + ref: dev + fetch-depth: 0 + + - name: Install git-cliff + uses: taiki-e/install-action@v2 + with: + tool: git-cliff + + - name: Compute next version + id: bump + run: | + CURRENT=$(grep -m1 '^version' pyproject.toml | sed 's/version = "\(.*\)"/\1/') + NEXT=$(git cliff --bumped-version) + echo "Current version: $CURRENT, bumped version: $NEXT" + + if [ "$NEXT" = "$CURRENT" ]; then + echo "No releasable commits since $CURRENT, skipping" + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + echo "version=$NEXT" >> "$GITHUB_OUTPUT" + fi + + - name: Update version files + if: steps.bump.outputs.skip == 'false' + run: | + V=${{ steps.bump.outputs.version }} + sed -i "s/^version = \".*\"/version = \"$V\"/" pyproject.toml + sed -i "s/^__version__ = \".*\"/__version__ = \"$V\"/" unshackle/core/__init__.py + + - name: Install uv + if: steps.bump.outputs.skip == 'false' + uses: astral-sh/setup-uv@v4 + + - name: Update uv.lock + if: steps.bump.outputs.skip == 'false' + run: uv lock + + - name: Prepend changelog entry + if: steps.bump.outputs.skip == 'false' + run: git cliff --unreleased --tag ${{ steps.bump.outputs.version }} --prepend CHANGELOG.md + + - name: Commit, tag, and push + if: steps.bump.outputs.skip == 'false' + run: | + V=${{ steps.bump.outputs.version }} + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add pyproject.toml unshackle/core/__init__.py uv.lock CHANGELOG.md + git commit -m "chore(release): bump version to $V" + git tag "$V" + git push origin dev "$V" diff --git a/.gitignore b/.gitignore index 3aa99fc..466c00d 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ temp/ logs/ services/ /.[^/]*/ +!/.github/ # Byte-compiled / optimized / DLL files __pycache__/