Release and Recovery Procedure¶
Only a maintainer with repository and PyPI project control may publish a release.
One-Time Trusted Publishing Setup¶
- Create or claim the
pyffmpegcoreproject on PyPI with the intended maintainer account. - In PyPI, add a GitHub Trusted Publisher for owner
OthmaneBlial, repositorypyffmpegcore, workflowrelease.yml, environmentpypi. - In GitHub, protect the
pypienvironment and restrict it to protected release tags. - Keep the workflow permission limited to
id-token: write; do not add a long-lived PyPI API token.
Release Gate¶
- Confirm every earlier P0 roadmap gate and all required checks are green.
- Update
CHANGELOG.md, compatibility notes, and the runtime version. - Run the Release workflow manually in dry-run mode.
- Create an SSH-signed annotated tag matching the runtime version exactly.
The maintainer key must match
.github/allowed_signers, and the GitHub tag ruleset prevents deletion and non-fast-forward updates ofv*refs:
git -c gpg.format=ssh \
-c user.signingkey="$HOME/.ssh/id_ed25519" \
tag -s v0.2.0 -m "pyffmpegcore 0.2.0"
git -c gpg.format=ssh \
-c gpg.ssh.allowedSignersFile=.github/allowed_signers \
tag --verify v0.2.0
- Push the tag. The workflow builds once, tests the exact wheel on the supported OS/Python anchors, attests it, and publishes it through OIDC.
- The workflow waits for the exact wheel and source distribution to appear in the public PyPI JSON endpoint. It then performs a clean
pipx install,--version,doctor, andsmoke-teston Linux, macOS, and Windows before creating the matching GitHub Release with checksums. A failed public-install gate must be fixed forward; it must not be bypassed by creating the release manually. - Record the public terminal proof only after those endpoints are healthy:
The recorder installs the exact public version in a fresh environment, captures a real PTY session, enforces a 60–90 second duration and required proof steps, rejects private home paths, and writes an accessible text transcript beside the cast. Never hand-edit the recording to invent output.
Never rebuild or replace files for an existing version. A failed gate means fix forward with a new commit and, if any immutable artifact was already published, a new version.
Rollback and Yanking¶
Python packages cannot be safely “rolled back” by replacing files. For a broken but non-malicious release:
- yank the affected PyPI version with a concise reason;
- mark the GitHub Release as affected without deleting evidence;
- document the impact and workaround;
- publish a corrected patch version through the normal pipeline.
Delete an artifact only for legal, credential, malware, or personal-data exposure where preservation causes more harm. Record the reason privately and publish a public incident note when safe.
Deprecation¶
Announce a CLI/API deprecation in the changelog and user documentation before removal. Keep the old behavior for at least one feature release when security and correctness allow, provide a migration example, and use a major version for intentional incompatible public-contract changes.
Security Fixes¶
Coordinate confirmed vulnerabilities in a private GitHub Security Advisory. Prepare tests and the fix on the advisory fork when needed, request a CVE when appropriate, and publish the patched release before or with disclosure. Do not expose reporter data or exploit details prematurely. Follow the response expectations in the security policy.