Skip to content

ci: tag-driven release pipeline with TestPyPI RC track#11

Merged
chris-colinsky merged 2 commits into
mainfrom
chore/release-pipeline
May 6, 2026
Merged

ci: tag-driven release pipeline with TestPyPI RC track#11
chris-colinsky merged 2 commits into
mainfrom
chore/release-pipeline

Conversation

@chris-colinsky
Copy link
Copy Markdown
Member

@chris-colinsky chris-colinsky commented May 6, 2026

Summary

Adds a Release workflow triggered by tag push. Tag pattern decides the publish target:

Tag pattern Action
v0.5.0-rc1, v0.5.0-rc2, ... TestPyPI only (staging / dry-run)
v0.5.0 PyPI + GitHub Release

Both publish paths use Trusted Publishing (OIDC) via pypa/gh-action-pypi-publish — no long-lived API tokens stored as secrets.

Also extends ci.yml with a uv build step at the end of the test job. Verifies the package builds on every PR/push so packaging bugs surface before they reach a release tag.

Release flow once this lands

# 1. Bump version + spec pins on main
vim pyproject.toml                    # version = "0.5.0rc1"
vim src/openarmature/__init__.py      # __spec_version__ = "0.8.1"
vim tests/test_smoke.py               # match
git commit -am "release: prep 0.5.0-rc1" && git push origin main

# 2. Tag the RC
git tag v0.5.0-rc1 && git push origin v0.5.0-rc1
# → workflow uploads to TestPyPI

# 3. Verify in a fresh venv
pip install --index-url https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple/ openarmature==0.5.0rc1

# 4. Once verified, drop the rc suffix and tag the real release
vim pyproject.toml                    # version = "0.5.0"
git commit -am "release: 0.5.0" && git push origin main
git tag v0.5.0 && git push origin v0.5.0
# → publish-pypi pauses for manual approval (if env reviewer protection set), then publishes
# → github-release creates a GitHub Release with auto-generated notes

Each RC iteration burns a fresh number — PyPI/TestPyPI refuse re-uploads of the same version. Iterate rc1 → rc2 → rc3 → 0.5.0 as needed.

Test plan

  • uv build runs clean locally (produces openarmature-0.4.0.tar.gz + wheel).
  • Both YAML files parse without errors.
  • Existing ci.yml test job still passes; new uv build step appended at the end.
  • First release flow exercised end-to-end at Phase 6 release prep time (intentionally not tagging yet — release strategy says wait until all phases land).

Notes

  • Tag glob is v[0-9]*.[0-9]*.[0-9]* — matches both v0.5.0 and v0.5.0-rc1 (the trailing -rc1 is part of the final *). Job-level if: contains(github.ref_name, '-rc') splits the two paths.
  • No Homebrew tap update job (not relevant for this project).
  • No release notes for RC tags — only real releases create a GitHub Release. RCs are TestPyPI-only.

Add a Release workflow triggered by tag push. Tag pattern decides the
publish target:

  v0.5.0-rc1, v0.5.0-rc2, ...   → TestPyPI (staging / dry-run)
  v0.5.0                        → PyPI + GitHub Release

Both publish paths use Trusted Publishing (OIDC) via
pypa/gh-action-pypi-publish — no long-lived API tokens. The pypi
environment is the recommended place to add a "required reviewers"
protection rule so real-PyPI uploads pause for manual approval.

Also extend ci.yml with a `uv build` step at the end of the test job.
Verifies the package builds on every PR/push so packaging bugs surface
before they hit a release tag, not after.

First publish from either workflow needs a one-time pending-publisher
setup on TestPyPI and PyPI plus the testpypi/pypi GitHub Environments
to exist; documented in the PR description.
Copilot AI review requested due to automatic review settings May 6, 2026 00:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a tag-driven release workflow that builds, tests, and publishes artifacts via PyPI Trusted Publishing (OIDC), with RC tags going to TestPyPI and final tags going to PyPI plus a GitHub Release. It also extends CI to always run a package build so packaging issues are caught before tagging a release.

Changes:

  • Introduces .github/workflows/release.yml to run tests/build on tag push and publish to TestPyPI for -rc tags or to PyPI + GitHub Release for non--rc tags.
  • Uses pypa/gh-action-pypi-publish with OIDC (no API token secrets) for both TestPyPI and PyPI publishing.
  • Appends uv build to the main CI test job to validate wheel/sdist packaging on every PR/push.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/release.yml New tag-triggered release pipeline with RC → TestPyPI and final → PyPI + GitHub Release.
.github/workflows/ci.yml Adds uv build to CI to detect packaging problems earlier.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Two release-safety fixes:

1. publish-pypi and github-release now gate on `!contains(ref_name, '-')`
   instead of `!contains(ref_name, '-rc')`. The trigger pattern matches
   any v[digits].[digits].[digits]* tag, so a `v0.5.0-beta1` tag would
   previously skip the -rc check and land on real PyPI. Tightening to
   "no `-` at all" makes any non-rc pre-release tag a no-op (failsafe).

2. Add a "Verify pyproject.toml version matches tag" step at the top of
   the test job. Reads pyproject's version, compares to the pushed tag
   (with leading `v` stripped), and fails fast if they don't match.
   Both sides go through `packaging.version.Version` so PEP 440
   equivalences like "0.5.0-rc1" ≡ "0.5.0rc1" are accepted. Catches the
   "tagged but forgot to bump pyproject" mistake before any build runs.
@chris-colinsky chris-colinsky merged commit fedcce6 into main May 6, 2026
5 checks passed
@chris-colinsky chris-colinsky deleted the chore/release-pipeline branch May 6, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants