-
Notifications
You must be signed in to change notification settings - Fork 0
RELEASING
Only a clean, reviewed commit on main may become a release. Production
publishing uses GitHub Actions OIDC Trusted Publishing; API tokens and local
uploads are prohibited.
- Protect
mainwith a ruleset that requires CI, CodeQL, signed commits, and every review conversation to be resolved before merge, and that prevents force pushes and deletion. - Enforce tag immutability with a ruleset for
v*.*.*: prevent tag update and deletion, and restrict creation to the maintainer. - Create GitHub environments
testpypiandpypi. For the current one-maintainer release, configuresodejmas the required reviewer forpypi; self-approval must remain permitted so the production deployment does not deadlock. Requiring a reviewer other than the workflow initiator is a future hardening step after a second maintainer exists. - Register pending Trusted Publishers on TestPyPI and PyPI for
sodejm/AncestryLLM, workflowrelease.yml, and the matching environment. Keep publishing OIDC-only; no API token or token secret is a permitted fallback. - Enable GitHub immutable releases.
- Enable automatic deletion of merged pull-request branches.
These hosted controls are not created or changed by the repository workflows. An authorized maintainer must approve and verify each one in GitHub, PyPI, and TestPyPI before the first production release.
Before the readiness run, verify and record each control in issue #133 with
the verifier, date, and a settings-page link or redacted screenshot:
- the
mainruleset requires the named CI and CodeQL checks, signed commits, resolved review conversations, and blocks force pushes and deletion; - the
v*.*.*tag ruleset restricts creation and blocks update and deletion; - the
pypienvironment hassodejmas the required reviewer, while self-approval remains enabled for the current one-maintainer release; - the TestPyPI and PyPI Trusted Publishers match repository
sodejm/AncestryLLM, workflowrelease.yml, and their exact environments, and no API-token publishing secret or fallback is configured; and - GitHub immutable releases and automatic pull-request branch deletion are enabled.
Any missing or mismatched control blocks readiness. After a second maintainer is available, separately approve and verify the change that disables initiator self-approval; do not make that change during the one-maintainer release.
- Complete every issue and pull request in the release milestone without
bypassing checks, except for exactly one open, non-pull-request issue: issue
#133, labeledrelease-tracker. Any other open issue or pull request, another issue with the label, an unlabeled#133, or multiple tracker exceptions blocks readiness and release. Both workflows paginate the full milestone result before applying this rule. Close an item only after its implementation, documentation, regression tests, dead-code review, and required hosted checks are complete. - For every candidate release branch and worktree, first confirm a clean
status with
git status --short, then audit reachability and unique commits withgit rev-list --left-right --count main...<branch>andgit log main..<branch>. Only remove the worktree and use normalgit branch -d <branch>when it is clean and its work is fully reachable frommain; then confirm the remote branch was deleted. Never use-Dto make this check pass. Preserve and record any dirty or active worktree, graph-unique commits, unmerged branch, or abnormal deletion failure for explicit follow-up. - Finalize the dated changelog, curated
docs/release-notes/<version>.md, and versioned findings/interoperability records underdocs/release-evidence/<version>/. Every finding needs an owner and expiry; every importer needs a dated evidence link, and only fictional-data manual imports may be marked verified. - Approve and merge a release-only preparation PR through the protected
mainruleset, after required checks pass and conversations are resolved. - Confirm the
0.2.0 CLImilestone has no open issues or pull requests except the single permitted#133release-trackerissue. - Run
Release readinesswith the exactmaincommit and semantic version, and affirm the branch/worktree cleanup input, backed by the documented reachability and unique-commit audit. - Review the evidence artifact and confirm every required job succeeded.
At the exact approval points, a maintainer approves the release-preparation PR;
the readiness operator attests the cleanup audit and approves its evidence; the
maintainer approves creation and push of the signed tag; and sodejm approves
the pypi environment deployment. For this one-maintainer release, that final
approval may be self-approval by the workflow initiator. A separate explicit
approval is required for the GitHub-only fallback described below.
The workflow rechecks milestone closure with only the exact #133
release-tracker exception and refuses every other open item. Local worktrees
are machine-specific, so their cleanup is an explicit operator attestation
recorded in the evidence bundle.
The readiness workflow records the exact commit, run URL, and complete gate
inventory in gates.json. The tag workflow rechecks milestone closure, requires
that exact approved record, and compares the release distribution hashes with
the readiness build before any artifact is published.
Configure Git tag signing before creating the release tag. From a clean checkout
whose HEAD is the approved main commit. When using SSH signatures, also
configure gpg.ssh.allowedSignersFile with the maintainer identity and the
registered signing public key so local verification is meaningful. Confirm the
release commit first with git log --show-signature -1, then:
git tag -s v0.2.0 HEAD -m "AncestryLLM 0.2.0"
git tag -v v0.2.0
git push origin v0.2.0Push only the release tag. The tag-triggered workflow verifies the signed,
annotated tag; rebuilds and attests the artifacts; prepares a draft GitHub
Release; publishes to TestPyPI with attestations: false because TestPyPI does
not provide PyPI's PEP 740 Integrity API; it verifies only the exact TestPyPI
artifact hashes; and pauses for required production approval. Production PyPI
publishing explicitly requests attestations: true. The workflow then verifies
the PEP 740 provenance for both the wheel and source distribution, including
exact repository, workflow, environment, filename, and SHA-256 identity, with
the pinned pypi-attestations==0.0.30 verifier. It preserves the provenance and
verifier output as evidence and fails closed. After production PyPI publishing,
the supported platform/Python wheel-and-sdist install smoke matrix runs before
the immutable GitHub Release. The attached SHA256SUMS covers
every release asset except the checksum file itself.
Retry only transient failed jobs. Never make an upload idempotent by silently skipping or overwriting an existing file.
If initial draft creation stops after a partial asset upload, verify that the release is still a draft and that the tag is unchanged, delete only that unpublished draft, and rerun the workflow. Draft reuse is accepted only when its title, body, complete asset inventory, checksum manifest, and every asset hash already match the workflow build exactly.
If PyPI remains unavailable after an approved retry, stop the failed workflow.
Only when the maintainer explicitly approves a GitHub-only release may the
draft be published, and only when the failure is external to the product and
artifacts, every non-index release gate passed, and the prepared draft still
contains the exact workflow-built assets. Download the release-distributions
artifact from that run and the draft assets into separate directories, then
require:
python scripts/verify_release_assets.py \
--expected /path/to/release-distributions \
--actual /path/to/draft-downloadBefore publishing the immutable draft, edit its body to state
PyPI: unavailable, link the failed workflow run, and remove every PyPI or
TestPyPI verification claim. Record that explicit approval in the tracking
issue. Do not use an API-token fallback, upload replacement files, or claim
that the GitHub-only release is available from a Python package index.
If a product or artifact defect makes 0.2.0 unusable, preserve the tag and
release evidence, yank the PyPI version when appropriate, document the reason,
and publish the correction as 0.2.1. Never force-push or recreate a release
tag.
- Home
- CLI reference
- Interactive console guide
- Architecture ownership and dependency contracts
- Bounded file ingress
- Versioning and compatibility
- Continuous integration
- Release runbook
- Encrypted backup and recovery
- First-run storage diagnostics
- GEDCOM compatibility and release checks
- Built-in module authoring
- Privacy and consent
- Provider guide
- Local LLM benchmarks
- Local-first retrieval evaluation
- Wiki synchronization
- Wiki operations and recovery
- Security response checklist
- Electron and FastAPI desktop ADR
- Data-flow threat model and control matrix