Lesson 269: Godot Export VDF LF Line Ending steamcmd Receipt on BUILD_RECEIPT (2026)
Direct answer: Before November 2026 fest Linux steamcmd upload week, promote vdf_line_ending_receipt_v1.json with V1–V6 gates—prove app_build_*.vdf is LF-only on the Linux CI runner with file + hexdump, pin .gitattributes* `.vdf text eol=lf`, capture a dry-run parse log without ERROR! App build file, and fail-close vdf_lf_ok** on BUILD_RECEIPT. Pair VDF LF preflight (Guide #31), Godot VDF LF evening tutorial, and cousin Lesson 268 (Unity cancel poison—not Godot VDF bytes).

Why this matters now (November Godot Linux CI parse)
November 2026 Godot 4.5 teams export app_build_*.vdf on Windows, pass Steamworks UI validation, then watch ubuntu-latest steamcmd die with ERROR! App build file before queue telemetry even starts. Lesson 268 wires Unity cancel boundaries; 269 wires VDF line endings on BUILD_RECEIPT before Wednesday smoke and setlive dry-run when multi-engine.
C# AOT depot size preflight owns byte trim; 269 owns LF proof and parse dry-run on BUILD_RECEIPT. SteamPipe wall-clock trend applies after successful parse—do not route CRLF failures there.
Beginner path (prove LF → policy → receipt)
| Step | Action | Success check |
|---|---|---|
| 1 | Locate app_build_*.vdf after Godot export |
V1 path exists on CI |
| 2 | Run file + hexdump on Linux runner |
No CRLF line terminators |
| 3 | Add .gitattributes *.vdf text eol=lf |
V3 merged on fest branch |
| 4 | Linux steamcmd dry-run parse |
V4 log has no parse error |
| 5 | Wire fail-closed jq before merge | V5 vdf_lf_ok true |
| 6 | File receipt + BUILD_RECEIPT column | steam_upload_promotion_allowed |
Time: ~50 minutes first VDF path pin; ~12 minutes per hotfix when .gitattributes exists.
Developer path (gates V1–V6)
| Gate | Check | Fail when |
|---|---|---|
| V1 | app_build_*.vdf at documented CI path |
Missing after export step |
| V2 | file shows LF-only |
CRLF line terminators in output |
| V3 | .gitattributes contains *.vdf text eol=lf |
Rule absent on fest branch |
| V4 | Linux steamcmd dry-run log |
ERROR! App build file line present |
| V5 | Fail-closed promotion jq | Merge when vdf_lf_ok false |
| V6 | vdf_line_ending_receipt_v1.json |
vdf_lf_ok false at promote |
Align with Guide #31 preflight—guide = ninety-second gate; 269 = BUILD_RECEIPT milestone with promotion jq.
Cousin receipt crosswalk
| Field | Cousin (evening tutorial) | Cousin (Guide #31) | This lesson (269) |
|---|---|---|---|
| Schema | blocks A–D evening path | ninety-second V1–V6 | vdf_line_ending_receipt_v1 |
| Scope | First-evening LF proof | Editor/CI preflight | BUILD_RECEIPT promotion column |
| Path | release-evidence/steam/vdf-lf/ |
same evidence folder | release-evidence/steam/vdf-lf/ |
Do not merge schemas with GameMaker setlive receipt forward—reference paths in cousin_receipts only.
V1 — Locate VDF after Godot export
VDF="build/steam/app_build_1234560.vdf"
test -f "$VDF"
Log path + export preset name in receipt app_build_vdf_path. Pin once in release-evidence/steam/vdf-lf/README.md.
V2 — file + hexdump proof (Linux runner only)
file "$VDF" | tee vdf_file_proof.txt
hexdump -C "$VDF" | head -n 5 | tee vdf_hex_head.txt
if file "$VDF" | grep -q CRLF; then
echo "V2 fail: CRLF detected"
exit 1
fi
CRLF smoking gun: 0d 0a at line ends instead of 0a alone.
One-shot fix:
dos2unix "$VDF"
file "$VDF"
Rule: Run V2 on the same runner that executes steamcmd—not a Windows path copy.
V3 — .gitattributes policy
# Steam VDF must be LF for Linux steamcmd (Godot 4.5 CI)
*.vdf text eol=lf
After adding:
git add --renormalize .
Pair 12 setlive preflight checks check 6—partner identity is separate from LF.
V4 — Linux steamcmd dry-run (parse only)
steamcmd +login "$STEAM_PARTNER_USER" "$STEAM_PARTNER_PASS" \
+run_app_build build/steam/app_build_1234560.vdf \
+quit 2>&1 | tee release-evidence/steam/vdf-lf/build_app_dry_run.log
V4 pass: no ERROR! App build file.
V4 fail: return to V2/V3—do not open wall-clock trend playbook.
Auth vs parse vs queue (quick route)
| Log signal | Lane |
|---|---|
Invalid Password |
Partner login / SteamGuard — GameMaker partner Lesson 262 cousin |
ERROR! App build file |
This lesson (LF/parse) |
OK then long idle |
Wall-clock trend |
DepotOwnedByOtherAccount |
Partner sanity preflight |
V5 — Fail-closed promotion jq (CI tail)
jq -e '.vdf_lf_ok == true' release-evidence/steam/vdf-lf/VDF_LINE_ENDING_RECEIPT.json
Block merge to fest branch when receipt missing after any VDF hotfix week—pair Thursday BUILD_RECEIPT review column vdf_lf_ok.
V6 — vdf_line_ending_receipt_v1.json
{
"schema": "vdf_line_ending_receipt_v1",
"build_label": "november-closeout-2026-rc2",
"engine": "godot_4.5",
"app_build_vdf_path": "build/steam/app_build_1234560.vdf",
"file_proof_output": "ASCII text",
"gitattributes_vdf_rule": "*.vdf text eol=lf",
"dry_run_log": "release-evidence/steam/vdf-lf/build_app_dry_run.log",
"cousin_receipts": {
"depot_size": "release-evidence/godot/depot-size/DEPOT_SIZE_RECEIPT.json",
"ci_cancel": "release-evidence/unity/ci-cancel/CI_CANCEL_SAFE_RECEIPT.json"
},
"gates": {
"V1_vdf_exists": "pass",
"V2_lf_only": "pass",
"V3_gitattributes": "pass",
"V4_dry_run_parse": "pass",
"V5_fail_closed": "pass",
"V6_receipt": "pass"
},
"vdf_lf_ok": true,
"steam_upload_promotion_allowed": true
}
Pin under release-evidence/steam/vdf-lf/VDF_LINE_ENDING_RECEIPT.json.
BUILD_RECEIPT columns (November lane)
| Column | Source | Pass when |
|---|---|---|
vdf_lf_ok |
V5 jq | true |
steam_upload_promotion_allowed |
V6 receipt | true |
ci_cancel_safe_ok |
Lesson 268 cousin | true when Unity lane active |
wednesday_smoke_allowed |
Lesson 267 cousin | true |
Key takeaways
fileon Linux runner—CRLF is invisible in many Windows editors.- *
.gitattributes`.vdf text eol=lf**—repo policy beats manualdos2unix` every hotfix. - Dry-run parse before upload week—separate from queue telemetry.
- Run evening VDF LF tutorial before this milestone if team never proved LF.
- Guide #31 preflight owns ninety-second gate; 269 owns BUILD_RECEIPT promotion.
- Help #31 forward owns traceback-first CRLF fix when V2 already failed in CI.
- 15-free GitHub Actions CI recipes bookmark workflow graphs—VDF LF material is separate column.
- Cousin C# depot size preflight owns bytes—not line endings.
Common mistakes
- Assuming Steamworks UI validates LF on disk (V2 still required).
- Editing VDF in Notepad on Windows without
dos2unixin CI (V2 fail). - Running
fileon Windows path while CI uses Linux copy (V2 must match runner). - Blaming Steam queue when log shows parse error (V4 routing).
- Promoting without V6 receipt after Friday VDF hotfix.
- Merging
vdf_line_ending_receiptwithgm_steam_setlive_dry_run_receiptschemas.
Troubleshooting
| Symptom | Lane |
|---|---|
ERROR! App build file on Linux only |
V2 dos2unix + V3 .gitattributes |
| CRLF returns after merge | git add --renormalize; check editor EOL |
| Dry-run OK on Windows, fail on Linux | V2 on ubuntu runner only |
| Parse OK, upload idle hours | Wall-clock trend |
| Help #31 fix applied, CRLF recurs | V3 missing or overridden locally |
Mini exercise (50 minutes)
- Export Godot preset—log V1 path in README.
- Inject CRLF once—confirm V2
filecatches it. - Add V3
.gitattributesPR withgit add --renormalize. - Capture V4 dry-run log on Linux runner.
- Wire V5 jq gate in workflow tail.
- File receipt; BUILD_RECEIPT GREEN for
vdf_lf_ok.
Continuity — November 2026 fest close-out + playtest triage (266–276)
| Lesson | Receipt focus |
|---|---|
| 268 | Unity CI cancel poison |
| 269 (this) | Godot VDF LF |
| 270 | GameMaker setlive dry-run |
Previous: Lesson 268 — Unity CI concurrency cancel Library poison receipt
Next: Lesson 270 — GameMaker Steam setlive branch dry-run receipt
FAQ
Same as evening tutorial?
Evening owns blocks A–D first path; 269 owns vdf_line_ending_receipt_v1 BUILD_RECEIPT column + V5 jq.
Same as Guide #31?
Guide = ninety-second preflight; 269 = course milestone with promotion jq + cousin crosswalk.
Same as Help #31 when it ships?
Help = traceback-first CRLF fix; 269 prevents promotion without V1–V6.
Same as Resource #29 when it ships?
Bookmark list for dos2unix / file tools—use the now-live SteamPipe observability list for parse-versus-queue routing until Resource #29 refresh expands its VDF rows.
Same as 12 setlive checks?
Checklist owns partner + branch discipline; 269 owns LF proof on disk.
Does this replace Wednesday smoke?
No—binary smoke is separate; 269 stops false-green VDF before upload week.
Does this replace Lesson 268?
No—268 = Unity cancel; 269 = Godot VDF LF. Multi-engine studios file both.
Linux steamcmd lies when Windows CRLF hides in VDF—prove LF with file, pin .gitattributes, dry-run parse, fail-closed vdf_lf_ok, then promote.