Skip to content

ci: two-stage trusted-publishing release workflow - #61

Merged
thad0ctor merged 3 commits into
mainfrom
ci/release-workflow
Jul 10, 2026
Merged

ci: two-stage trusted-publishing release workflow#61
thad0ctor merged 3 commits into
mainfrom
ci/release-workflow

Conversation

@thad0ctor

@thad0ctor thad0ctor commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Adds .github/workflows/release.yml: a tag-driven release pipeline using PyPI trusted publishing (OIDC, no stored tokens).

Flow

  • git push fork v0.2.0.dev1 → build sdist+wheel → TestPyPI (gate 1) → stops (prerelease).
  • git push fork v0.2.0 → build → TestPyPI (gate 1) → PyPI (gate 2).

The same artifacts built once are promoted through both indexes, so what lands on PyPI is byte-identical to what was smoke-tested on TestPyPI.

Safeguards

  • Two manual approval gates via GitHub Environments testpypi / pypi (required reviewer).
  • Build-time guard fails if the git tag doesn't match the version in pyproject.toml.
  • Prerelease markers (.devN/aN/bN/rcN) route to TestPyPI only.

Notes

  • Trusted publishers are registered on TestPyPI and PyPI for owner=thad0ctor repo=Gefen-X workflow=release.yml env=testpypi|pypi. Do not rename release.yml or the OIDC handshake breaks.
  • Validated locally: clean build, twine check, kernel sources ship in wheel+sdist, and the installed wheel JIT-compiles all CUDA kernels + runs optimizer steps on a 3090.

Summary by CodeRabbit

  • New Features
    • Added an automated GitHub Actions release pipeline triggered by version tags.
    • Builds and validates source and wheel artifacts before publishing.
    • Publishes to TestPyPI for verification, then to PyPI for approved stable releases.
    • Detects prerelease versions to prevent prereleases from being published to PyPI.
    • Ensures the tag version matches the packaged wheel version for consistency.
    • Added weekly Dependabot updates for GitHub Actions.

Tag-driven pipeline (v* tags): build sdist+wheel once, then promote the
same artifacts through TestPyPI and PyPI, each behind its own GitHub
Environment approval gate. Auth is OIDC trusted publishing (no stored
tokens). Prerelease tags (.devN/aN/bN/rcN) stop at TestPyPI; clean
vX.Y.Z tags also publish to PyPI. A guard fails the build if the tag
does not match the version in pyproject.toml.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae048b44-a11c-46ad-ab37-64aa701b13d9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds a tag-triggered GitHub Actions workflow that builds and validates Python distributions, uploads them as an artifact, and publishes them to TestPyPI and PyPI through gated OIDC-based jobs. It also configures weekly grouped Dependabot updates for GitHub Actions.

Changes

Package release pipeline

Layer / File(s) Summary
Release build and validation
.github/workflows/release.yml
Tags matching v* trigger a Python 3.12 build, distribution validation, wheel/tag version validation, prerelease detection, and dist/ artifact upload.
TestPyPI publishing
.github/workflows/release.yml
The gated TestPyPI job downloads the shared artifact and publishes with skip-existing: true.
PyPI publishing
.github/workflows/release.yml
The gated PyPI job publishes only non-prerelease versions and fails when the version already exists.

GitHub Actions update automation

Layer / File(s) Summary
Grouped Actions updates
.github/dependabot.yml
Dependabot checks GitHub Actions dependencies weekly from the repository root and groups matching updates into one pull request.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitTag
  participant BuildJob
  participant ArtifactStore
  participant TestPyPI
  participant PyPI
  GitTag->>BuildJob: trigger on v* tag
  BuildJob->>BuildJob: build and validate distributions
  BuildJob->>ArtifactStore: upload dist artifact
  ArtifactStore->>TestPyPI: provide artifact after approval
  ArtifactStore->>PyPI: provide artifact for non-prerelease after approval
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: a two-stage trusted-publishing release workflow for releases.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-workflow

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 44-47: Disable pip caching in the release workflow by removing the
cache: pip setting from the actions/setup-python@v5 step, leaving Python setup
otherwise unchanged so tag-triggered builds use a clean environment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 73afcca7-e891-4bca-a078-cd52d84bd9f4

📥 Commits

Reviewing files that changed from the base of the PR and between 6e40f84 and 0a76720.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Comment thread .github/workflows/release.yml Outdated
setup-python's pip cache is branch-scoped and writable by less-trusted
runs (PRs, ci.yml on other branches). A tag-triggered publish job could
restore a poisoned cache and taint the wheel uploaded to PyPI, so the
privileged release workflow now builds without a shared cache. Addresses
CodeRabbit / zizmor cache-poisoning finding on PR #61.
Pin every action in release.yml to a full-length commit SHA (with a
trailing # vX.Y.Z comment) so a moved tag can't swap out the code a
privileged, id-token-write publish job runs:
  actions/checkout           v4.3.1
  actions/setup-python       v5.6.0
  actions/upload-artifact    v4.6.2
  actions/download-artifact  v4.3.0
  pypa/gh-action-pypi-publish v1.14.0

Add .github/dependabot.yml (github-actions, weekly, grouped) so the pins
still receive update PRs instead of silently rotting.
@thad0ctor

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thad0ctor
thad0ctor merged commit f578e0e into main Jul 10, 2026
15 checks passed
@thad0ctor
thad0ctor deleted the ci/release-workflow branch July 10, 2026 19:45
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.

1 participant