Conversation
…orever The gitignore.in binary cache is keyed only by os/arch/version, and actions/cache never overwrites an existing key. So once a corrupted or truncated archive is written under a key (e.g. from an interrupted upload in a cancelled run), that key can never be replaced: every later run restores the same bad bytes. For the bundled version, a checksum mismatch was already detected and triggered a fresh download for that run, but the corrected archive had no way back into the cache, so every future run kept re-downloading and re-detecting the same stale corruption instead of converging on a good, cached state. Compute the cache key once and pass it to install-gitignore-in.sh. When the cached archive fails its SHA-256 check, evict that cache entry with `gh cache delete` before falling back to a fresh, verified download, so the corrected archive can be saved back under the same key at the end of the run. Eviction is best-effort: it needs the `actions: write` permission, and its absence only degrades to the previous always-re-download behavior (with a warning) rather than failing the run.
kitsuyui
deleted the
fix/audit-cache-corrupted-archive-persists-unverified-001
branch
September 21, 2026 07:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
action.ymlcaches thegitignore.inbinary withactions/cache, keyed only by{os, arch, gitignore-version}.actions/cachenever overwrites an existing key, so once acorrupted or truncated archive is written under a key (e.g. an interrupted upload from a
cancelled earlier run), that key can never be replaced: every later run restores the same bad
bytes. For the bundled version,
scripts/install-gitignore-in.shalready re-verifies thecached archive's SHA-256 and falls back to a fresh download on mismatch, but the corrected
archive had no way back into the cache, so every future run kept re-downloading and
re-detecting the same stale corruption instead of converging on a good, cached state.
What changed
action.yml: compute theactions/cachekey once in a dedicated step and reuse it both forthe cache
key:and as an env var (GITIGNORE_IN_CACHE_KEY) passed to the install script, sothe two stay in sync. Also pass
GH_TOKEN: ${{ github.token }}to the install step.scripts/install-gitignore-in.sh: when the cached archive fails its SHA-256 check, evict thatcache entry with
gh cache delete "${cache_key}"before falling back to the fresh, verifieddownload, so the corrected archive can be saved back under the same key at the end of the run.
Eviction is best-effort — it needs the
actions: writepermission on the token; if that'smissing, it logs a
::warning::and behavior degrades to the previousalways-re-download-on-mismatch behavior (no regression, no new failure mode).
scripts/test-install-gitignore-in.sh: theshasumstub can now be told to fail on its firstinvocation only (
SHASUM_FAIL_ONCE=true), and aghstub records calls and can simulate afailed eviction (
STUB_GH_CACHE_DELETE_EXIT=1). Two new tests cover: (1) a corrupted cache hittriggers
gh cache deletewith the right key and a fresh, verified install still succeeds, and(2) when eviction itself fails, the action still installs correctly and only logs a warning.
README.md: document the cache-eviction behavior and the optionalactions: writepermissionit needs.
The intentionally-unverified custom-
gitignore-versionpath(
allow-unverified-gitignore-version: true) is unchanged — that is documented, opt-in behavior,not the bug this fixes.
Verification
scripts/test-install-gitignore-in.shpasses, including the two new tests.shellcheckonscripts/*.shand on the extractedaction.ymlrun blocks passes.shfmt -d scripts/*.shreports no diff.