# Releasing Gig Line This guide describes how to produce downloadable executables and publish them so the README "Downloads" links always point at the latest release. ## 1. Install export templates Godot needs platform export templates to build standalone binaries. The first time you export, either: - Open the editor and use **Editor → Manage Export Templates** (downloads the matching templates), or - Install them manually from the [Godot downloads](https://godotengine.org/download/) page by placing the `Godot_v4.7.2-stable_export_templates.tpz` contents into `~/.local/share/godot/export_templates/4.7.2.stable/`. The templates must match the editor binary you use locally. CI and local development both use Godot 4.7.2 with its matching templates. Verify with: ```bash godot --headless --export-release "Linux" build/gig-line-smoke.x86_64 ``` ## 2. Bump the version `project.godot` sets `config/version`. Keep it in sync with the release tag (e.g. `v0.3.0` → `config/version="0.3.0"`, plus a git tag `v0.3.0`). ## 3. CI (Gitea Actions) The repository ships a Gitea Actions workflow (`.gitea/workflows/build.yml`): - Every push/PR runs the **checks** job: Godot 4.7.2 install, project import, and the full headless test suite. This is the fast safety net. - **Tags (`v*`)** and **manual `workflow_dispatch`** runs additionally execute the **build** job: export templates install, import, `tools/build_releases.sh` for Linux/Windows/macOS, artifact upload, and — on tags — release publication via `tools/publish_release.sh`. `tools/publish_release.sh` picks the first available credential, in order: 1. `GITEA_TOKEN` (repo secret, write:repository scope), 2. `GITEA_AUTH_HEADER` (a ready-made `Authorization: ...` header), 3. `~/.git-credentials` for the host, 4. the **local git extraheader** that `actions/checkout` configures on the CI job. Option 4 is what makes tag builds publish without any repo secret: the runner already injects basic-auth credentials for the checkout, and the script reuses that header for the API (same server). `github.token` is *not* available in this Gitea setup, so do not rely on it. > **Disk space:** Gitea stores release assets under `/var/lib/gitea/data/attachments` on > the host root filesystem (7.8 GB here). When it is full, asset uploads fail with > `HTTP 500 … no space left on device` and even `git push` can fail with "unpacker error". > `publish_release.sh` now verifies the asset count and exits non-zero, so this is visible. > > **Incident (2026-10-31):** `tools/publish_release.sh` never set `AUTH` in its > `~/.git-credentials` branch, so every API call failed silently (`AUTH[@]` was > unbound under `set -u`). Combined with no `GITEA_TOKEN` secret on the repo, tag > builds from v0.2.2 to v0.2.8 produced installers but published nothing. The script > is fixed (`AUTH=(-u "$CRED")`) and v0.2.9 was published locally with all five > artifacts. If CI publishing fails again, run > `./tools/publish_release.sh ` from a checkout with `~/.git-credentials`. > **Godot cache evaluation:** Gitea Actions cache was tested for the Godot binary and > trimmed 4.7.2 templates. Restores worked intermittently, but cache saves timed out > in `CreateCacheEntry` / were rejected as reserved by another job. The cache steps > were removed because they added restore/save overhead without a reliable hit. > Revisit when the host's Gitea Actions cache service is healthy; otherwise keep > downloading the binary/templates directly. > The workflow lives in `.gitea/workflows/` (Gitea's canonical path). The old > `.github/workflows/ci.yml` was removed to avoid double runs on hosts that scan > both directories. ## 4. Local build (alternative to CI) ```bash godot --headless --path . --script res://src/test/test_runner.gd # all tests godot --headless --path . --quit-after 120 # boot smoke test ./tools/build_releases.sh ``` Artifacts are written to `build/` (all exports embed the PCK — single files): - `build/gig-line-linux-.x86_64` - `build/gig-line-windows-.exe` - `build/gig-line-macos-.zip` - `build/gig-line-web-.zip` — browser build (non-threaded Godot web template; unzip and serve the folder, no COOP/COEP headers required) - `build/gig-line-desktop-hq-.zip` — optional Forward+ Windows/Linux build with `override.cfg`; requires a Vulkan-capable GPU/driver When run in CI (tags/dispatch), the build job also packages: - `build/gig-line-setup-.exe` — Windows installer (NSIS, incl. shortcuts + uninstaller; apt `nsis` on the runner) - `build/gig-line--x86_64.AppImage` — Linux AppImage (`packaging/linux/build_appimage.sh`, appimagetool via `APPIMAGE_EXTRACT_AND_RUN`) The optional Desktop HQ zip is assembled by `tools/build_releases.sh` from `packaging/desktop_hq/`; keep `override.cfg` next to the extracted executable. It is not part of the default Compatibility/Web build. Locally you can build the AppImage with `bash packaging/linux/build_appimage.sh `; the NSIS installer requires `makensis` (covered by CI). > macOS builds are unsigned and will need `xattr -dr com.apple.quarantine` > guidance or notarization for production releases. ## 5. Publish on the repository host (Gitea/Forgejo) The repository lives at `https://git.allucanget.biz/zwitschi/security-game`. Preferred path — use the helper script. It needs either a token or the same credentials used by `git push` (it falls back to `~/.git-credentials`): ```bash GITEA_TOKEN=your_api_token ./tools/publish_release.sh 0.2.1 # or simply: ./tools/publish_release.sh 0.2.1 (uses ~/.git-credentials) ``` The script creates (or reuses) the release from `project.godot`'s `config/version`, uploads the three portable artifacts **plus** the NSIS installer, AppImage, Web zip and Desktop HQ zip when present, and prints the release URL. If CI already published the release, re-running the script only adds missing assets. > **Host note**: the release is fully built by CI, but anonymous users can only > browse and download when the instance sets `[service] REQUIRE_SIGNIN_VIEW=false` > in `app.ini` (the repo itself is public). This is a host-admin setting, not a > repository file. Manual alternative: ### Via the web UI 1. Create a **New Release** with tag `v`. 2. Attach all artifacts from `build/` (portables, installer/AppImage, Web and optional Desktop HQ). 3. Write release notes (see checklist below). ### Via the API ```bash TOKEN="your_api_token" REPO="zwitschi/security-game" VERSION="0.3.0" API="https://git.allucanget.biz/api/v1/repos/$REPO/releases" # Create the release RELEASE_JSON=$(curl -s -X POST "$API" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"tag_name\":\"v$VERSION\",\"name\":\"v$VERSION\",\"body\":\"Playable prototype release.\"}") RELEASE_ID=$(echo "$RELEASE_JSON" | python3 -c "import sys,json;print(json.load(sys.stdin)['id'])") for f in build/gig-line-*"$VERSION"*; do curl -s -X POST "$API/$RELEASE_ID/assets" \ -H "Authorization: token $TOKEN" \ -F "attachment=@$f" done ``` ## 6. Update the README The **Downloads** section links to the host releases page (`https://git.allucanget.biz/zwitschi/security-game/releases`), so no README edit is needed when the page follows the naming pattern. If artifact names change, update `tools/build_releases.sh` first. ## Release notes checklist - [ ] All headless tests pass (exit code 0). - [ ] Game boots cleanly in a smoke test. - [ ] Controls documented in `docs/getting-started.md` match the build. - [ ] Version in `project.godot` matches the tag. - [ ] Export templates used are the official ones for the pinned engine. - [ ] Artifacts uploaded; README downloads page shows them.