Skip to content

Commit 95c8760

Browse files
committed
[CICD] add build workflow
1 parent 56a9615 commit 95c8760

10 files changed

Lines changed: 756 additions & 18 deletions

File tree

.gitattributes

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Git LFS tracking for large binary assets
2+
3+
# Images
4+
assets/images/**/*.png filter=lfs diff=lfs merge=lfs -text
5+
assets/images/**/*.jpg filter=lfs diff=lfs merge=lfs -text
6+
assets/images/**/*.JPG filter=lfs diff=lfs merge=lfs -text
7+
8+
# Audio
9+
assets/sounds/**/*.wav filter=lfs diff=lfs merge=lfs -text
10+
assets/sounds/**/*.mp3 filter=lfs diff=lfs merge=lfs -text
11+
12+
# Fonts
13+
assets/fonts/**/*.otf filter=lfs diff=lfs merge=lfs -text
14+
assets/fonts/**/*.ttf filter=lfs diff=lfs merge=lfs -text
15+
16+
# Root-level images
17+
assets/*.png filter=lfs diff=lfs merge=lfs -text
18+
assets/*.JPG filter=lfs diff=lfs merge=lfs -text

.github/workflows/build.yaml

Lines changed: 189 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,198 @@
1-
name: build game
1+
name: Build & Release
2+
23
on:
34
release:
45
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
version:
9+
description: "Version tag for manual build (e.g. v0.1.0-test)"
10+
required: false
11+
default: "dev"
12+
13+
permissions:
14+
contents: write
15+
16+
defaults:
17+
run:
18+
shell: bash
519

620
jobs:
7-
build:
21+
# ─────────────────────────────────────────────────────────────────────────────
22+
# Desktop builds: Windows / macOS / Linux
23+
# ─────────────────────────────────────────────────────────────────────────────
24+
build-desktop:
25+
name: Desktop (${{ matrix.os }})
26+
runs-on: ${{ matrix.os }}
27+
env:
28+
VERSION: ${{ github.event.release.tag_name || inputs.version || 'dev' }}
29+
strategy:
30+
fail-fast: false
31+
matrix:
32+
os: [windows-latest, macos-latest, ubuntu-latest]
33+
34+
steps:
35+
- name: Checkout (with LFS)
36+
uses: actions/checkout@v4
37+
with:
38+
lfs: true
39+
40+
- name: Set up Python 3.12
41+
uses: actions/setup-python@v5
42+
with:
43+
python-version: "3.12"
44+
45+
- name: Install uv
46+
uses: astral-sh/setup-uv@v4
47+
48+
- name: Install game dependencies
49+
run: uv sync
50+
51+
- name: Install PyInstaller
52+
run: uv pip install pyinstaller
53+
54+
# ── Icon conversion ────────────────────────────────────────────────────
55+
- name: Convert icon to ICO (Windows)
56+
if: runner.os == 'Windows'
57+
run: |
58+
uv pip install Pillow
59+
python -c "
60+
from PIL import Image
61+
img = Image.open('assets/fall_in_icon.png').convert('RGBA')
62+
img.save('assets/fall_in_icon.ico', sizes=[(16,16),(32,32),(48,48),(256,256)])
63+
"
64+
65+
- name: Convert icon to ICNS (macOS)
66+
if: runner.os == 'macOS'
67+
run: |
68+
mkdir -p assets/fall_in_icon.iconset
69+
for size in 16 32 128 256 512; do
70+
sips -z $size $size assets/fall_in_icon.png \
71+
--out assets/fall_in_icon.iconset/icon_${size}x${size}.png
72+
done
73+
iconutil -c icns assets/fall_in_icon.iconset \
74+
--out assets/fall_in_icon.icns
75+
76+
# ── ffmpeg setup ───────────────────────────────────────────────────────
77+
- name: Install ffmpeg (macOS)
78+
if: runner.os == 'macOS'
79+
run: brew install ffmpeg
80+
81+
- name: Install ffmpeg (Windows)
82+
if: runner.os == 'Windows'
83+
run: choco install ffmpeg -y
84+
85+
# ── BGM WAV → OGG ─────────────────────────────────────────────────────
86+
# Converts only bgm/ (68 MB → ~20 MB). sfx/ stays as WAV (5.7 MB).
87+
# OGG files are picked up automatically by asset_loader._resolve_sound_path().
88+
- name: Convert BGM WAV to OGG
89+
run: |
90+
for f in assets/sounds/bgm/*.wav; do
91+
ffmpeg -i "$f" -codec:a libvorbis -q:a 4 "${f%.wav}.ogg" -y
92+
rm "$f"
93+
done
94+
95+
# ── PyInstaller build ──────────────────────────────────────────────────
96+
- name: Build with PyInstaller
97+
run: uv run pyinstaller fall_in.spec
98+
99+
# ── Archive ───────────────────────────────────────────────────────────
100+
- name: Archive (Windows)
101+
if: runner.os == 'Windows'
102+
run: cd dist && zip -r "../fall-in-${VERSION}-windows.zip" fall-in/
103+
104+
- name: Archive (macOS)
105+
if: runner.os == 'macOS'
106+
run: cd dist && zip -r "../fall-in-${VERSION}-macos.zip" "Fall In.app/"
107+
108+
- name: Archive (Linux)
109+
if: runner.os == 'Linux'
110+
run: cd dist && tar -czf "../fall-in-${VERSION}-linux.tar.gz" fall-in/
111+
112+
# ── Upload artifact (always, for inspection) ──────────────────────────
113+
- name: Upload build artifact
114+
uses: actions/upload-artifact@v4
115+
with:
116+
name: fall-in-${{ runner.os }}-${{ env.VERSION }}
117+
path: fall-in-${{ env.VERSION }}-*
118+
retention-days: 7
119+
120+
# ── Upload to GitHub Release (release trigger only) ───────────────────
121+
- name: Upload to GitHub Release
122+
if: github.event_name == 'release'
123+
uses: softprops/action-gh-release@v2
124+
with:
125+
files: fall-in-${{ env.VERSION }}-*
126+
127+
# ─────────────────────────────────────────────────────────────────────────────
128+
# Web build: Pygbag (WebAssembly)
129+
# NOTE: Requires async game loop before this job succeeds.
130+
# GameManager.run() must use `await asyncio.sleep(0)`.
131+
# ─────────────────────────────────────────────────────────────────────────────
132+
build-web:
133+
name: Web (Pygbag)
8134
runs-on: ubuntu-latest
135+
env:
136+
VERSION: ${{ github.event.release.tag_name || inputs.version || 'dev' }}
137+
9138
steps:
10-
- name: Checkout
139+
- name: Checkout (with LFS)
11140
uses: actions/checkout@v4
12-
- name: Set up Python
13-
uses: actions/setup-python@v4
14141
with:
15-
python-version: '3.12'
142+
lfs: true
143+
144+
- name: Set up Python 3.12
145+
uses: actions/setup-python@v5
146+
with:
147+
python-version: "3.12"
148+
149+
- name: Install uv
150+
uses: astral-sh/setup-uv@v4
151+
152+
- name: Install game dependencies
153+
run: uv sync
154+
155+
- name: Install Pygbag
156+
run: pip install pygbag
157+
158+
# ── BGM WAV → OGG ─────────────────────────────────────────────────────
159+
- name: Convert BGM WAV to OGG
160+
run: |
161+
for f in assets/sounds/bgm/*.wav; do
162+
ffmpeg -i "$f" -codec:a libvorbis -q:a 4 "${f%.wav}.ogg" -y
163+
rm "$f"
164+
done
165+
166+
# ── Stage assets next to game code ────────────────────────────────────
167+
# Pygbag requires assets to be reachable from the game folder.
168+
# _find_project_root() in config.py searches parent dirs of config.py,
169+
# so copying assets/ and data/ into src/fall_in/ makes them discoverable.
170+
- name: Stage assets for Pygbag
171+
run: |
172+
cp -r assets src/fall_in/assets
173+
cp -r data src/fall_in/data
174+
175+
# ── Pygbag build ──────────────────────────────────────────────────────
176+
- name: Build web (Pygbag)
177+
run: python -m pygbag --build src/fall_in
178+
179+
# ── Archive ───────────────────────────────────────────────────────────
180+
- name: Archive web build
181+
run: |
182+
cd src/fall_in/build
183+
zip -r "../../../fall-in-${VERSION}-web.zip" web/
184+
185+
# ── Upload artifact (always, for inspection) ──────────────────────────
186+
- name: Upload build artifact
187+
uses: actions/upload-artifact@v4
188+
with:
189+
name: fall-in-web-${{ env.VERSION }}
190+
path: fall-in-${{ env.VERSION }}-web.zip
191+
retention-days: 7
192+
193+
# ── Upload to GitHub Release (release trigger only) ───────────────────
194+
- name: Upload to GitHub Release
195+
if: github.event_name == 'release'
196+
uses: softprops/action-gh-release@v2
197+
with:
198+
files: fall-in-${{ env.VERSION }}-web.zip

.github/workflows/test.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "src/**"
8+
- "tests/**"
9+
- "pyproject.toml"
10+
- "uv.lock"
11+
pull_request:
12+
branches: [main]
13+
paths:
14+
- "src/**"
15+
- "tests/**"
16+
- "pyproject.toml"
17+
- "uv.lock"
18+
19+
jobs:
20+
test:
21+
name: Test & Lint
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Set up Python 3.12
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: "3.12"
31+
32+
- name: Install uv
33+
uses: astral-sh/setup-uv@v4
34+
35+
- name: Install dependencies
36+
run: uv sync --dev
37+
38+
- name: Lint (ruff)
39+
run: uv run ruff check src/ tests/
40+
41+
- name: Test (pytest)
42+
run: uv run pytest --cov=fall_in --cov-report=term-missing
43+
env:
44+
SDL_VIDEODRIVER: dummy
45+
SDL_AUDIODRIVER: dummy
Lines changed: 3 additions & 0 deletions
Loading
-478 KB
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Loading
-499 KB
Loading

0 commit comments

Comments
 (0)