diff --git a/.github/workflows/dev-publish.yml b/.github/workflows/dev-publish.yml index d83b925..a82e65a 100644 --- a/.github/workflows/dev-publish.yml +++ b/.github/workflows/dev-publish.yml @@ -2,12 +2,16 @@ name: dev-publish on: push: - branches: [main] + branches: + - main workflow_dispatch: + inputs: + dry_run: + description: "skip the PyPI upload (validation run)" + required: false jobs: dev: - if: ${{ github.event_name != 'push' || !contains(github.event.head_commit.message, 'chore(release)') }} runs-on: ubuntu-latest permissions: contents: read @@ -20,16 +24,21 @@ jobs: enable-cache: false - name: Derive dev version id: ver + env: + HEAD_MESSAGE: ${{ github.event.head_commit.message }} run: | + if [[ "$GITHUB_EVENT_NAME" == "push" && "$GITHUB_REF" != "refs/heads/main" ]]; then + echo "SKIP: dev releases only publish from main" >&2 + echo "version=SKIP" >> "$GITHUB_OUTPUT" + exit 0 + fi VER=$(python scripts/dev_version.py | tail -n1) echo "version=$VER" >> "$GITHUB_OUTPUT" - name: Build wheel + sdist if: ${{ !startsWith(steps.ver.outputs.version, 'SKIP') }} run: uv build - name: Publish to PyPI - if: ${{ !startsWith(steps.ver.outputs.version, 'SKIP') }} + if: ${{ !startsWith(steps.ver.outputs.version, 'SKIP') && github.event.inputs.dry_run != 'true' }} env: UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }} run: uv publish - - name: Log published version - run: echo "urag-cli pre-release: ${{ steps.ver.outputs.version }}" diff --git a/scripts/dev_version.py b/scripts/dev_version.py index a6e54d7..c208be8 100644 --- a/scripts/dev_version.py +++ b/scripts/dev_version.py @@ -4,13 +4,15 @@ Example: latest stable tag v0.2.0, 3 commits on main -> 0.2.1.dev3. Prints the version to stdout, or "SKIP" (details on stderr) when there is -nothing to publish (no stable tags yet, or HEAD is a tagged commit). +nothing to publish (no stable tags yet, HEAD is a tagged commit, or the +HEAD commit is a release-prep commit). Side effects: rewrites the `version` line in pyproject.toml and `__version__` in src/urag/__init__.py so the built artifacts carry the derived version. Intended for CI runners only. """ +import os import re import subprocess import sys @@ -38,6 +40,11 @@ def skip(reason: str) -> None: print("SKIP") +head_message = os.environ.get("HEAD_MESSAGE") or git("log", "-1", "--pretty=%s") +if "chore(release)" in head_message: + skip("release-prep commit; stable tag flow publishes it") + raise SystemExit(0) + tags = git("tag", "--list", "v[0-9]*").splitlines() stable = [t[1:] for t in tags if STABLE_TAG.match(t)] if not stable: