Skip to content

Latest commit

 

History

History
47 lines (33 loc) · 4.99 KB

File metadata and controls

47 lines (33 loc) · 4.99 KB

Releasing

How the five packages get to PyPI; the everyday conventions are in AGENTS.md. publish_release.yml fires on push to release, so merging is what publishes, and the pipeline extracts the changelog section matching each tag as the GitHub release notes.

The branch loop

  1. rel-<date>-NNrelease — the PR targets release, never main. Merging it starts the publish run.
  2. The workflow tags and publishes on the release ref. Never hand-tag, and never tag on main.
  3. releasemain with a plain merge commit (gh pr merge <n> --merge), preserving the released commit in main's history. The publish jobs appear as release-packages (<pkg>) checks on this PR; don't merge before they are green — a failed publish is easier to redo before main absorbs the release commit.

The push trigger takes no inputs: with no force_packages or environment, check-package-versions compares each version against PyPI to decide what to build, and publishes to production. priority-order: bfabric,bfabric_scripts,bfabric_app_runner plus max-parallel: 1 releases sequentially, so bfabric lands before the packages that floor on it.

Verify offline first

Install it the way a user gets it, then import whatever the release touched:

uv venv /tmp/rel -p 3.11
uv pip install --python /tmp/rel --no-sources ./bfabric   # --no-sources: resolve deps from PyPI, not the workspace
uv pip list --python /tmp/rel | grep -i bfabric           # check the resolved dependency floor
/tmp/rel/bin/python -c "import bfabric"

Import the real [project.scripts] modules (bfabric_scripts.cli.__main__, bfabric_app_runner.cli.__main__); a guessed path raises ImportError and reads like a broken release. Don't use --help@use_client connects before the command body runs, so it fails for config reasons unrelated to the release. A dependent package can't be verified until the core publishes, since its new floor (bfabric>=1.20.0) excludes the current rc under PEP 440 and the run doesn't pause between packages: verify bfabric before opening the PR, the dependents right after (PyPI's index lags about a minute).

Out-of-band dispatch (hotfixes, re-runs)

  • Never dispatch environment: test as a dry run. It only switches the PyPI URL; tag creation and the GitHub release are ungated and run first, so the real tag is pushed and the production re-run then dies at git tag -a. Verify locally and dispatch straight to production.
  • Pass force_packages explicitly — a non-empty value skips the PyPI comparison, so only the named packages build. Confirm via Forcing release of <pkg> in the check-packages log.
  • Leave "Set as the latest release" unchecked, except for bfabric stable — GitHub keeps one repo-wide badge and it belongs to the core library. rcN and 0.x tags are auto-flagged as prereleases.

Release candidates

  • Keep one cumulative entry per RC line (e.g. ## [1.20.0rc2]) covering the full changeset for the upcoming X.Y.0, re-dated and extended for each RC rather than stacked below the last one. The published tags keep the per-RC history.
  • RC entries use flat, abbreviated, headline-first bullets — the one exception to the Keep a Changelog subsections — with dev-facing changes in a trailing Internal: bullet.
  • Graduation renames [X.Y.0rcN] to [X.Y.0] with the date; no content merge, since the entry was cumulative.
  • A floor on an unreleased bfabric must name the rc (bfabric>=1.20.0rc2,<1.21); a plain >=1.20.0 excludes it under PEP 440.

Hotfixes (patch of an older line)

  1. Find what is actually released on that line — check the <pkg>/* tags and PyPI. Your base is the latest released patch and your version is that + 1; guessing collides with an existing tag or silently drops a shipped patch.
  2. Land the fix on main first, via a normal reviewed PR under [Unreleased], so one commit is the source of truth.
  3. Cut from the version tag and cherry-pick once that PR merges, so the recorded SHA is permanent: git checkout -b hotfix/<pkg>-X.Y.Z <pkg>/X.Y.(Z-1), then git cherry-pick -x <main-commit>.
  4. Add the version bump and the ## [X.Y.Z] section on the hotfix branch — that is what the pipeline extracts into the tag and GitHub Release.
  5. Publish out-of-band: gh workflow run publish_release.yml --ref hotfix/<pkg>-X.Y.Z -f environment=production -f force_packages=<pkg>. Merging into release would mislabel a tree that is ahead on a newer line.
  6. Forward-port under [Unreleased] only — never backfill a ## [X.Y.Z] section into main, which can't hold a past-line patch without breaking version or date order. A fix that can't apply to main leaves its changelog alone, since an [Unreleased] bullet would be promoted into the next release's notes.
  7. Never open a PR from the hotfix branch — its diff against main reads as a mass revert and CI would run the old line's whole suite. The tag and GitHub Release are the record; the only PR is the forward-port.