Summary
Every deploy, the assemble action re-downloads and unzips every release's
docs.zip to reconstruct the released-version layer of the site. This is the one
recurring cost that scales with the number of releases. A GitHub Actions cache of the
immutable released-tags layer could skip those re-downloads. This is deliberately
not built yet — open this as a tracking issue and revisit only with profiling
evidence.
Why it is deferred (not built now)
- The likely-dominant cost is the N sequential
gh round-trips, not the
downloads. That is already addressed by listing all releases in one
gh api --paginate repos/$repo/releases call (vs N gh release view), which is
faster and simpler and needs no cache.
- The benefit is zero at adoption. A freshly-migrated repo has no
docs.zip
releases yet; the saving grows only as releases accumulate. For a handful of
releases it is within noise.
- It is a real readability cost now for an unproven, future, N-dependent saving.
Bring it back only if profiling on a repo with many docs.zip releases shows the
download/unzip phase dominating.
Why it must be scoped to the immutable release layer (never the whole site)
GitHub cache semantics fight the obvious "cache the expanded site" idea:
- Cache scoping is one-directional. A cache written on a branch is visible only
to that branch and its descendants; the default branch's cache is the only one
all other branches/PRs can restore, and writes never flow upward. So "active
branches write their build into a shared cache" is impossible — which is exactly
why branch/PR previews come from cross-run CI artifacts (gh run download),
which do cross the run/branch boundary. A cache cannot replace artifact gathering
for branches.
- A cached site reintroduces drift. An accumulating tree never forgets a deleted
branch/release unless actively pruned — the very keep_files problem the
reconstruct-from-sources model kills. Letting deploy-pages replace the whole site
every deploy is what makes deletion self-healing; a cached tree forfeits that.
- A cache is never a source of truth. GH caches evict after 7 idle days (and
under a 10 GB/repo LRU cap), so the full durable-source gather must exist
regardless. The cache only ever accelerates it.
So cache only the released-tags layer, which is immutable and permanent.
Sketch of the implementation
A composite action can't express a dynamic per-tag cache step, so the realisation is
a single extracted-releases bundle dir (<tag>/html per release) behind one
actions/cache step:
- Key
docs-releases-v1-<hash of the sorted tag set> with restore-keys prefix
docs-releases-v1-. Adding a release changes the key ⇒ the prefix restores the
previous superset (every prior release), the gather loop downloads only the one new
tag, and the post-step save stores the new superset.
- Released
docs.zip is immutable, so a restored tag dir is never stale (a deliberate
--clobber re-upload is out of scope — bump the v1 prefix if ever needed). On a
miss the loop falls back to gh release download + unzip as today.
- Branches (incl.
main) and open PRs stay fresh from CI artifacts every deploy.
It would be a transparent enhancement to the release-gather step, not a change to the
action's contract; correctness rests entirely on the durable sources whether or not a
cache hits.
Summary
Every deploy, the
assembleaction re-downloads and unzips every release'sdocs.zipto reconstruct the released-version layer of the site. This is the onerecurring cost that scales with the number of releases. A GitHub Actions cache of the
immutable released-tags layer could skip those re-downloads. This is deliberately
not built yet — open this as a tracking issue and revisit only with profiling
evidence.
Why it is deferred (not built now)
ghround-trips, not thedownloads. That is already addressed by listing all releases in one
gh api --paginate repos/$repo/releasescall (vs Ngh release view), which isfaster and simpler and needs no cache.
docs.zipreleases yet; the saving grows only as releases accumulate. For a handful of
releases it is within noise.
Bring it back only if profiling on a repo with many
docs.zipreleases shows thedownload/unzip phase dominating.
Why it must be scoped to the immutable release layer (never the whole site)
GitHub cache semantics fight the obvious "cache the expanded site" idea:
to that branch and its descendants; the default branch's cache is the only one
all other branches/PRs can restore, and writes never flow upward. So "active
branches write their build into a shared cache" is impossible — which is exactly
why branch/PR previews come from cross-run CI artifacts (
gh run download),which do cross the run/branch boundary. A cache cannot replace artifact gathering
for branches.
branch/release unless actively pruned — the very
keep_filesproblem thereconstruct-from-sources model kills. Letting
deploy-pagesreplace the whole siteevery deploy is what makes deletion self-healing; a cached tree forfeits that.
under a 10 GB/repo LRU cap), so the full durable-source gather must exist
regardless. The cache only ever accelerates it.
So cache only the released-tags layer, which is immutable and permanent.
Sketch of the implementation
A composite action can't express a dynamic per-tag cache step, so the realisation is
a single extracted-releases bundle dir (
<tag>/htmlper release) behind oneactions/cachestep:docs-releases-v1-<hash of the sorted tag set>with restore-keys prefixdocs-releases-v1-. Adding a release changes the key ⇒ the prefix restores theprevious superset (every prior release), the gather loop downloads only the one new
tag, and the post-step save stores the new superset.
docs.zipis immutable, so a restored tag dir is never stale (a deliberate--clobberre-upload is out of scope — bump thev1prefix if ever needed). On amiss the loop falls back to
gh release download+unzipas today.main) and open PRs stay fresh from CI artifacts every deploy.It would be a transparent enhancement to the release-gather step, not a change to the
action's contract; correctness rests entirely on the durable sources whether or not a
cache hits.