Release integrity and verification
Yagami publishes immutable, versioned artifacts through one reviewed GitHub
Actions workflow. A release tag must be annotated, must match the versions in
pyproject.toml and src/yagami/__init__.py, and must point to the current tip
of the protected main branch. Release tags cannot be updated or deleted while
the repository's release-tag ruleset is active.
The release workflow reruns the complete Python, UI, and container CI suite. It then performs a clean wheel install, imports the installed application, runs the CLI, starts the built container, checks its health endpoint, and blocks known fixed HIGH or CRITICAL vulnerabilities. The public outputs are:
- A wheel and source distribution on PyPI and the GitHub release.
- A versioned Helm chart archive on the GitHub release.
- Linux
amd64andarm64images atghcr.io/matthewtracy/yagami:<version>and an immutablesha-<commit>tag. - SHA-256 checksums, an SPDX Python-environment SBOM, a Python license inventory, and the exact container digest on the GitHub release.
- GitHub/Sigstore build-provenance attestations for both Python distributions and the pushed container digest. BuildKit also publishes registry-native provenance and SBOM attestations with the image.
Attestations establish which repository, workflow, commit, and environment built an artifact. They do not prove that the code is vulnerability-free or appropriate for a particular regulated workload.
Verify a release
Download the release assets, then verify their checksums:
sha256sum --check SHA256SUMS
Verify a wheel or source archive against this repository's GitHub attestation:
gh attestation verify yagami-0.6.0-py3-none-any.whl \
--repo MatthewTracy/yagami
Verify the downloaded Helm chart the same way:
gh attestation verify yagami-0.6.0.tgz \
--repo MatthewTracy/yagami
Read release-metadata/container-digest.txt from the release and verify that
exact OCI subject:
gh attestation verify \
oci://ghcr.io/matthewtracy/yagami@sha256:<digest> \
--repo MatthewTracy/yagami
Production deployments should use the verified digest, not a mutable local alias:
docker pull ghcr.io/matthewtracy/yagami@sha256:<digest>
Maintainer release procedure
PyPI uses Trusted Publishing. For the first release, create a pending publisher
for project yagami with owner MatthewTracy, repository yagami, workflow
release.yml, and environment pypi. After it is registered, set the GitHub
repository variable PYPI_PUBLISH_ENABLED=true. Never add a PyPI API token or
password to GitHub secrets.
- Update the stable version in
pyproject.tomlandsrc/yagami/__init__.py, and move the shipped changelog entries fromUnreleasedinto that version. Runuv lockand regeneraterequirements.container.lockwith the command recorded at the top of that file whenever runtime dependencies change. Regeneraterequirements.build.lockfromrequirements.build.inwhen build tooling changes. - Merge the change through the protected branch after every required check
passes. Run the
Releaseworkflow manually onmain; this executes all release-only build, clean-install, runtime, vulnerability, SBOM, and attestation steps without publishing anything. - Create and push an annotated tag from the exact
origin/maincommit only after the dry run succeeds:
git switch main
git pull --ff-only
git tag -a v0.6.0 -m "Yagami 0.6.0"
git push origin v0.6.0
- Do not create or upload release artifacts by hand. Wait for the
Releaseworkflow and verify the PyPI project, GitHub release, GHCR digest, checksums, attestations, and package visibility.
Published PyPI filenames and versions cannot be replaced. If a release has a serious defect, yank it on PyPI, document the reason in the GitHub release, and publish a new patch version. If credentials or the release workflow may have been compromised, disable publication, revoke affected credentials, remove compromised container tags, preserve evidence, and publish a security advisory before issuing a clean replacement version.