186 lines
7.9 KiB
Markdown
186 lines
7.9 KiB
Markdown
# 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 <version>` 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-<version>.x86_64`
|
||
- `build/gig-line-windows-<version>.exe`
|
||
- `build/gig-line-macos-<version>.zip`
|
||
- `build/gig-line-web-<version>.zip` — browser build (non-threaded Godot web
|
||
template; unzip and serve the folder, no COOP/COEP headers required)
|
||
- `build/gig-line-desktop-hq-<version>.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-<version>.exe` — Windows installer (NSIS, incl. shortcuts +
|
||
uninstaller; apt `nsis` on the runner)
|
||
- `build/gig-line-<version>-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.
|
||
|
||
Always run the release build from a clean checkout or detached worktree. Godot
|
||
can pack files from ignored `tmp/` and old `build/` folders into the PCK; the
|
||
0.9.6 dirty-tree build produced 1.6–3.1 GB artifacts, while the clean worktree
|
||
produced the expected ~160–240 MB packages.
|
||
|
||
Locally you can build the AppImage with `bash packaging/linux/build_appimage.sh <version>`;
|
||
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<version>`.
|
||
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.
|