Adds a "Known issues from first runs" section to the workflow README capturing what broke on 2026-05-17: - Container jobs (validate, export-*) fail at actions/checkout@v4 with `node: not found` because barichello/godot-ci:4.6 has no Node. Workflow fix pending. - The earlier `actions/checkout` URL-prefix problem (Gitea behind YunoHost at /gitea/) is now resolved server-side by moving Gitea to the root; the note records this for future reference. - Default-branch mismatch (Gitea = main, CLAUDE.md says dev). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gitea Actions CI
Workflow defined in build.yml. Triggered on push / PR to
dev and main, or manually via workflow_dispatch.
Jobs
| Job | Image | Role |
|---|---|---|
validate |
barichello/godot-ci:4.6 |
godot --headless --import then grep for SCRIPT ERROR / Parse Error. Uploads .godot/ cache. |
lint |
ubuntu-latest (Python) |
gdlint scripts db scenes via gdtoolkit==4.* (Scony). Parallel to validate; does not gate exports yet. |
export-desktop |
barichello/godot-ci:4.6 |
Matrix: Windows / Linux / macOS. Reuses the import cache, uploads each binary as artifact. |
export-android |
barichello/godot-ci:4.6 + JDK 17 + Android SDK installed at runtime |
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
- Docker image tag — verify
barichello/godot-ci:4.6exists on Docker Hub. Otherwise adjustGODOT_IMAGE(common alternatives:4.3,4.4). - macOS preset missing — add it in Godot Editor → Project → Export →
Add → macOS, name it exactly
macOS(or change the matrix entry). The.zipwill be unsigned; on Mac it needsxattr -dr com.apple.quarantineto launch. Linux/X11Debugpreset — Godot-3-era name. Reopen the project in Godot 4 once and re-save the preset (the editor may rename it). Update the matrixpreset:field accordingly if it does.- Gitea runner — must support Docker containers (
act_runnerindockermode, orhostmode with Docker installed). Checkact_runner execaccess to Docker Hub. - Optional secret
ANDROID_KEYSTORE_BASE64—base64 -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 fail at actions/checkout@v4 with node: not found
OCI runtime exec failed: ... exec: "node": executable file not found in $PATH
actions/checkout@v4 is a JavaScript action and needs Node.js inside
the container. The barichello/godot-ci:4.6 image does not ship Node,
so every job using container: (validate, export-desktop, export-android)
breaks immediately.
Fix path (recommended): drop the container: block entirely and install
Godot in a step (the default catthehacker/ubuntu:act-latest image used
for runs-on: ubuntu-latest already has Node, Python, git, JDK). The
lint job is already structured this way.
Alternative: switch to a Godot CI image that bundles Node (some community images do); pin a specific tag.
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/ emptyReleaseVersionpipeline → replaced by triggers onmain(release branch perCLAUDE.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.