Skip to content

ci(release-package): tag and publish an immutable GitHub Release after PyPI - #1208

Merged
abrichr merged 2 commits into
mainfrom
ci/release-package-tag-and-github-release
Oct 18, 2026
Merged

abrichr merged 2 commits into
mainfrom
ci/release-package-tag-and-github-release

Conversation

@abrichr

@abrichr abrichr commented Oct 17, 2026

Copy link
Copy Markdown
Member

A package release from packages/ currently publishes only to PyPI. It leaves no tag, no GitHub Release, and nothing the Production release admission can bind to. This PR adds those steps.

Tags

  • Each package release is tagged <pypi-project>-v<version>, for example openadapt-flow-v2.2.0.
  • v* stays reserved for the launcher, so a package tag never triggers release-and-publish.yml.

Rulesets (already created on this repository; the existing v* rulesets are untouched)

  • One creation ruleset per package pattern. The only bypass is the openadapt-release App (Integration 4730708, always).
  • One immutability ruleset per pattern (deletion, non_fast_forward, update), with no bypass.
  • IDs: openadapt-flow 25323647 and 25323648; openadapt-agent 25323649 and 25323650; openadapt-types 25323655 and 25323656.

Build job now also refuses to continue when:

  • packages/<pkg>/CHANGELOG.md does not open with ## v<version> (date);
  • the tag already exists;
  • it cannot tell whether the tag exists.

preflight-github (new; runs before the PyPI upload)

  • Runs in release-identity as the openadapt-release App, with the App slug checked.
  • Runs verify_release_hosting.py for the exact package tag, so the upload can't start without immutable releases and closed tag rules.

publish-github (new; needs publish, so it runs only after PyPI accepts the files)

  • Uses the App token and re-runs the hosting check.
  • Requires the published commit to be on main (main may have moved since the upload; the tag still names exactly what was built).
  • Creates the annotated tag at that commit. On a rerun, it accepts an existing tag only if it names the same commit.
  • Creates a draft release with --verify-tag and --latest=false, carrying the same sdist and wheel and the CHANGELOG notes.
  • Verifies the draft, publishes it, then verifies the immutable release, its downloaded assets, the release attestation and each asset.

verify_release_hosting.py

  • Accepts v<X.Y.Z> or one of the exact prefixes openadapt-agent-, openadapt-flow- and openadapt-types-.
  • New tests: a package tag passes under its own rules; the launcher's v* rules don't cover it; any other prefix is refused.

The matching policy change in OpenAdaptAI/.github (flow and agent bound to this repository and these tags) is OpenAdaptAI/.github#54.

Checks run: pytest tests/test_release_hosting.py (15 passed) and actionlint on the workflow.

…r PyPI

Each package release is tagged <pypi-project>-v<version>; v* stays the
launcher's. Before the upload, preflight-github runs as the
openadapt-release App and requires immutable releases plus active
creation, update and deletion rules for that exact package tag. The build
also requires the package CHANGELOG to open with the version and the tag
not to exist. After PyPI accepts the files, publish-github creates the
annotated tag at the published commit as the App, then a draft release
with the same sdist and wheel and the CHANGELOG notes. It verifies the
draft, publishes it, and verifies the immutable release and its
attestation. verify_release_hosting accepts only the three package tag
prefixes besides v.
@abrichr
abrichr merged commit c5247a2 into main Oct 18, 2026
20 checks passed
@abrichr
abrichr deleted the ci/release-package-tag-and-github-release branch October 18, 2026 00:23
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