From e7389cb144aa2a0419bb0a18f6bda88c816e23d5 Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Mon, 3 Aug 2026 21:17:32 +0200 Subject: [PATCH] Add desktop binary exports to the CI pipeline Export win-x86, win-x64, linux-x64 and mac-universal builds headless from the godot-builder image and upload them as ReleaseAssets (--.zip, single root folder). Mac is one universal (intel + arm) build with Godot's built-in ad-hoc codesign; per-arch export is not possible with the official export templates. ETC2 ASTC texture import is enabled because the arm64 slice requires it. Co-Authored-By: Claude Fable 5 --- .woodpecker.yaml | 1 + Makefile | 70 +++++++++++++++++++++++++- export_presets.cfg | 120 +++++++++++++++++++++++++++++++++++++++++++++ project.godot | 5 ++ 4 files changed, 194 insertions(+), 2 deletions(-) diff --git a/.woodpecker.yaml b/.woodpecker.yaml index d759e38..a69e0ad 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -9,6 +9,7 @@ steps: image: git.teletypegames.org/internal/godot-builder:4.7.1 commands: - make ci-export + - make ci-binaries - name: artifact image: alpine diff --git a/Makefile b/Makefile index cc6231f..f93d9db 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,67 @@ export: web @echo "==> Cleaning temporary files" rm -rf $(WEB_DIR) +# --- native binaries --------------------------------------------------------- +# Godot cross-exports every desktop platform from linux with the official +# export templates, so unlike ebitengine ALL targets build in CI. Mac is a +# single universal (intel + arm) build: the official templates only ship a +# universal binary, per-arch export would need custom-built templates. +# Zip layout follows the ReleaseAsset convention: a single root folder, +# --/, zipped as --.zip. +BINARY_TARGETS = win-x86 win-x64 linux-x64 mac-universal + +binaries: build + @if [ -z "$(VERSION)" ]; then \ + echo "ERROR: VERSION not set!"; exit 1; \ + fi + @for target in $(BINARY_TARGETS); do \ + $(MAKE) binary-$$target VERSION=$(VERSION) || exit 1; \ + done + +binary-win-x86: + @$(MAKE) binary-build VERSION=$(VERSION) B_PRESET="Windows x86" B_EXT=.exe B_TARGET=win-x86 + +binary-win-x64: + @$(MAKE) binary-build VERSION=$(VERSION) B_PRESET="Windows x64" B_EXT=.exe B_TARGET=win-x64 + +binary-linux-x64: + @$(MAKE) binary-build VERSION=$(VERSION) B_PRESET="Linux x64" B_EXT= B_TARGET=linux-x64 + +binary-mac-universal: + @$(MAKE) binary-build-mac VERSION=$(VERSION) B_PRESET="Mac universal" B_TARGET=mac-universal + +# belső helper: egy win/linux target exportja + zip egyetlen gyökérmappával +# (embed_pck miatt az export egyetlen futtatható fájl) +binary-build: + @set -e; \ + PKG_DIR="$(PROJECT)-$(VERSION)-$(B_TARGET)"; \ + echo "==> Building $$PKG_DIR"; \ + rm -rf "$$PKG_DIR" "$$PKG_DIR.zip"; \ + mkdir -p "$$PKG_DIR"; \ + $(GODOT) --headless --export-release "$(B_PRESET)" "$$(pwd)/$$PKG_DIR/$(PROJECT)$(B_EXT)"; \ + if [ -f LICENSE ]; then cp LICENSE "$$PKG_DIR/"; fi; \ + if [ -f README.md ]; then cp README.md "$$PKG_DIR/"; fi; \ + zip -r "$$PKG_DIR.zip" "$$PKG_DIR" >/dev/null; \ + rm -rf "$$PKG_DIR"; \ + echo "==> $$PKG_DIR.zip kesz" + +# mac helper: a Godot linuxról csak .zip-be tud macOS-t exportálni (benne a +# .app), ezt csomagoljuk át a gyökérmappás konvencióra (zip -ry: exec bitek +# és symlinkek megmaradnak) +binary-build-mac: + @set -e; \ + PKG_DIR="$(PROJECT)-$(VERSION)-$(B_TARGET)"; \ + echo "==> Building $$PKG_DIR"; \ + rm -rf "$$PKG_DIR" "$$PKG_DIR.zip"; \ + mkdir -p "$$PKG_DIR"; \ + $(GODOT) --headless --export-release "$(B_PRESET)" "$$(pwd)/$$PKG_DIR/$(PROJECT)-mac-tmp.zip"; \ + cd "$$PKG_DIR" && unzip -q "$(PROJECT)-mac-tmp.zip" && rm "$(PROJECT)-mac-tmp.zip"; cd ..; \ + if [ -f LICENSE ]; then cp LICENSE "$$PKG_DIR/"; fi; \ + if [ -f README.md ]; then cp README.md "$$PKG_DIR/"; fi; \ + zip -ry "$$PKG_DIR.zip" "$$PKG_DIR" >/dev/null; \ + rm -rf "$$PKG_DIR"; \ + echo "==> $$PKG_DIR.zip kesz" + watch: fswatch -o . --include="\.gd$$" --include="\.tscn$$" | while read; do make build; done @@ -57,18 +118,23 @@ ci-export: @VERSION=$$(cat $(VERSION_FILE)); \ $(MAKE) export VERSION=$$VERSION +ci-binaries: + @VERSION=$$(cat $(VERSION_FILE)); \ + $(MAKE) binaries VERSION=$$VERSION + ci-upload: @VERSION=$$(cat $(VERSION_FILE)); \ FILE="$(PROJECT)-$$VERSION.html.zip"; \ META_SRC="metadata.json"; \ META_DST="$(PROJECT)-$$VERSION.metadata.json"; \ + BINS=$$(ls $(PROJECT)-$$VERSION-*.zip 2>/dev/null || true); \ cp $$META_SRC $$META_DST; \ sshpass -p "$(DROPAREA_SSH_PASSWORD)" scp -o StrictHostKeyChecking=no -P $(DROPAREA_PORT) \ - $$FILE $$META_DST \ + $$FILE $$META_DST $$BINS \ $(DROPAREA_USER)@$(DROPAREA_HOST):$(DROPAREA_TARGET_PATH)/ ci-update: @VERSION=$$(cat $(VERSION_FILE)); \ curl "$(UPDATE_SERVER)/update?secret=$(UPDATE_SECRET)&name=$(PROJECT)&platform=godot&version=$$VERSION" -.PHONY: all build run web export watch clean ci-version ci-export ci-upload ci-update +.PHONY: all build run web export watch clean binaries binary-win-x86 binary-win-x64 binary-linux-x64 binary-mac-universal binary-build binary-build-mac ci-version ci-export ci-binaries ci-upload ci-update diff --git a/export_presets.cfg b/export_presets.cfg index fa0c4f6..938d986 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -41,3 +41,123 @@ html/canvas_resize_policy=2 html/focus_canvas_on_start=true html/experimental_virtual_keyboard=false progressive_web_app/enabled=false + +; Desktop presets: the preset names match the Makefile's binary-* targets +; and the resulting zips follow the ReleaseAsset naming +; (--.zip). Windows/Linux embed the .pck into +; the executable (single-file builds); `modify_resources=false` because +; the CI image has no rcedit. + +[preset.1] + +name="Windows x64" +platform="Windows Desktop" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.1.options] + +binary_format/architecture="x86_64" +binary_format/embed_pck=true +application/modify_resources=false +codesign/enable=false + +[preset.2] + +name="Windows x86" +platform="Windows Desktop" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.2.options] + +binary_format/architecture="x86_32" +binary_format/embed_pck=true +application/modify_resources=false +codesign/enable=false + +[preset.3] + +name="Linux x64" +platform="Linux" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.3.options] + +binary_format/architecture="x86_64" +binary_format/embed_pck=true + +; macOS: a single universal (x86_64 + arm64) build — the official export +; templates only ship a universal binary, per-arch export would need +; custom-built templates. Exported as .zip (the only option when +; exporting from Linux), signed with Godot's built-in ad-hoc codesign +; (codesign/codesign=1), which works on any host platform. arm64 macOS +; refuses to run completely unsigned binaries, so signing is required. + +[preset.4] + +name="Mac universal" +platform="macOS" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.4.options] + +export/distribution_type=1 +binary_format/architecture="universal" +application/bundle_identifier="org.teletypegames.pong" +codesign/codesign=1 +notarization/notarization=0 diff --git a/project.godot b/project.godot index fcb1cc1..9bf51e8 100644 --- a/project.godot +++ b/project.godot @@ -47,3 +47,8 @@ confirm={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"echo":false,"script":null) ] } + +[rendering] + +; needed for the universal (arm64) macOS export in CI +textures/vram_compression/import_etc2_astc=true