CI: Gitea-compatible artifacts and cache; macOS/Windows builds as a manual workflow
build / mod (push) Successful in 8m48s
build / game-linux (push) Failing after 17m56s
build / release (push) Has been skipped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 19:24:26 +03:00
parent a6a13003c2
commit 0b9d7d2942
4 changed files with 118 additions and 80 deletions
+16 -76
View File
@@ -1,7 +1,5 @@
# Сборка на каждый пуш: мод (.hmod, для всех ОС) и игра-форк для Linux;
# для Windows и macOS — если в репозитории заданы переменные BUILD_WINDOWS / BUILD_MACOS = true
# и подключены раннеры с метками windows-latest / macos-latest.
# Пуш в main публикует релиз build-<номер> со всеми собранными архивами.
# Сборка на каждый пуш: мод (.hmod, для всех ОС) и игра-форк для Linux.
# Пуш в main публикует релиз build-<номер>. Сборки для Windows и macOS — desktop.yml (вручную).
name: build
on:
@@ -20,6 +18,12 @@ jobs:
run: |
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/cargo-horizon-mod
~/.cargo/registry
key: mod-tool-${{ hashFiles('HORIZON_COMMIT', 'horizon-patches/*') }}
- name: Форк Horizon (исходники)
run: python3 tools/airdef.py fork
- name: Мод
@@ -28,7 +32,7 @@ jobs:
run: |
mkdir -p out
cp airdef-mod/target/horizon-mod/airdef.hmod out/airdef.hmod
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: airdef-hmod
path: out/airdef.hmod
@@ -47,7 +51,7 @@ jobs:
run: |
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
@@ -59,7 +63,7 @@ jobs:
run: python3 tools/airdef.py fork
- name: Игра
run: python3 tools/airdef.py game
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
name: airdef-hmod
path: out
@@ -70,81 +74,17 @@ jobs:
cp horizon/target/fast/horizon-client horizon/target/fast/horizon-ctl out/airdef.hmod dist/play.sh "$D/"
cp docs/INSTALL.md "$D/"
tar czf "out/$D.tar.gz" "$D"
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: airdef-linux
path: out/airdef-linux-x86_64.tar.gz
game-macos:
if: vars.BUILD_MACOS == 'true'
runs-on: macos-latest
needs: mod
steps:
- uses: actions/checkout@v4
- name: Rust
run: |
command -v cargo || curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Форк Horizon
run: python3 tools/airdef.py fork
- name: Игра
run: python3 tools/airdef.py game
- uses: actions/download-artifact@v4
with:
name: airdef-hmod
path: out
- name: Архив
run: |
D=airdef-macos-arm64
mkdir -p "$D"
cp horizon/target/fast/horizon-client horizon/target/fast/horizon-ctl out/airdef.hmod dist/play.sh docs/INSTALL.md "$D/"
tar czf "out/$D.tar.gz" "$D"
- uses: actions/upload-artifact@v4
with:
name: airdef-macos
path: out/airdef-macos-arm64.tar.gz
game-windows:
if: vars.BUILD_WINDOWS == 'true'
runs-on: windows-latest
needs: mod
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v4
- name: Rust
run: |
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) {
Invoke-WebRequest https://win.rustup.rs/x86_64 -OutFile rustup-init.exe
.\rustup-init.exe -y --profile minimal
}
"$env:USERPROFILE\.cargo\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
- name: Форк Horizon
run: python tools/airdef.py fork
- name: Игра
run: python tools/airdef.py game
- uses: actions/download-artifact@v4
with:
name: airdef-hmod
path: out
- name: Архив
run: |
$D = "airdef-windows-x86_64"
New-Item -ItemType Directory -Force $D | Out-Null
Copy-Item horizon\target\fast\horizon-client.exe, horizon\target\fast\horizon-ctl.exe, out\airdef.hmod, dist\play.bat, docs\INSTALL.md $D
Compress-Archive -Path $D -DestinationPath "out\$D.zip" -Force
- uses: actions/upload-artifact@v4
with:
name: airdef-windows
path: out/airdef-windows-x86_64.zip
release:
if: github.ref == 'refs/heads/main' && !failure() && !cancelled()
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
needs: [mod, game-linux, game-macos, game-windows]
needs: [mod, game-linux]
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v3
with:
path: artifacts
- name: Релиз
@@ -155,7 +95,7 @@ jobs:
SHA: ${{ github.sha }}
run: |
set -e
BODY=$(printf 'Сборка %s (%s).\n\n- airdef.hmod — мод, для всех ОС;\n- airdef-<ОС>.* — игра-форк Horizon с модом и скриптом запуска.\n\nКак запускать: docs/INSTALL.md.' "$TAG" "$SHA")
BODY=$(printf 'Сборка %s (%s).\n\n- airdef.hmod — мод, для всех ОС;\n- airdef-linux-x86_64.tar.gz — игра-форк Horizon для Linux с модом и play.sh.\n\nСборки для Windows и macOS добавляет workflow desktop (запуск вручную с этим тегом).\nКак запускать: docs/INSTALL.md.' "$TAG" "$SHA")
DATA=$(BODY="$BODY" python3 -c 'import json,os;print(json.dumps({"tag_name":os.environ["TAG"],"target_commitish":os.environ["SHA"],"name":os.environ["TAG"],"body":os.environ["BODY"]}))')
ID=$(curl -sf -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" "$API/releases" -d "$DATA" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')
find artifacts -type f | while read -r f; do
+96
View File
@@ -0,0 +1,96 @@
# Сборки игры-форка для macOS и Windows: запускаются вручную (Actions → desktop → Run workflow)
# с тегом готового релиза (build-N) и дописывают свои архивы в него. Нужны раннеры с метками
# macos-latest / windows-latest (например, act_runner в режиме host на своём Маке или ПК).
name: desktop
on:
workflow_dispatch:
inputs:
tag:
description: Тег релиза, например build-3
required: true
os:
description: macos, windows или both
required: true
default: both
env:
CARGO_TERM_COLOR: never
jobs:
game-macos:
if: inputs.os == 'macos' || inputs.os == 'both'
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Rust
run: |
command -v cargo || curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Форк Horizon
run: python3 tools/airdef.py fork
- name: Игра
run: python3 tools/airdef.py game
- name: Мод
run: |
rustup target add wasm32-unknown-unknown
python3 tools/airdef.py mod
mkdir -p out
cp airdef-mod/target/horizon-mod/airdef.hmod out/
- name: Архив
run: |
D=airdef-macos-arm64
mkdir -p "$D"
cp horizon/target/fast/horizon-client horizon/target/fast/horizon-ctl out/airdef.hmod dist/play.sh docs/INSTALL.md "$D/"
tar czf "out/$D.tar.gz" "$D"
- name: В релиз
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
TAG: ${{ inputs.tag }}
run: |
set -e
ID=$(curl -sf -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/airdef-macos-arm64.tar.gz" "$API/releases/$ID/assets?name=airdef-macos-arm64.tar.gz" > /dev/null
game-windows:
if: inputs.os == 'windows' || inputs.os == 'both'
runs-on: windows-latest
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v4
- name: Rust
run: |
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) {
Invoke-WebRequest https://win.rustup.rs/x86_64 -OutFile rustup-init.exe
.\rustup-init.exe -y --profile minimal
}
"$env:USERPROFILE\.cargo\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
- name: Форк Horizon
run: python tools/airdef.py fork
- name: Игра
run: python tools/airdef.py game
- name: Мод
run: |
rustup target add wasm32-unknown-unknown
python tools/airdef.py mod
New-Item -ItemType Directory -Force out | Out-Null
Copy-Item airdef-mod\target\horizon-mod\airdef.hmod out\
- name: Архив
run: |
$D = "airdef-windows-x86_64"
New-Item -ItemType Directory -Force $D | Out-Null
Copy-Item horizon\target\fast\horizon-client.exe, horizon\target\fast\horizon-ctl.exe, out\airdef.hmod, dist\play.bat, docs\INSTALL.md $D
Compress-Archive -Path $D -DestinationPath "out\$D.zip" -Force
- name: В релиз
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
TAG: ${{ inputs.tag }}
run: |
$h = @{ Authorization = "token $env:TOKEN" }
$id = (Invoke-RestMethod -Headers $h "$env:API/releases/tags/$env:TAG").id
curl.exe -sf -X POST -H "Authorization: token $env:TOKEN" -F "attachment=@out\airdef-windows-x86_64.zip" "$env:API/releases/$id/assets?name=airdef-windows-x86_64.zip"
+3 -2
View File
@@ -23,8 +23,9 @@ python3 tools/airdef.py play # запустить (аргументы игр
(`tools/gen_sounds.py`, нужны numpy и ffmpeg), собирает и ставит мод. Сгенерированные файлы лежат в репозитории,
так что для обычной сборки нужен только Rust.
CI (`.gitea/workflows/build.yml`) на каждый пуш собирает мод и игру для Linux (и для Windows/macOS, если заданы
переменные `BUILD_WINDOWS` / `BUILD_MACOS` и есть раннеры), а пуш в `main` публикует релиз `build-N`.
CI: `.gitea/workflows/build.yml` на каждый пуш собирает мод и игру для Linux, а пуш в `main` публикует релиз
`build-N`; `.gitea/workflows/desktop.yml` (запуск вручную с тегом релиза) собирает игру для macOS и Windows на
раннерах с метками `macos-latest` / `windows-latest` и дописывает архивы в релиз.
## Как играть
+3 -2
View File
@@ -23,8 +23,9 @@ AirDef работает на своей сборке (форке) Horizon: в н
- `airdef.hmod` — сам мод;
- `airdef-windows-x86_64.zip`, `airdef-macos-arm64.tar.gz`, `airdef-linux-x86_64.tar.gz` — игра-форк + мод +
скрипт запуска (сборки для Windows и macOS появляются, только если в CI подключены такие раннеры;
иначе — способ 2б).
скрипт запуска. Сборка для Linux есть всегда; для Windows и macOS её добавляет workflow **desktop**
(Actions → desktop → Run workflow, указать тег релиза), если подключены раннеры с метками
`windows-latest` / `macos-latest`. Нет такой сборки — способ 2б.
**Windows:** распакуй zip куда угодно и запусти `play.bat`. Он положит мод в папку игры, включит его и запустит
игру. Конкретный мир: `play.bat --world "Имя мира"` (в командной строке, из папки архива).