Your First GitHub Actions Library Cache Bust Receipt for Unity Addressables in One Evening - 2026
Your GitHub Actions badge is green. Your Addressables group move merged Tuesday. Wednesday demo smoke fails with InvalidKeyException on the first asset load. CI never rebuilt Addressables content—it restored yesterday's Library/ from actions/cache.
October 2026 fest prep teams move Addressables groups weekly. Cached Library/ is the silent failure mode: compile succeeds, player build loads stale catalog references, and only the installed smoke catches it. 7-day Addressables key audit owns K1–K7 inventory calendar; jq inventory preflight owns schema—this Tutorials & Beginner-First guide closes the CI cache gap in one evening: hash AddressablesContentState.bin, fix your cache key, add a clean Library/ job, file unity_ci_library_cache_receipt_v1.json, and set library_cache_bust_ok on BUILD_RECEIPT before fest promotion.
Non-repetition note: Invalid Key runtime help owns player triage; Library cache preflight (Guide) owns the ninety-second checklist; Lesson 261 owns the BUILD_RECEIPT milestone. This URL is the beginner evening path for teams who cache Library/ but never busted after group moves.
Why this matters now (October 2026)
- Group moves on Tuesday, promote Wednesday — Default cache keys hide catalog drift on the same branch.
InvalidKeyExceptionafter green CI — Discord reports spike; engineers blame "Addressables bug" instead of cache.- Fest content updates — October strip weeks delete groups; restored
Library/references ghosts. - False-green CI culture — Teams skip Wednesday smoke because "GitHub passed."
- Receipt rows multiplied — Thursday row review needs
library_cache_bust_okbesidedemo_smoke—this evening wires it.
Direct answer: Hash Library/com.unity.addressables/AddressablesContentState.bin, include that hash in actions/cache key, run rm -rf Library Temp after group moves, file unity_ci_library_cache_receipt_v1.json with C1–C6 pass, set library_cache_bust_ok: true on BUILD_RECEIPT before promotion.
Who this is for and what you get
| Audience | You will be able to… |
|---|---|
| Beginner with first Unity CI | Turn off branch-only cache keys with one checkbox list |
| Solo engineer | Stop promoting after Addressables moves without bust |
| Producer | Require receipt before Wednesday smoke week |
| Working dev | Wire ContentState hash + fail-closed jq gate |
Time: ~2–3 hours first evening (includes one CI run); 15 minutes per group-move week after template exists.
Prerequisites: Unity 6.x + Addressables; GitHub Actions workflow with actions/cache on Library/ (or willingness to add it); one recent Addressables build locally or in CI.
What you will have after one evening
- Cache key YAML including
AddressablesContentStatesha256 clean-library-on-group-moveworkflow_dispatch job (or documented manual trigger)unity_ci_library_cache_receipt_v1.jsonpassing C1–C6- BUILD_RECEIPT column
library_cache_bust_ok release-evidence/unity/ci-cache/README.mdwith hash paths- Optional no-cache weekly job sketch for strip months
Beginner checkbox (turn off bad cache)
Before YAML depth, confirm you are not doing these:
| # | Bad habit | Fix tonight |
|---|---|---|
| 1 | Cache key = github.ref or branch name only |
Add ContentState hash (C2) |
| 2 | Restore Library/ after deleting Addressables groups |
Run clean job (C3) |
| 3 | Trust green badge without player smoke | Pair Wednesday smoke |
| 4 | Skip Temp/ clear on Addressables build |
Add rm step (C4) |
| 5 | Promote without receipt JSON | File C6 before merge |
Success check: After a deliberate group move, CI either uses a new cache key or runs no-cache once—and player smoke loads moved assets.
Evening overview (four blocks)
| Block | Minutes | Output |
|---|---|---|
| A — Find ContentState | 20–30 | sha256 logged |
| B — Fix cache key | 45–60 | Workflow YAML PR |
| C — Clean job | 30–45 | clean-library-on-group-move |
| D — Receipt + BUILD_RECEIPT | 30–45 | JSON + library_cache_bust_ok |
Run one CI workflow after B before filing receipt—receipt must describe observed cache behavior, not intent only.
Gates C1–C6 (promotion discipline)
Align with Library cache preflight (Guide). Blog = evening path; guide = ninety-second gate.
| Gate | Check | Fail when |
|---|---|---|
| C1 | AddressablesContentState.bin exists post-build |
Path missing in CI log |
| C2 | Cache key includes ContentState hash | Branch-only key |
| C3 | Clean-library job linked after group move | No bust path documented |
| C4 | Temp/ cleared on Addressables player build |
Stale script assemblies |
| C5 | Fail-closed promotion jq | Merge without library_cache_bust_ok |
| C6 | unity_ci_library_cache_receipt_v1.json |
Missing on promotion |
Promotion rule: content_update_promotion_allowed is true only when C1–C6 pass and Wednesday smoke S4–S6 are GREEN on the same build_label.
Block A — Locate and hash AddressablesContentState
Default path after an Addressables content build:
Library/com.unity.addressables/AddressablesContentState.bin
Linux / macOS / GitHub Actions:
STATE="Library/com.unity.addressables/AddressablesContentState.bin"
sha256sum "$STATE"
Windows PowerShell:
Get-FileHash "Library\com.unity.addressables\AddressablesContentState.bin" -Algorithm SHA256
Log hash, build_label, and K1 inventory sha256 in receipt notes.
Red flag: File missing in CI before hash step—run Addressables build step before cache restore on content-update weeks (C1 fail).
Block B — Cache key sketch (GitHub Actions)
Add a hash step before actions/cache restore:
- name: Hash Addressables content state
id: addr_state
shell: bash
run: |
STATE="Library/com.unity.addressables/AddressablesContentState.bin"
if [ -f "$STATE" ]; then
echo "hash=$(sha256sum "$STATE" | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
else
echo "hash=missing" >> "$GITHUB_OUTPUT"
fi
- uses: actions/cache@v4
with:
path: Library
key: unity-library-${{ runner.os }}-${{ hashFiles('ProjectSettings/ProjectVersion.txt', 'Packages/manifest.json') }}-${{ steps.addr_state.outputs.hash }}
restore-keys: |
unity-library-${{ runner.os }}-${{ hashFiles('ProjectSettings/ProjectVersion.txt', 'Packages/manifest.json') }}-
Fail-closed: If steps.addr_state.outputs.hash == missing on the Addressables build job, fail the workflow—do not restore unbounded Library/.
Cache key policy table (pin in #unity-ci)
| Input | Include in cache key? | Why |
|---|---|---|
ProjectSettings/ProjectVersion.txt |
Yes | Editor version drift |
Packages/manifest.json hash |
Yes | Package graph |
AddressablesContentState.bin sha256 |
Yes — mandatory | Group/catalog moves |
address_inventory_v1.json sha256 |
Recommended | K1 inventory changes |
Library/ whole-tree hash |
No — too slow | Use ContentState instead |
| Git branch name alone | No | Hides group moves on same branch |
Pair 15-free GitHub Actions CI recipes for build graph patterns—this post owns cache bust material, not full workflow authoring.
Block C — Clean job after group move
When K1 inventory shows group changes, bust cache explicitly:
clean-library-on-group-move:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Remove stale Library and Temp
run: rm -rf Library Temp
- name: Note for receipt
run: echo "clean-library-on-group-move ran at $(date -u +%Y-%m-%dT%H:%M:%SZ)"
Trigger manually after Tuesday group moves—or automate when address_inventory_v1.json diff detected in a follow-up PR.
No-cache weekly job sketch (strip months):
weekly-no-cache-addressables:
if: github.event.schedule == '0 6 * * 2'
runs-on: ubuntu-latest
steps:
- run: rm -rf Library Temp
# then run full Addressables build without cache restore
Document trigger in release-evidence/unity/ci-cache/README.md.
Block D — unity_ci_library_cache_receipt_v1.json
Pin under release-evidence/unity/ci-cache/UNITY_CI_LIBRARY_CACHE_RECEIPT.json:
{
"schema": "unity_ci_library_cache_receipt_v1",
"build_label": "october-fest-2026-rc3",
"addressables_content_state_path": "Library/com.unity.addressables/AddressablesContentState.bin",
"addressables_content_state_sha256": "b7e2c4f1a9d8e3b6…",
"inventory_path": "release-evidence/unity/addressables-jq/address_inventory_v1.json",
"inventory_sha256": "aa11bb22…",
"cache_key_template": "unity-library-{os}-{project}-{packages}-{content_state_hash}",
"workflow_path": ".github/workflows/unity-addressables-ci.yml",
"clean_library_job": "clean-library-on-group-move",
"cousin_receipts": {
"jq_audit": "release-evidence/unity/addressables-jq/ADDRESSABLES_AUDIT_JQ_RECEIPT.json",
"key_audit_week": "release-evidence/unity/addressables-audit-week/addressables_key_audit_receipt_v1.json"
},
"gates": {
"C1_content_state": "pass",
"C2_cache_key": "pass",
"C3_clean_job": "pass",
"C4_temp_clear": "pass",
"C5_fail_closed": "pass",
"C6_receipt": "pass"
},
"library_cache_bust_ok": true,
"content_update_promotion_allowed": true
}
Alias note: Some resource briefs reference addressables_ci_cache_receipt_v1.json—same gate semantics; canonical schema in this cluster is unity_ci_library_cache_receipt_v1.
BUILD_RECEIPT columns
| Column | Example |
|---|---|
library_cache_bust_ok |
true |
unity_ci_library_cache_receipt_path |
release-evidence/unity/ci-cache/UNITY_CI_LIBRARY_CACHE_RECEIPT.json |
addressables_content_state_sha256 |
b7e2c4f1… |
Lesson 261 wires promotion gates; Lesson 268 forward covers concurrency: cancel-in-progress cousin lane (distinct from cache key bust).
C5 — Fail-closed jq (CI tail)
jq -e '.library_cache_bust_ok == true' release-evidence/unity/ci-cache/UNITY_CI_LIBRARY_CACHE_RECEIPT.json
Block merge to fest branch when receipt missing or false—pair Thursday row review column library_cache_bust_ok.
Developer path — strip week order
| Step | Artifact | Owner |
|---|---|---|
| 1 | K1 address_inventory_v1.json |
7-day challenge |
| 2 | jq has("groups") pass |
jq preflight |
| 3 | Cache key + clean job | This evening |
| 4 | Strip PR merge | Engineering |
| 5 | Wednesday smoke | Producer |
| 6 | Thursday row diff | Release owner |
Do not delete jq guards to silence CI—fix inventory (jq preflight J5).
Relationship to challenge vs help vs 3-day challenge forward
| Artifact | Role |
|---|---|
| This tutorial | One-evening cache bust + receipt |
| 7-day challenge | K1–K7 calendar |
| Library cache preflight | Ninety-second C1–C6 |
| Invalid Key help | Runtime triage |
| Help #26 forward | Stale Library fix lane |
| Blog #17 | 3-day no false green challenge — three-day ladder sibling |
Common mistakes
- Cache key = branch name only (C2 fail).
- Restoring
Library/after deleting groups without busting key. - Green CI + skipping player smoke — "it compiled" is not fest truth.
concurrency: cancel-in-progressmid-Addressables build poisoningLibrary/— cousin Help #30 / Lesson 268 lane.- Mixing smoke profile — CI builds Development, smoke tests Release without documenting delta.
- Promoting with visible label mismatch — player-visible build label must match receipt
build_label. - Filing receipt before CI run — hash must come from observed workflow log.
Troubleshooting
| Symptom | Lane |
|---|---|
| CI green, InvalidKey in player | C2 bust + C3 clean Library/ |
| Cache always miss (slow CI) | Narrow restore-keys; keep ContentState in primary key |
| ContentState missing in CI | Run Addressables build before hash step |
| Intermittent fails after cancel | Help #30 concurrency + Library/ corruption |
| Inventory jq OK, still stale | C4 Temp/ + verify smoke profile matches CI |
BUILD_RECEIPT library_cache_bust_ok false |
Re-run clean job; re-hash ContentState |
Worked example — Tuesday group move to Wednesday promote
Scenario: You moved DLC_Audio Addressables group to Remote on Tuesday. CI badge green Wednesday 9 a.m. Player smoke fails InvalidKeyException on audio/ambience_01.
| Step | What you do | Expected result |
|---|---|---|
| 1 | Export K1 inventory after merge | address_inventory_v1.json shows group change |
| 2 | Run jq preflight | has("groups") pass |
| 3 | Trigger clean-library-on-group-move |
Workflow run deletes Library/ + Temp/ |
| 4 | Re-run Addressables CI job | New AddressablesContentState hash in logs |
| 5 | Verify cache key changed | GitHub Actions cache miss or new key suffix |
| 6 | File unity_ci_library_cache_receipt_v1.json |
library_cache_bust_ok: true |
| 7 | Wednesday smoke | S4–S6 GREEN on same build_label |
| 8 | Thursday row review | library_cache_bust_ok matches receipt |
Lesson learned: Green CI before step 3 only proved compile against stale catalog—not player-load truth.
Discord stand-up one-liner (copy/paste)
Tuesday strip merged — triggered
clean-library-on-group-move, ContentState hashb7e2…,library_cache_bust_ok=true, smoke Wednesday PM before promote.
Proof table (producer audit)
| Row | Evidence | Pass |
|---|---|---|
| ContentState path | C1 log line | File exists post-build |
| Cache key YAML | C2 snippet in repo | Hash in key: |
| Clean job ran | C3 workflow run URL | After group move |
| Temp cleared | C4 step in workflow | Present on player job |
| jq gate | C5 CI log | Exit 0 |
| Receipt filed | C6 path on disk | library_cache_bust_ok: true |
Seven scenarios (A–G)
| ID | Situation | Correct response |
|---|---|---|
| A | First time caching Library/ |
Implement C2 before enabling restore |
| B | Tuesday group move | Trigger C3 clean job before Wednesday promote |
| C | ContentState missing in CI |
Fail workflow; build Addressables first |
| D | Smoke RED, CI GREEN | Cache bust lane—not store copy |
| E | Contractor changed groups without inventory | Run K1 export before C3 |
| F | Receipt true, smoke false | Binary/regression lane—do not blame cache only |
| G | Skipped receipt, promoted anyway | Roll back; file C6 before retry |
Folder layout
release-evidence/unity/ci-cache/
README.md
UNITY_CI_LIBRARY_CACHE_RECEIPT.json
.github/workflows/
unity-addressables-ci.yml # cache key + clean job
Tools and sibling reads
- 15-free GitHub Actions CI recipes
- Invalid Key runtime help
- String Tables empty help
- Localization_Local preflight
- Tuesday CSV ingest — parallel Tuesday ops lane
- Official: actions/cache, Unity Addressables docs
Key takeaways
AddressablesContentStatehash belongs in the cache key—not optional for fest months.- One evening wires hash step, clean job, receipt, and BUILD_RECEIPT column.
- Branch-only cache keys lie after group moves on the same branch.
- Manual clean job after group moves beats debugging player-only failures.
- Fail-closed
library_cache_bust_okbefore fest branch promotion. - Run jq preflight before cache bust on strip weeks.
- 7-day challenge owns calendar; this tutorial owns evening CI cache material.
- Wednesday smoke still required—cache receipt ≠ binary proof.
- Guide preflight holds ninety-second C1–C6; this post holds beginner evening blocks.
- Forward #17 three-day challenge when you need sustained false-green discipline.
FAQ
Can we disable actions/cache entirely?
Yes for strip months—but slow CI hurts iteration. ContentState hash is the balanced fix.
Does this fix wrong addresses in groups?
No—run 7-day audit for inventory; cache bust only prevents stale builds.
Godot or Unreal?
This tutorial is Unity 6 Addressables-specific; Godot export caches are a different cluster.
What if we use Unity Cloud Build instead of GitHub Actions?
Same policy: cache key must include catalog/content state fingerprint—adapt receipt fields to UCB job IDs.
How does this relate to Lesson 261?
Lesson 261 promotes unity_ci_library_cache_receipt into BUILD_RECEIPT gates—run this evening tutorial first.
Is addressables_ci_cache_receipt_v1 different?
Planner alias—use unity_ci_library_cache_receipt_v1 schema in this cluster.
Conclusion
October CI lies when Library/ cache outlives Addressables group moves. One evening: hash AddressablesContentState, fix the cache key, link a clean job, file the receipt, set library_cache_bust_ok—then run Wednesday smoke on honest binary truth.
Next reads: Library cache preflight (Guide), 7-day Addressables audit, Lesson 261, Wednesday demo smoke, Invalid Key help.
Found this useful? Pin the cache key YAML beside your Addressables group move checklist before October strip week—not after the first false-green fest promote.