Files
puzzle-quest/.gitea/workflows
Vaillant Jeremy 4e159b1065
Build Puzzle Quest / Lint GDScript (push) Successful in 33s
Build Puzzle Quest / Validate GDScript (pull_request) Successful in 33s
Build Puzzle Quest / Validate GDScript (push) Successful in 42s
Build Puzzle Quest / Lint GDScript (pull_request) Successful in 25s
Build Puzzle Quest / Export macOS (pull_request) Failing after 4m55s
Build Puzzle Quest / Export Linux (pull_request) Successful in 7m3s
Build Puzzle Quest / Export Windows (pull_request) Failing after 6m53s
Build Puzzle Quest / Export Android (pull_request) Failing after 6m16s
Build Puzzle Quest / Export macOS (push) Failing after 6m27s
Build Puzzle Quest / Export Linux (push) Successful in 6m44s
Build Puzzle Quest / Export Windows (push) Failing after 4m48s
Build Puzzle Quest / Export Android (push) Failing after 4m23s
ci: fix lint venv, drop artifact cache, fix Android sdkmanager pipe
Three follow-up fixes from the first non-container run (#10):

- lint: Ubuntu 24.04 / Python 3.12 enforces PEP 668, so
  `pip install --user` exits with externally-managed-environment.
  Install gdtoolkit into a throwaway venv at /tmp/gdlint-venv
  instead.

- exports: drop the .godot/ artifact cache shared between
  `validate` and the export jobs. Gitea's artifact service returns
  404 on actions/download-artifact@v3 (v3 protocol incomplete on
  this server). Each export job now runs its own
  `godot --headless --import` before exporting — costs ~30s but
  avoids the failing cross-job artifact dependency.

- export-android: `yes | sdkmanager --licenses` returned 141
  (SIGPIPE) under `set -o pipefail` because sdkmanager closes
  stdin after accepting all licenses while `yes` keeps writing.
  Feed a finite `printf 'y\n%.0s' {1..50}` instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 19:26:06 +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.