Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @joryirving
137 changes: 137 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Release

on:
push:
tags:
- 'tags/*'

permissions:
contents: write

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

env:
GODOT_VERSION: 4.2.2
GODOT_STATUS: stable
GODOT_LINUX_URL: https://github.com/godotengine/godot-builds/releases/download/4.2.2-stable/Godot_v4.2.2-stable_linux.x86_64.zip
GODOT_TEMPLATES_URL: https://github.com/godotengine/godot-builds/releases/download/4.2.2-stable/Godot_v4.2.2-stable_export_templates.tpz
GODOT_MACOS_URL: https://github.com/godotengine/godot-builds/releases/download/4.2.2-stable/Godot_v4.2.2-stable_macos.universal.zip

jobs:
linux:
name: Linux export
runs-on: [windowstead, linux, x64]
steps:
- uses: actions/checkout@v4

- name: Download Godot
shell: bash
run: |
set -euo pipefail
mkdir -p .tools
curl -fsSL "$GODOT_LINUX_URL" -o /tmp/godot_linux.zip
unzip -oq /tmp/godot_linux.zip -d .tools/
chmod +x .tools/Godot_v4.2.2-stable_linux.x86_64

- name: Install export templates
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}
curl -fsSL "$GODOT_TEMPLATES_URL" -o /tmp/godot_export_templates.tpz
unzip -oq /tmp/godot_export_templates.tpz -d /tmp/godot_export_templates
cp -f /tmp/godot_export_templates/templates/* ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}/

- name: Export Linux build
shell: bash
run: |
set -euo pipefail
mkdir -p build/release/linux
.tools/Godot_v4.2.2-stable_linux.x86_64 --headless --path . --export-release "Linux/X11" ./build/release/linux/windowstead.x86_64
cd build/release/linux
zip -r ../../windowstead-linux.zip windowstead.x86_64 windowstead.pck

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: build/windowstead-linux.zip
fail_on_unmatched_files: true

windows:
name: Windows export
runs-on: [windowstead, linux, x64]
steps:
- uses: actions/checkout@v4

- name: Download Godot
shell: bash
run: |
set -euo pipefail
mkdir -p .tools
curl -fsSL "$GODOT_LINUX_URL" -o /tmp/godot_linux.zip
unzip -oq /tmp/godot_linux.zip -d .tools/
chmod +x .tools/Godot_v4.2.2-stable_linux.x86_64

- name: Install export templates
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}
curl -fsSL "$GODOT_TEMPLATES_URL" -o /tmp/godot_export_templates.tpz
unzip -oq /tmp/godot_export_templates.tpz -d /tmp/godot_export_templates
cp -f /tmp/godot_export_templates/templates/* ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}/

- name: Export Windows build
shell: bash
run: |
set -euo pipefail
mkdir -p build/release/windows
.tools/Godot_v4.2.2-stable_linux.x86_64 --headless --path . --export-release "Windows Desktop" ./build/release/windows/windowstead.exe
cd build/release/windows
zip -r ../../windowstead-windows.zip windowstead.exe windowstead.pck

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: build/windowstead-windows.zip
fail_on_unmatched_files: true

macos:
name: macOS export
runs-on: [windowstead, macos, arm64]
steps:
- uses: actions/checkout@v4

- name: Install Godot and export templates
shell: bash
run: |
set -euo pipefail
mkdir -p ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}
curl -fsSL "$GODOT_TEMPLATES_URL" -o /tmp/godot_export_templates.tpz
unzip -oq /tmp/godot_export_templates.tpz -d /tmp/godot_export_templates
cp -f /tmp/godot_export_templates/templates/* ~/.local/share/godot/export_templates/${GODOT_VERSION}.${GODOT_STATUS}/
mkdir -p .tools/macos
curl -fsSL "$GODOT_MACOS_URL" -o /tmp/godot_macos.zip
unzip -oq /tmp/godot_macos.zip -d .tools/macos

- name: Export macOS build
shell: bash
run: |
set -euo pipefail
mkdir -p build/release/macos
GODOT_MAC_APP=$(find .tools/macos -maxdepth 2 -name 'Godot.app' -print -quit)
if [ -z "$GODOT_MAC_APP" ]; then
echo 'Godot.app not found in downloaded macOS archive' >&2
exit 1
fi
"$GODOT_MAC_APP/Contents/MacOS/Godot" --headless --path . --export-release "macOS" ./build/release/macos/windowstead.app
cd build/release/macos
zip -r ../../windowstead-macos.zip windowstead.app windowstead.pck

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: build/windowstead-macos.zip
fail_on_unmatched_files: true
52 changes: 52 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test

on:
pull_request:

permissions:
contents: read

env:
GODOT_VERSION: 4.2.2
GODOT_STATUS: stable
GODOT_LINUX_URL: https://github.com/godotengine/godot-builds/releases/download/4.2.2-stable/Godot_v4.2.2-stable_linux.x86_64.zip

jobs:
smoke-test:
name: Headless smoke test
runs-on: [windowstead, linux, x64]
steps:
- uses: actions/checkout@v4

- name: Download Godot
shell: bash
run: |
set -euo pipefail
mkdir -p .tools
curl -fsSL "$GODOT_LINUX_URL" -o /tmp/godot_linux.zip
unzip -oq /tmp/godot_linux.zip -d .tools/
chmod +x .tools/Godot_v4.2.2-stable_linux.x86_64

- name: Verify Godot binary
shell: bash
run: |
set -euo pipefail
chmod +x .tools/Godot_v4.2.2-stable_linux.x86_64
./.tools/Godot_v4.2.2-stable_linux.x86_64 --version

- name: Run headless smoke test
shell: bash
run: |
set -euo pipefail
timeout 15 ./.tools/Godot_v4.2.2-stable_linux.x86_64 --headless --path . --fixed-fps 60 --quit-after 300 > smoke.log 2>&1
if grep -E "SCRIPT ERROR|ERROR:" smoke.log; then
echo "Smoke test logged an engine/script error" >&2
exit 1
fi

- name: Run lightweight script tests
shell: bash
run: |
set -euo pipefail
./.tools/Godot_v4.2.2-stable_linux.x86_64 --headless --path . --script res://tests/test_runner.gd > tests.log 2>&1
cat tests.log
6 changes: 6 additions & 0 deletions INITIAL_BUILD_BRIEF.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ Issue: `joryirving/windowstead#2`
- There was no existing native windowing layer, no game engine setup, no asset pipeline worth preserving, and no reusable desktop-overlay behavior from the web prototype.
- Because the request is a pivot, not an incremental patch, the cleanest path is a fresh Godot 4 root project on a new branch from `main`, then re-implement only the proven MVP loop from the prototype.
- The web prototype already proved the tiny colony loop shape works: seeded wood/stone nodes, a stockpile, worker task scoring by priority and distance, placeholder structures, and an ambient log cadence.
- For this CI/CD follow-up, I verified the repo already includes Godot 4.2.2 Linux editor bits in `.tools/`, starter export presets for Linux/Windows/macOS in `export_presets.cfg`, and no existing `.github/workflows/` or `CODEOWNERS`.
- I also verified the checked-in Linux binary can run headless smoke tests locally, but exports fail without installing matching 4.2.2 export templates first, so workflow setup must bootstrap templates on runners before calling `--export-release`.
- GitHub state no longer matches the original task note: PR #4 is already merged, and `feat/godot-pivot` remains as an unmerged branch ref, so any new CI/CD work should ship in a fresh PR instead of trying to reopen dead history.

## Recommended Approach
- Replace the Vite app with a Godot 4 project rooted at the repo top level: `project.godot`, `scenes/main.tscn`, `scripts/main.gd`, `scripts/game_state.gd`, theme/icon, and `export_presets.cfg`.
- Keep the first pass intentionally small: one `Control`-driven scene, a grid of buttons for the world, sidebar controls for builds/priorities/save, and a timer-based autonomous sim loop in GDScript.
- Use an Autoload singleton for persistence so desktop builds save to `user://` while web builds can use `localStorage` through `JavaScriptBridge`.
- Set borderless + always-on-top by default, enable transparent window mode when the platform supports it, and fall back to a compact frameless top-right window when it does not.
- Preserve the functional MVP from the prototype rather than overbuilding engine systems: 2 workers, gather/haul/build tasks, hut/workshop/garden placeholders, stockpile resources, event log, and export presets for Linux/Windows/macOS.
- Add `.github/workflows/test.yml` for Linux self-hosted PR validation using the checked-in Linux Godot binary, a 5-second headless smoke run, and a tiny GDScript persistence regression test.
- Add `.github/workflows/release.yml` for tag-only release builds that run Linux and Windows exports on the Linux self-hosted runner with the checked-in Linux binary, run macOS export on the macOS self-hosted runner with a matching 4.2.2 macOS editor download, install export templates on every runner, zip each artifact with consistent names, and attach them to the GitHub release via `softprops/action-gh-release`.
- Add `.github/CODEOWNERS` with `* @joryirving` so future PRs request the right reviewer by default.
26 changes: 26 additions & 0 deletions tests/test_runner.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
extends SceneTree

func _initialize() -> void:
var game_state_script := load("res://scripts/game_state.gd")
var game_state = game_state_script.new()
root.add_child(game_state)
await process_frame

var payload := {
"tick": 42,
"resources": {"wood": 7, "stone": 3},
"events": [{"tick": 42, "text": "test event"}],
}

game_state.use_local_storage = false
game_state.save_game(payload)
var loaded = game_state.load_game()
assert(int(loaded.get("tick", -1)) == 42)
assert(int(loaded.get("resources", {}).get("wood", -1)) == 7)
assert(int(loaded.get("resources", {}).get("stone", -1)) == 3)
assert(loaded.get("events", []).size() == 1)
game_state.clear_game()
assert(game_state.load_game().is_empty())

print("test_runner: ok")
quit()
Loading