diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 4ecbb124..25368eed 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -293,36 +293,8 @@ jobs: run: | set -euo pipefail notes_file=".local/release-staging/RELEASE_NOTES.md" - changelog=".project/CHANGELOG.md" - if [ ! -f "$changelog" ]; then - # TODO(release-notes): CHANGELOG doesn't exist — emit a placeholder - # instead of failing. When CHANGELOG is authored, this branch - # will never be taken. - printf 'Release %s\n\n(no CHANGELOG.md present at release time)\n' \ - "${{ steps.version.outputs.version }}" > "$notes_file" - else - # Find the range in CHANGELOG between the previous tag and HEAD. - # CLAUDE.md spec: CHANGELOG entries are newest-at-bottom, date-prefixed. - prev_tag="$(git describe --tags --abbrev=0 "${GITHUB_REF_NAME}^" 2>/dev/null || true)" - { - echo "# Magic Civilization ${{ steps.version.outputs.version }}" - echo - if [ -n "$prev_tag" ]; then - echo "_Changes since ${prev_tag}:_" - echo - # Diff the CHANGELOG between the two tags; lines added since - # the previous tag are the new release notes. - git diff "${prev_tag}..${GITHUB_REF_NAME}" -- "$changelog" \ - | grep -E '^\+[^+]' \ - | sed 's/^\+//' \ - || echo "(no new CHANGELOG entries between ${prev_tag} and ${GITHUB_REF_NAME})" - else - echo "_First tagged release; full CHANGELOG below:_" - echo - cat "$changelog" - fi - } > "$notes_file" - fi + mkdir -p "$(dirname "$notes_file")" + bash tools/release-notes.sh "$GITHUB_REF_NAME" > "$notes_file" echo "notes_file=$notes_file" >> "$GITHUB_OUTPUT" - name: Collect release assets diff --git a/.project/history/20260417_export_pipeline_audit.md b/.project/history/20260417_export_pipeline_audit.md new file mode 100644 index 00000000..0f0931d0 --- /dev/null +++ b/.project/history/20260417_export_pipeline_audit.md @@ -0,0 +1,88 @@ +# p2-06 export-pipeline audit — 2026-04-17 + +Scope: verify the `./run export` chain per the objective's five acceptance +bullets. Work was done from the EDIT host; all Godot export invocations +were shelled out to the apricot RUN host per the CLAUDE.md Two-Host +Workflow. No compiled `.so`/`.dylib`/`.dll` binaries were rsynced EDIT→RUN +(CLAUDE.md safety invariant). + +## What already existed + +- `src/game/export_presets.cfg` (229 lines) with three desktop presets: + `Linux/X11`, `macOS`, `Windows Desktop`. Android/iOS presets were + intentionally left out — they require per-dev keystore/team-id config. +- `tools/export.sh` — orchestrator; fans out to `tools/export-single.sh` + per platform in parallel, writes logs under + `.local/build/godot//logs/`, exits 0 iff every platform wins. +- `tools/export-single.sh` — lowest-level per-platform export; resolves + preset + artifact path, probes for a usable Godot binary (prefers + `$GODOT_BIN`, falls back to `godot` CLI, then Flatpak), writes to + `.local/build/godot///`. +- `scripts/run/export.sh` — glue that wires `./run export [version]` + to `tools/export.sh`, and `./run export:` to + `tools/export-single.sh`. +- `.forgejo/workflows/release.yml` — full Forgejo Actions pipeline that + fires on `v*` tag push. Authors one job each for + `linux_build` / `macos_build` / `windows_build` / `wasm_build`, a final + `release` job that downloads all four artifacts, runs + `tools/release-notes.sh` to generate notes from CHANGELOG, and uploads + via the Forgejo release API. +- `.forgejo/RUNNER_SETUP.md` — runner registration + systemd notes. + +## Empirical verification on apricot + + ssh lilith@apricot.local 'cd ~/Code/@projects/@magic-civilization \ + && bash tools/export-single.sh linux p2-06-audit' + +Result: produced +`.local/build/godot/p2-06-audit/linux/MagicCivilization.x86_64` (29MB +payload, 71MB sparse). Flatpak Godot 4.6.2.stable is installed; export +templates for 4.6.2.stable resolve. No error exit. + +Two `.pck-XXXXXX` temp files were left behind — this is a Godot +atomic-rename artifact caused by a concurrent `--import` running from a +parallel test session on the same repo. Not a bug in the export chain +itself; the exported binary is valid. + +## Gaps found + fixed this pass + +1. **`.gdextension` manifest missing `windows.x86_64.debug` entry.** + Only `windows.x86_64.release` was listed, which would cause the Godot + debug export to fail to resolve the native library on Windows targets. + Fixed in `src/game/engine/addons/magic_civ_physics/magic_civ_physics.gdextension`. + +2. **Release-notes generation lived only inline in the forgejo workflow.** + Extracted to `tools/release-notes.sh` so developers can preview what + a release body will contain before pushing a tag: + tools/release-notes.sh v0.2.0 + The forgejo workflow now shells out to this script (one line, the + previous 28-line inline heredoc deleted). + +## Gaps still open (out of this pass's budget) + +- **Windows `.dll` not present in the repo.** Cross-compiling from a + Linux or macOS EDIT host would need `x86_64-pc-windows-msvc` toolchain + + WINE. The release pipeline's `windows_build` job handles this + correctly (registers a windows runner), but `./run export:windows` + from the EDIT host today cannot produce a shippable archive. The + objective's acceptance bullet 3 ("GDExtension binaries are per-platform + … never cross-shipped") is satisfied by the release pipeline; the + local dev path is aspirational. +- **Unattended end-to-end smoke of a fresh release archive.** Bullet 2 + ("unpacked and run … plays a seeded 10-turn game without errors") is + authored as logic but was not run this pass. The apricot linux binary + has never been installed + launched headless for a 10-turn autoplay + under p2-06-audit-version; that's the natural next verification step. +- **WASM bundling in the local `./run export`.** The forgejo `wasm_build` + job covers WASM. `./run export` does not build WASM as part of the + all-platforms fan-out; bullet 4 ("WASM guide build is a separate + artifact in the same release bundle") is satisfied by the release + pipeline but not by the local dev path. + +## Status call + +Moving from `partial` → `partial` (no status change). The release +pipeline is substantially more complete than the objective frontmatter +suggested; the local `./run export` chain is the remaining work. Keeping +the objective at `partial` with richer evidence prevents a premature +`done` flip that would violate the Objective Status Integrity rule. diff --git a/.project/objectives/README.md b/.project/objectives/README.md index d7477d81..94adce05 100644 --- a/.project/objectives/README.md +++ b/.project/objectives/README.md @@ -66,7 +66,7 @@ | [p2-03](p2-03-hotkey-cheat-sheet.md) | ❌ missing | Hotkey cheat sheet (F1 / ?) | — | 2026-04-17 | | [p2-04](p2-04-localization-audit.md) | 🟡 partial | Localization audit — no hardcoded strings | — | 2026-04-17 | | [p2-05](p2-05-turn-latency.md) | 🟡 partial | Sub-second single-player turn latency | — | 2026-04-17 | -| [p2-06](p2-06-export-pipeline.md) | 🟡 partial | Export pipeline for Windows / macOS / Linux | — | 2026-04-17 | +| [p2-06](p2-06-export-pipeline.md) | 🟡 partial | Export pipeline for Windows / macOS / Linux | [shipwright](../team-leads/shipwright.md) | 2026-04-17 | | [p2-07](p2-07-credits-screen.md) | ✅ done | Credits screen accessible from main menu | [shipwright](../team-leads/shipwright.md) | 2026-04-17 | | [p2-08](p2-08-accessibility.md) | ❌ missing | Accessibility baseline — colorblind palette + keyboard navigation | — | 2026-04-17 | | [p2-09](p2-09-guide-web-deploy.md) | 🟡 partial | Player guide web app — deployed and up to date | — | 2026-04-17 | diff --git a/.project/objectives/p2-06-export-pipeline.md b/.project/objectives/p2-06-export-pipeline.md index 446f6485..b389db46 100644 --- a/.project/objectives/p2-06-export-pipeline.md +++ b/.project/objectives/p2-06-export-pipeline.md @@ -4,17 +4,32 @@ title: Export pipeline for Windows / macOS / Linux priority: p2 status: partial scope: game1 +owner: shipwright updated_at: 2026-04-17 evidence: - src/game/export_presets.cfg + - src/game/engine/addons/magic_civ_physics/magic_civ_physics.gdextension + - scripts/run/export.sh - scripts/run/remote.sh + - tools/export.sh + - tools/export-single.sh + - tools/release-notes.sh - .forgejo/workflows/release.yml - .forgejo/RUNNER_SETUP.md + - .project/history/20260417_export_pipeline_audit.md +acceptance_audit: + run_export_per_platform: "✓ — scripts/run/export.sh → tools/export.sh fans out to tools/export-single.sh per platform. Verified empirically on apricot: bash tools/export-single.sh linux p2-06-audit produced .local/build/godot/p2-06-audit/linux/MagicCivilization.x86_64 (29MB)." + archive_boots_and_plays: "✗ — the 10-turn seeded-game smoke from a freshly exported archive has not been wired. Authored as logic in the release pipeline, unverified end-to-end. Next verification: install:linux on a clean apricot + autoplay-batch 1 seed T10 against the installed binary." + per_platform_gdext_bundling: "⚠ — .gdextension manifest lists all three desktop libraries (linux .so, macos .dylib, windows .dll). Windows debug entry was missing until this pass (added). Windows .dll does not yet live in the repo; the release pipeline's windows_build job produces it on a registered windows runner, but ./run export:windows from a non-windows EDIT host cannot complete." + wasm_in_release_bundle: "✓ — .forgejo/workflows/release.yml wasm_build job runs bash build-wasm.sh + pnpm build of the guide, packages pkg/ + guide/dist/ into magic-civilization--wasm.tar.gz. Not wired into ./run export — that path remains desktop-only." + release_notes_from_changelog: "✓ — tools/release-notes.sh extracts added CHANGELOG lines between the prior tag and the current tag via git diff. Smoke-tested from the EDIT host: tools/release-notes.sh v9.9.9-preview → first-release path. release.yml shells out to this script." --- ## Summary -Players need binaries. Godot export presets exist; the pipeline must produce shippable archives for Windows, macOS, and Linux with the GDExtension correctly bundled per platform. +Players need binaries. Godot export presets (desktop: Linux/X11, macOS, Windows Desktop) are authored; the `./run export` chain produces per-platform archives via `tools/export.sh` + `tools/export-single.sh`, and the `.forgejo/workflows/release.yml` tag-push pipeline bundles Linux + macOS + Windows + WASM-guide archives into a Forgejo release with release notes generated from the CHANGELOG diff. + +Open work: (1) Windows `.dll` production only happens on a registered windows runner — local `./run export:windows` from a macOS/Linux EDIT host does not yet cross-compile. (2) The boots-and-plays end-to-end smoke has not been run against a fresh export archive. Both are blockers before flipping to `done`. ## Acceptance