Skip to content

Hardening candidates: CI artifact retention and release assets #247

Description

@jeiel85

Candidates surfaced by the artifact-retention work (#243, #244). Filed alongside the change, not worked on in it. Nothing here blocks a release.

  • The Release asset list has no CI gate, only prose in three places. D062 recorded that this list drifted twice (docs/RELEASE.md claimed "all three assets" for two releases, AGENTS.md claimed both providers publish "APK/AAB 릴리스"). ci: drop R8 mapping from the Release and cap artifact retention #244 had to hand-sync the same three spots again — two paragraphs in docs/RELEASE.md and one in AGENTS.md. Nothing fails if they drift a third time. A check that asserts the gh release create argument list against the documented one would make the "documented interface" claim enforceable. Affects: release documentation accuracy, and trust in D062/D064 as a contract.
  • gh release create file arguments are only exercised on a tag push. ci: drop R8 mapping from the Release and cap artifact retention #244 removed the step that produced markleaf-vX.Y.Z.mapping.txt; had the matching argument been left behind, the release job would have failed at tag time with a missing file, after the tag was already public. The release job is skipping on PRs, so PR CI cannot catch it. A dry-run or an argument-vs-produced-files assertion inside the build job would move the failure earlier. Affects: tag-time release failures that require deleting and re-pushing a tag.
  • Permanent mapping retention depends on a manual local step. :app:exportReleaseToBuildDrive is run by hand, and it had not been run for six released versions — v2.27.2, v2.28.0, v2.28.1, v2.28.2, v2.28.3, v2.29.0 had no mapping in D:\Build. This was only discovered while deleting the GitHub copies, and those six were recovered from GitHub before deletion. Now that the mapping is no longer a Release asset (D064), skipping the local export silently loses it for good. Affects: ability to deobfuscate crash reports from sideloaded builds.
    • Done in release: make the local export a required, verified pre-tag step #248. scripts/verify-release-export.ps1 asserts the AAB, mapping, and six-locale notes exist and are non-empty for the current versionName/versionCode, and docs/RELEASE.md / AGENTS.md now make the export a required pre-tag step. It also covers a case the original note missed: the export can succeed without a mapping, because writeReleaseArtifacts throws on a missing AAB but only logs a warning on a missing mapping.
    • Two limits remain, deliberately out of scope there. The gate is local-only — CI cannot see D:\Build — so it converts a silent omission into a loud one at tag time but still depends on someone running it. And the six missing AABs were never recovered; only the mappings were, pulled from the Release assets before they were deleted.
  • A missing GitLab mirror run is not detectable. v2.28.0 and v2.28.1 shipped without GitLab Releases because the monthly CI minutes ran out, and nothing reported it. D064 leans on GitLab as a secondary permanent copy while explicitly calling it unguaranteed; there is currently no way to know a given tag is missing from the mirror short of opening it. Affects: the DR mirror silently degrading to zero coverage.
    • Narrower than filed, but still open. The daily mirror-check workflow (added 2026-07-20) compares refs/heads/main and refs/tags/v* across the two remotes, so a tag that never reached GitLab is now detectable and the check has been green. What it cannot see is the Release objectverify-mirror.ps1 reads refs, and the Release plus its AAB/mapping are created by the GitLab CI pipeline, which is the part the quota stops.
    • So the blind spot is exactly the artifact half of D064, and it is not hypothetical: measured 2026-07-24, GitLab's newest Release is still v2.27.2 (2026-07-21) — eight releases missing while every tag is present. Tracked with the outage itself in Hardening candidates: v2.29.1 #252.
  • Retention is set per artifact with no stated policy, and three still use the 90-day default. roborazzi-diff-images, roborazzi-goldens-linux, and lint-report-release keep the default while the four binary artifacts now carry explicit values. The defaults are defensible individually but the reasoning lives only in code comments. Worth deciding once whether diff images and goldens need 90 days. Affects: storage accumulation — this repo had 821 artifacts totalling 8.7 GB before ci: cap debug APK artifact retention at 7 days #243.
  • launch-smoke is non-required because it flakes, and the flake is unexamined. Both ci: cap debug APK artifact retention at 7 days #243 and ci: drop R8 mapping from the Release and cap artifact retention #244 merged while it was still pending, which is by design, but it means the emulator smoke path has not gated a merge in some time. Either the flake gets diagnosed and the job becomes required, or the job is not carrying its weight. Affects: confidence that the app still launches on a clean device.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions