The tag workflow creates a draft GitHub Release only after every expected artifact is present and checksummed. Publishing the draft, uploading to Play or distributing desktop archives remains an explicit owner action.
- Permanent name/application ID, publisher contacts and asset rights are
approved in
IDENTITY_AND_ASSETS.md. - Owner signing key recovery drill and certificate fingerprint are current.
-
release-version.jsonis incremented andpython3 tools/verify_release_version.pypasses. -
CHANGELOG.md,FORK_DELTA.md, privacy/Data safety and listing text match the exact release candidate. - Full CI, instrumentation, license/SBOM and strict performance evidence are green.
-
telemetry-policy.jsonremains disabled and the no-telemetry gate passes. - Both clean-runner rebuilds pass
REPRODUCIBLE_BUILDS.md; investigate any mismatch rather than adding an artifact-specific exception. - Clean install, previous-version upgrade, SAF root, database migration, OPDS, consumption-only LitRes and TTS checks pass.
- Linux and macOS archives start on their declared clean reference systems. Record that the macOS archive is not notarized unless a separate owner-controlled signing/notarization step is added.
- Create the reviewed tag
v<versionName>on the reviewed commit and push only that tag. - The release workflow validates tag/version equality and protected signing secrets.
- Confirm the draft contains exactly:
- signed AAB and universal APK;
- Android native debug symbols and signing-certificate evidence;
- Android SPDX 2.3 SBOM;
- Linux x86_64 and macOS arm64 desktop archives;
SHA256SUMS.
- Independently recompute checksums after downloading the complete artifact.
- Inspect generated release notes and keep the GitHub Release as a draft until the P0 Play/privacy/identity requirements are complete.
The CI secret store needs COOLREADER_RELEASE_STORE_BASE64,
COOLREADER_RELEASE_STORE_PASSWORD, COOLREADER_RELEASE_KEY_ALIAS and
COOLREADER_RELEASE_KEY_PASSWORD. Restrict them to the protected release
environment. The base64 value is transport encoding, not encryption.
- Verify AAB/APK signer SHA-256 against the owner record.
- Generate an APK set with the current bundletool and test clean install and update from the previous production certificate/version.
- Complete internal/closed/pre-launch gates in
PLAY_RELEASE.md. - Confirm Play artifact version, permissions, Data safety, content rating, privacy URL and consumption-only behavior before production.
- Verify archive root, executable, resources, translations, hyphenation data, license/notice files and clean-system startup.
- Record dynamically required system libraries for Linux.
- Verify macOS architecture, Gatekeeper behavior and any owner-applied signature/notarization.
- Publish source/notice obligations alongside binary archives.
Do not delete or overwrite an immutable published tag/artifact.
- Play: halt the rollout. Users already updated are not downgraded; prepare a higher-version hotfix from the last known-good source and the same signing lineage.
- GitHub/desktop: mark the release and affected assets as withdrawn, retain forensic evidence, and publish a higher-version replacement. Do not silently replace a file under the same filename/checksum.
- Preserve the failing artifact, logs, SBOM, symbols, reproduction steps and impact assessment. If privacy/data integrity is involved, stop distribution before normal bug triage.
- Branch from the last known-good release commit.
- Apply only the minimal fix and its regression test.
- Increment fork release, Android code and tag; update changelog/delta.
- Run the full release gates—hotfix urgency does not waive signing, migration, privacy or artifact verification.
- Publish clear impact/upgrade notes and monitor the rollout using the same stop criteria.