fix(docs): retain prior builds' hashed assets across Pages deploys
Pages serves exactly the newest artifact, so every push-triggered deploy deleted the previous build's content-hashed JS/CSS while edge caches (max-age=300, stale-while-revalidate=3600) kept serving HTML that referenced them. With deploys landing every ~15-30 min, docs pages spent most of the day pointing at 404'd bundles — search (pure client JS) was the loudest casualty. Fix: keep a rolling 14-day pool of hashed assets (en + zh-Hans) in the Actions cache and union-merge it into each deploy artifact, current build authoritative on collision (cp --update=none). Stale HTML and already-open tabs now keep resolving across any number of deploys.
This commit is contained in:
55
.github/workflows/deploy-site.yml
vendored
55
.github/workflows/deploy-site.yml
vendored
@@ -189,6 +189,61 @@ jobs:
|
||||
cp website/build/llms-full.txt _site/llms-full.txt
|
||||
fi
|
||||
|
||||
# Pages serves exactly the newest artifact, so each deploy used to delete
|
||||
# the previous build's content-hashed JS/CSS while edge caches (Vercel →
|
||||
# Fastly, max-age=300 + stale-while-revalidate=3600) kept serving HTML
|
||||
# that referenced it — every asset request 404'd for up to ~65 minutes
|
||||
# after each deploy. With push-triggered deploys landing every ~15-30
|
||||
# minutes, the docs were in that broken window most of the day (search,
|
||||
# being pure client JS, died first). Fix: keep a rolling pool of prior
|
||||
# builds' hashed assets and union-merge it into every artifact so stale
|
||||
# HTML keeps resolving. Hashed filenames are content-addressed, so a
|
||||
# collision is by definition the identical file — the merge never
|
||||
# overwrites current-build output (cp --update=none).
|
||||
- name: Restore asset retention pool
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: _asset_retention
|
||||
key: docs-asset-retention-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
docs-asset-retention-
|
||||
|
||||
- name: Merge retained assets from previous deploys
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ASSET_DIRS="assets zh-Hans/assets"
|
||||
mkdir -p _asset_retention
|
||||
# 1) Add this build's hashed assets to the pool (fresh mtimes, so
|
||||
# assets still shipped by current builds never age out).
|
||||
for d in $ASSET_DIRS; do
|
||||
if [ -d "_site/docs/$d" ]; then
|
||||
mkdir -p "_asset_retention/$d"
|
||||
cp -a "_site/docs/$d/." "_asset_retention/$d/"
|
||||
fi
|
||||
done
|
||||
# 2) Drop pool entries no build has produced for 14 days — far
|
||||
# beyond any edge-cache or open-tab horizon.
|
||||
find _asset_retention -type f -mtime +14 -delete
|
||||
find _asset_retention -type d -empty -delete
|
||||
# 3) Union-merge the pool into the artifact; --update=none keeps the
|
||||
# current build authoritative for any path it produced.
|
||||
for d in $ASSET_DIRS; do
|
||||
if [ -d "_asset_retention/$d" ]; then
|
||||
mkdir -p "_site/docs/$d"
|
||||
cp -R --update=none "_asset_retention/$d/." "_site/docs/$d/"
|
||||
fi
|
||||
done
|
||||
echo "retention pool:" && du -sh _asset_retention
|
||||
echo "deployed assets:" && du -sh _site/docs/assets
|
||||
|
||||
- name: Save asset retention pool
|
||||
# Always save under a fresh key (caches are immutable); restore-keys
|
||||
# prefix matching picks the newest on the next run.
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: _asset_retention
|
||||
key: docs-asset-retention-${{ github.run_id }}
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
|
||||
with:
|
||||
|
||||
Reference in New Issue
Block a user