Continuous Integration for Games¶
A game’s builds for every platform can run on a CI service on each release
(or on demand), from the same commands a developer runs by hand. They build
from the published engine – the acron wheel of the version the game
pins, and the Acron SDKs for C++ – downloaded from the Acron archive; a game
never compiles the engine itself.
acronmanager ci init (the launcher’s Set up CI button) writes such a
workflow for GitHub Actions or Gitea Actions from the game’s
pyproject.toml:
acronmanager ci init # .github/workflows/acron.yml
acronmanager ci init --provider gitea # .gitea/workflows/acron.yml
acronmanager ci init --targets web,android
What is generated¶
One job per platform the game exports to:
Job |
Python game |
C++ game |
|---|---|---|
desktop-<os> |
|
|
web |
|
the same, when
|
android |
|
the same, when
|
wii |
– |
|
Each job checks out the repository, sets up uv,
runs uv sync (and installs acronmanager from the archive when the
game does not depend on it), runs the export, and uploads dist/ as the
job’s artifact. On GitHub, the Wii job runs in the devkitpro/devkitppc
container; Android jobs install the platform and build tools they need, and
the NDK an Android SDK names is installed on first use.
By default the jobs run when started by hand (Actions > Acron > Run
workflow) and when a tag v* is pushed.
Secrets¶
Set these in the repository’s settings (Secrets and variables > Actions):
UV_INDEX_ACRON_ARCHIVE_USERNAME,UV_INDEX_ACRON_ARCHIVE_PASSWORDRequired. An account on archive.acronengine.com with read access and its token: the engine comes from there. The jobs set them as their environment under these same names, which uv (the
acron-archiveindex) and acronmanager (the SDKs) read – as the launcher sets them on a developer’s machine.ANDROID_KEYSTORE_BASE64,ANDROID_KEYSTORE_ALIAS,ANDROID_KEYSTORE_PASSWORDOptional: the key the APK is signed with for a store (
base64 -w0 release.jksgives the first; see Signing). Without them the APK is signed with a debug key, which is fine for testing but cannot be published. The jobs hand the key to acronmanager asACRON_ANDROID_KEYSTORE(and_ALIAS,_PASSWORD), and to a packaging script of the game’s own asKEYSTORE,KEYSTORE_ALIASandKEYSTORE_PASSWORD.
Which engine¶
A Python game gets the acron wheel of the version it pins
(acron==... in [project] dependencies). A C++ game gets each SDK
from the archive: the desktop SDK of [tool.acron.desktop] version (pin a
release version there, or the job takes the latest), and the web, Android
and Wii SDKs as [tool.acron.web/android/wii] sdk name them, else the
archive’s latest. A game that lays its SDKs out with a script of its own
runs that script in setup (below).
Settings¶
ci init records its choices in [tool.acron.ci], which every later
acronmanager ci update regenerates the workflow from:
[tool.acron.ci]
provider = "github" # or "gitea"
targets = ["desktop", "web", "android"] # default: all the game supports
desktop = ["linux", "macos"] # default: linux, macos, windows
tags = ["v*"] # release tags ([] = none)
branches = [] # also run on pushes to these
python = "3.14" # the Python the engine wheels are built for
timeout = 120 # minutes per job
runners = { linux = "ubuntu-24.04", wii = ["self-hosted", "Linux"] }
setup = { android = ["tools/fetch-data.sh"] } # run before the export
artifacts = { android = ["dist/*.apk"] } # default: dist/
env = { MYGAME_RELEASE = "1" }
# platforms = { linux = "linux_x86_64" } # Python: build_apps' platform per OS
setup holds commands a job runs before the export (data a game downloads
or generates, a program it ships); it is keyed by the target or by the job
(desktop-macos).
A Python game’s desktop job builds its own OS’s platform: linux_x86_64,
macosx_11_0_arm64 or win_amd64 (platforms changes them). When
[tool.acron.build_apps] names platforms itself, each desktop job runs
plain acronmanager dist and builds all of them.
Runners¶
On GitHub the jobs use GitHub’s runners (ubuntu-24.04, macos-14,
windows-2022) unless runners names others, such as
["self-hosted", "macOS"]; a self-hosted Wii runner needs devkitPro in
/opt/devkitpro, an Android one a JDK.
On Gitea (--provider gitea) the jobs run on self-hosted act_runner
machines, by default labelled linux-x64, macos-arm64 and
windows-x64. The steps are plain shell (such runners cannot be relied on
to run JavaScript actions), so the machines need git, curl and
uv (installed by the job when missing); the jobs’ files are kept on the
runner, in $ACRON_ARTIFACT_DIR/<repository>/<run>/<job>/.
Your own changes¶
The generated parts of the workflow sit between marker comments:
# >>> acronmanager:web sha256=... >>>
web:
...
# <<< acronmanager:web <<<
acronmanager ci update rewrites only those, and keeps everything else:
comments, and jobs of your own after the last generated one. A generated
part changed by hand is not overwritten – put the change into
[tool.acron.ci] instead, or outside the markers, or replace it with
acronmanager ci update --force.
acronmanager ci check exits with an error when the workflow does not
parse, lacks a job for a target, or no longer matches [tool.acron.ci];
it fits a pre-commit hook.
Testing against an engine build¶
The engine’s own release builds real projects from its new wheels and SDKs before it publishes them, through these variables, which also let a game be built against an engine that is not published:
ACRON_WHEELthe desktop wheel
acronmanager distfreezes instead of the pinned oneACRON_WEB_WHEEL,ACRON_ANDROID_WHEELthe web and Android wheels (Python)
ACRON_DESKTOP_SDK,ACRON_WEB_SDK,ACRON_ANDROID_SDK,ACRON_WII_SDKan SDK directory or
.tar.gzinstead of the archive’s (C++)