Files
Vaillant Jeremy 4f9fa60fa0
Build Puzzle Quest / Lint GDScript (push) Successful in 29s
Build Puzzle Quest / Validate GDScript (push) Successful in 35s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 39s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 23s
Build Puzzle Quest / Export Linux (push) Successful in 6m32s
Build Puzzle Quest / Export Windows (push) Successful in 6m44s
Build Puzzle Quest / Export Android (push) Successful in 7m41s
Build Puzzle Quest / Export Windows (pull_request) Successful in 5m30s
Build Puzzle Quest / Export Linux (pull_request) Successful in 6m10s
Build Puzzle Quest / Export Android (pull_request) Successful in 6m48s
ci(android): explicit apksigner step after Godot export
Godot 4.6 produces an unsigned APK in headless mode on this
runner — verified by apksigner: "DOES NOT VERIFY, Missing
META-INF/MANIFEST.MF". The internal sign step seems to bail
silently (likely because the apksigner subprocess can't locate
java without inheriting JAVA_HOME). The export step still
reports success.

Sign the APK ourselves after the export with the same debug
keystore the workflow provisions. Idempotent if Godot ever
starts signing again; mandatory until then.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:59:33 +02:00
..

Gitea Actions CI

Workflow defined in build.yml. Triggered on push / PR to dev and main, or manually via workflow_dispatch.

Jobs

All jobs run on the default ubuntu-latest runner image (which already ships Node, Python, git, wget, unzip, etc.). Godot is installed per-job via the local composite action .gitea/actions/setup-godot, which downloads the official Linux binary from the godotengine GitHub release and (optionally) export templates into $HOME.

Job Tooling installed by the job Role
validate Godot binary (no templates) godot --headless --import then grep for SCRIPT ERROR / Parse Error. Uploads .godot/ cache.
lint gdtoolkit==4.* via pip gdlint scripts db scenes. Parallel to validate; does not gate exports yet.
export-desktop Godot binary + export templates Matrix: Windows / Linux / macOS. Reuses the import cache, uploads each binary as artifact.
export-android Godot binary + export templates + JDK 17 + Android SDK (under $GITHUB_WORKSPACE/.android-sdk) Provisions keystore, writes editor_settings-4.tres with SDK / JDK paths, exports APK.

Artifacts are kept 14 days, accessible from the Gitea run page.

Prerequisites before the first successful run

  1. Godot versionGODOT_VERSION is set at the top of the workflow (currently 4.6). The setup action expects a stable release on the godotengine GitHub releases page; bump in lockstep with the project.
  2. macOS preset missing — add it in Godot Editor → Project → Export → Add → macOS, name it exactly macOS (or change the matrix entry). The .zip will be unsigned; on Mac it needs xattr -dr com.apple.quarantine to launch.
  3. Linux/X11Debug preset — Godot-3-era name. Reopen the project in Godot 4 once and re-save the preset (the editor may rename it). Update the matrix preset: field accordingly if it does.
  4. Gitea runneract_runner with the default catthehacker/ubuntu:act-latest image is enough; no Docker-in-Docker needed now that no job uses container:. The runner must reach github.com (for actions + Godot release downloads) and dl.google.com (for the Android SDK).
  5. Optional secret ANDROID_KEYSTORE_BASE64base64 -w0 debug.keystore, stored as a Gitea repo secret. Without it, a throwaway keystore is generated per run, so the APK signature changes every build.

Linting

gdlint (from Scony's gdtoolkit) runs in the lint job over scripts/, db/, and scenes/. addons/ (third-party LOD plugin) and developers/ (sandbox) are intentionally excluded.

The job is non-blocking today — the export jobs only depend on validate, so a lint failure prints warnings but still produces binaries. Once the codebase is clean, switch the export jobs' needs: validate to needs: [validate, lint] to make lint a hard gate.

Suppress specific rules per-line with # gdlint: disable=<rule> or project-wide with a gdlintrc file at the repo root (see gdtoolkit docs).

Known issues from first runs

Captured from the first triggered runs on feature/godot-migration (2026-05-17). Both must be resolved before the workflow can pass.

1. Container jobs failed with node: not found (resolved 2026-05-17)

The first runs used container: barichello/godot-ci:4.6 for the Godot jobs. That image does not ship Node.js, so actions/checkout@v4 (a JS action) crashed at startup with OCI runtime exec failed: exec: "node": executable file not found.

Resolved by removing every container: block. The runner's default catthehacker/ubuntu:act-latest image already has Node / Python / git / JDK, and Godot is now installed at the start of each job via the local composite action .gitea/actions/setup-godot/.

2. actions/checkout clones the wrong URL (resolved 2026-05-17)

The first runs failed at clone time because the runner asked for https://dev.stilobique.com/darknight/puzzle-quest/info/refs while Gitea was mounted under /gitea/ behind YunoHost — the request was intercepted by the YunoHost SSO at the root and redirected before reaching Gitea.

Resolved by relocating Gitea to the root: it now serves at https://dev.stilobique.com/ directly (API at /api/v1/..., clone_url at /<owner>/<repo>.git). The runner-injected GITHUB_SERVER_URL and the actual Gitea base URL now agree.

If Gitea is ever moved back under a sub-path, the fix is ROOT_URL in app.ini ([server] ROOT_URL = https://<host>/<prefix>/) or re-registering act_runner with the full instance URL.

3. Default-branch mismatch

The Gitea API reports default_branch: main for the repo, but CLAUDE.md describes dev as the default. The workflow listens to both, so jobs trigger correctly either way, but the "Workflows" sidebar in the Gitea UI reads from whatever the actual default branch is. If you intend dev to be the default, update it under repo Settings → Branches.

Differences from the old .drone.yml

  • No more Drone, no more Butler — build only, artifacts downloadable from the Gitea UI.
  • GDScript validation step before export (didn't exist).
  • .godot/ import cache shared between jobs (faster reruns).
  • Keystore via Gitea secret instead of a public pCloud link.
  • macOS target added (preset still to be created in Godot).
  • master / empty ReleaseVersion pipeline → replaced by triggers on main (release branch per CLAUDE.md).

Future: itch.io deploy via Butler

Not wired. When you want it back, add a deploy-itch job gated on tag push (v*) that downloads the artifacts and runs butler push <dir> dev-crea/ahog:<channel> with BUTLER_API_KEY from secrets. Channels used historically: windows, linux, android, mac.