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
90 changes: 65 additions & 25 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ jobs:
check_name: "Test Results ${{ matrix.python-version }}"
github_retries: 10
secondary_rate_limit_wait_seconds: 60.0
# Version source of truth: pyproject.toml [project] version.
# - Patch: CI bumps patch on every push to main (and commits it).
# - Minor/major: Update version in pyproject.toml (e.g. uv version 3.22.0 or uv version --bump minor),
# merge with message "Release 3.22.0"; CI will use that version as-is and tag it.
# Version source of truth: pyproject.toml [project] version. User must update it before merging to main.
# PRs are checked so that version differs from main. On push to main, CI tags and publishes that version.
get-version:
if: github.repository == 'adobe/buildrunner'
runs-on: ubuntu-latest
Expand All @@ -69,7 +67,6 @@ jobs:
contents: write
outputs:
current-version: ${{ steps.version-number.outputs.CURRENT_VERSION }}
should-tag: ${{ steps.tag-decision.outputs.should_tag }}
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -80,31 +77,74 @@ jobs:
python-version: 3.9
- name: Install dependencies
run: uv sync --locked
- name: Bump version (patch only when not the bot’s bump commit)
id: bump
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, 'Bump version to')
run: uv version --bump patch
- name: Get current version
id: version-number
run: echo "CURRENT_VERSION=$(uv version --short)" >> $GITHUB_OUTPUT
- name: Print current version
run: echo CURRENT_VERSION ${{ steps.version-number.outputs.CURRENT_VERSION }}
- name: Set tag/publish decision
id: tag-decision
run: |
if [ "${{ steps.bump.outcome }}" = "success" ]; then echo "should_tag=true" >> $GITHUB_OUTPUT; exit 0; fi
echo "should_tag=false" >> $GITHUB_OUTPUT
- name: Print tag decision
run: echo "should_tag=${{ steps.tag-decision.outputs.should_tag }}"
- name: Commit and push version bump
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, 'Bump version to')
# PR check: version must differ from main and be strictly greater (semver: major.minor.patch).
# MAJOR may not decrease; MINOR may not decrease unless MAJOR increased; PATCH may not decrease unless MAJOR or MINOR changed.
version-changed:
if: github.repository == 'adobe/buildrunner' && github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: 3.9
- name: Check version increased from main
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml uv.lock
git diff --staged --quiet || (git commit -m "Bump version to ${{ steps.version-number.outputs.CURRENT_VERSION }}" && git push)
PR_VERSION=$(uv version --short)
git fetch origin main
MAIN_VERSION=$(git show origin/main:pyproject.toml | sed -n 's/^version *= *"\(.*\)".*/\1/p' | tr -d ' ')
if [ -z "$MAIN_VERSION" ]; then
echo "Could not read version from main's pyproject.toml"
exit 1
fi
# Parse major.minor.patch (default missing to 0; e.g. "3" -> 3.0.0, "3.22" -> 3.22.0)
main_major=$(echo "$MAIN_VERSION" | cut -d. -f1)
main_minor=$(echo "$MAIN_VERSION" | cut -d. -f2)
main_patch=$(echo "$MAIN_VERSION" | cut -d. -f3)
[ -z "$main_minor" ] && main_minor=0
[ -z "$main_patch" ] && main_patch=0
pr_major=$(echo "$PR_VERSION" | cut -d. -f1)
pr_minor=$(echo "$PR_VERSION" | cut -d. -f2)
pr_patch=$(echo "$PR_VERSION" | cut -d. -f3)
[ -z "$pr_minor" ] && pr_minor=0
[ -z "$pr_patch" ] && pr_patch=0
# Require PR version strictly greater than main (at least one component increased, none decreased per semver rules)
fail_msg="Version must be strictly greater than main ($MAIN_VERSION). Rules: MAJOR may not decrease; MINOR may not decrease unless MAJOR increased; PATCH may not decrease unless MAJOR or MINOR changed. Bump with e.g. \`uv version --bump patch\`."
if [ "$pr_major" -lt "$main_major" ]; then
echo "::error::MAJOR decreased ($main_major → $pr_major). $fail_msg"
exit 1
fi
if [ "$pr_major" -gt "$main_major" ]; then
echo "Version OK: $MAIN_VERSION → $PR_VERSION"
exit 0
fi
if [ "$pr_minor" -lt "$main_minor" ]; then
echo "::error::MINOR decreased ($main_minor → $pr_minor) without MAJOR increase. $fail_msg"
exit 1
fi
if [ "$pr_minor" -gt "$main_minor" ]; then
echo "Version OK: $MAIN_VERSION → $PR_VERSION"
exit 0
fi
if [ "$pr_patch" -lt "$main_patch" ]; then
echo "::error::PATCH decreased ($main_patch → $pr_patch) without MAJOR or MINOR change. $fail_msg"
exit 1
fi
if [ "$pr_patch" -gt "$main_patch" ]; then
echo "Version OK: $MAIN_VERSION → $PR_VERSION"
exit 0
fi
echo "::error::Version unchanged ($MAIN_VERSION). $fail_msg"
exit 1
tag-commit:
if: github.repository == 'adobe/buildrunner' && github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.get-version.outputs.should-tag == 'true'
if: github.repository == 'adobe/buildrunner' && github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
needs: [test, get-version]
steps:
Expand All @@ -115,7 +155,7 @@ jobs:
- name: Tag commit
run: git tag ${{ needs.get-version.outputs.current-version }} && git push --tags
publish-pypi:
if: github.repository == 'adobe/buildrunner' && (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.get-version.outputs.should-tag == 'true'))
if: github.repository == 'adobe/buildrunner' && (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main'))
runs-on: ubuntu-latest
needs: [test, get-version]
steps:
Expand All @@ -142,7 +182,7 @@ jobs:
user: __token__
password: ${{ secrets.ADOBE_BOT_PYPI_TOKEN }}
publish-docker:
if: github.repository == 'adobe/buildrunner' && (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.get-version.outputs.should-tag == 'true'))
if: github.repository == 'adobe/buildrunner' && (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main'))
runs-on: ubuntu-latest
needs: [test, get-version]
steps:
Expand Down
22 changes: 13 additions & 9 deletions VERSIONING.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
# Versioning

The **source of truth** for the version is `pyproject.toml` → `[project]` → `version`.
CI uses that value and the resulting git tag as the release version.
You are responsible for updating it for every release. CI tags and publishes whatever version is on `main` when you push.

## Where to update version

- **Single place:** `pyproject.toml` — set `version = "X.Y.Z"` (e.g. `"3.21"` or `"3.21.0"`).
- **Single place:** `pyproject.toml` — set `version = "X.Y.Z"` (e.g. `"3.22.0"`). You can use `uv version 3.22.0` or `uv version --bump patch` (etc.) and commit the change.

## How versions are produced
## Releasing (patch, minor, or major)

| You want | What to do |
|----------|------------|
| **Patch** (e.g. 3.21.0 → 3.21.1) | Nothing. Push to `main`; CI bumps patch, commits it, tags that version, and publishes. |
| **Minor** (e.g. 3.21 → 3.22.0) | Update version in `pyproject.toml` (e.g. `uv version 3.22.0` or `uv version --bump minor`). Commit with message **`Release 3.22.0`** and merge to `main`. CI will use that version as-is (no bump), tag it, and publish. |
| **Major** (e.g. 3.21 → 4.0.0) | Same as minor: set `version = "4.0.0"` in `pyproject.toml`, commit **`Release 4.0.0`**, merge to `main`. |
| **Patch** (e.g. 3.22.0 → 3.22.1) | Run `uv version --bump patch` (or set `version = "3.22.1"` in `pyproject.toml`). Commit, open a PR to `main`, merge. CI will tag and publish. |
| **Minor** (e.g. 3.22 → 3.23.0) | Run `uv version 3.23.0` or `uv version --bump minor`. Commit, open a PR to `main`, merge. CI will tag and publish. |
| **Major** (e.g. 3.x → 4.0.0) | Set `version = "4.0.0"` in `pyproject.toml` (or `uv version 4.0.0`). Commit, open a PR to `main`, merge. CI will tag and publish. |

## PR check: version must increase

For every **pull request targeting `main`**, CI runs a check that the version in `pyproject.toml` is **strictly greater** than the version on `main`: at least one of major.minor.patch must increase, and none may decrease (except MINOR/PATCH may reset when MAJOR increases, or PATCH when MINOR increases). MAJOR may never decrease; MINOR may not decrease unless MAJOR increased; PATCH may not decrease unless MAJOR or MINOR changed. If the version is unchanged or violates these rules, the check fails.

## Summary

- **Track/update** major.minor.patch in **`pyproject.toml`**.
- **Patch releases:** automatic on every push to `main` (CI bumps and commits).
- **Minor/major releases:** set the version in `pyproject.toml` and use a commit message starting with **`Release X.Y.Z`** so CI does not bump again and tags that version.
- **You** update the version in **`pyproject.toml`** for every release (patch, minor, or major).
- Open a PR to `main`; CI will fail the “version changed” check until the version is updated.
- After you merge to `main`, CI tags that version and publishes to PyPI and the container registry.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "uv_build"

[project]
name = "buildrunner"
version = "3.22"
version = "3.22.1"
description = "Docker-based build tool"
readme = "README.rst"
requires-python = ">=3.9"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading