Repository navigation
210 lines (190 loc) · 9.46 KB
/
Copy pathrelease.yml
File metadata and controls
210 lines (190 loc) · 9.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
name: Release
# Triggered by pushing a version tag `published-vX.Y.Z` (done manually after the
# release PR is merged — see the `release` skill). Builds the deliverable and
# publishes a GitHub Release with CTLD.lua attached.
on:
push:
tags: ['published-v*']
jobs:
release:
name: Publish GitHub Release
runs-on: windows-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
- name: Install ctld-tools (the build embeds the config YAML via `ctld-tools embed`)
working-directory: tools/ctld-tools
shell: bash
run: |
pip install poetry
poetry install --without build
- name: Build CTLD.lua
run: powershell -ExecutionPolicy Bypass -File tools\build\merge_CTLD.ps1
shell: pwsh
- name: Build the dev-time asset-check companion
run: powershell -ExecutionPolicy Bypass -File tools\companion\build_companion.ps1
shell: pwsh
- name: Resolve version from tag
id: ver
run: |
$tag = "${{ github.ref_name }}" # e.g. published-v2.0.0 or published-v2.0.0-rc1
$version = $tag -replace '^published-v', ''
"version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
# A semver pre-release suffix (a '-' in the version, e.g. -rc1) marks a pre-release:
# publish it as such and leave the published-latest floating tag untouched.
$prerelease = if ($version -match '-') { 'true' } else { 'false' }
"prerelease=$prerelease" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
shell: pwsh
- name: Create GitHub Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
notes=(--generate-notes)
[ -f RELEASE_NOTES.md ] && notes=(--notes-file RELEASE_NOTES.md)
# rc-suffixed versions publish as a GitHub pre-release (not the default "Latest").
pre=()
[ "${{ steps.ver.outputs.prerelease }}" = "true" ] && pre=(--prerelease)
# assets/*.ogg ship as release assets too: the engine plays them through
# radioTransmission, so a mission without them has silent beacons. They used to be
# repo-only, which made the manual install impossible to finish from the release page
# alone (FEAT-ONE-CLICK-INSTALL). The exe bundles them as well, for the tool path.
gh release create "${{ github.ref_name }}" \
CTLD.lua dist/CTLD_userConfig.lua dist/CTLD_asset_check.lua \
assets/beacon.ogg assets/beaconsilent.ogg \
--title "CTLD v${{ steps.ver.outputs.version }}" \
"${notes[@]}" "${pre[@]}"
# A floating "published-latest" tag tracks the last STABLE release. Only a real
# release advances it; a pre-release (rc) leaves production users on the previous
# stable. "published-latest" is not matched by the 'published-v*' trigger, so this
# push does not re-trigger the workflow.
- name: Advance published-latest (stable only)
if: steps.ver.outputs.prerelease != 'true'
run: |
git tag -f published-latest "${{ github.ref_name }}"
git push origin -f published-latest
shell: pwsh
# The engine is git-ignored since CHORE-UNTRACK-BUILT-ENGINE (PR #110), so build-exe's
# checkout no longer carries it — and that job bundles it with --add-data. Hand the
# freshly-built file over as an artifact rather than rebuilding it there: the exe then
# embeds byte-for-byte the CTLD.lua attached to this release, which a second independent
# build could not guarantee.
- name: Hand CTLD.lua to the exe build
uses: actions/upload-artifact@v4
with:
name: ctld-engine
path: CTLD.lua
retention-days: 1
if-no-files-found: error
# ─────────────────────────────────────────────────────────────
# Build the Mission Maker tool ctld-tools.exe (PyInstaller) and attach it to the
# release. A single console exe = the CLI (embed/validate/gen) AND the GUI launcher:
# double-clicking boots the local web app. The frontend is built with Node at CI and
# bundled as static assets; the default config YAML + schema + DCS type set are bundled
# too, so the exe runs with no repo, no Node, no network. Separate job: if packaging
# fails, the CTLD.lua release (job above) is already published.
# ─────────────────────────────────────────────────────────────
build-exe:
name: Build & attach ctld-tools.exe
needs: release
runs-on: windows-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
- uses: actions/setup-node@v7
with:
node-version: "22"
# --add-data below bundles CTLD.lua from the repo root. It is git-ignored since PR #110,
# so the checkout above does not provide it; the release job built it and passed it here.
- name: Collect CTLD.lua from the release job
uses: actions/download-artifact@v8
with:
name: ctld-engine
- name: Build the frontend (→ ctld_tools/web/static)
working-directory: tools/ctld-tools/web
shell: bash
run: |
npm ci
npm run build
- name: Build ctld-tools.exe
working-directory: tools/ctld-tools
shell: bash
run: |
pip install poetry
# --without dev (drops ruff/mypy/pytest); --with build adds pyinstaller.
poetry install --without dev --with build
poetry run pyinstaller --onefile --console --name ctld-tools \
--collect-data ctld_tools \
--collect-submodules uvicorn \
--add-data "../../src/CTLD_config.yaml;ctld_data" \
--add-data "../../src/CTLD_config_schema.yaml;ctld_data" \
--add-data "../../CTLD.lua;ctld_data" \
--add-data "../../assets/beacon.ogg;ctld_data" \
--add-data "../../assets/beaconsilent.ogg;ctld_data" \
ctld_tools/__main__.py
- name: Smoke-check the exe (CLI commands present)
working-directory: tools/ctld-tools
shell: bash
run: |
help="$(./dist/ctld-tools.exe --help)"
for cmd in embed validate gen; do
echo "$help" | grep -q " $cmd " || { echo "::error::$cmd command missing from exe"; exit 1; }
done
# --version must print the release's version and exit. Routed to `serve` by mistake it
# would hang this job instead of failing it, so assert the value, not just the exit code.
printed="$(./dist/ctld-tools.exe --version)"
expected="${GITHUB_REF_NAME#published-v}"
[ "$printed" = "$expected" ] || {
echo "::error::--version printed '$printed', expected '$expected'"; exit 1; }
# A bundle that silently loses an --add-data entry must fail the release, not ship: the exe
# installs these payloads into a mission, and a missing one only surfaces in DCS.
- name: Smoke-check the exe (bundled engine + beacon sounds)
working-directory: tools/ctld-tools
shell: bash
run: |
set -euo pipefail
./dist/ctld-tools.exe payloads
# The CLI check above passes even if the bundled web app is missing or broken, which is what a
# Mission Maker actually double-clicks. So boot the real thing and pull every kind of resource
# out of it: the page, a static asset, and the API a screen cannot render without.
- name: Smoke-check the exe (serves the web app and its assets)
working-directory: tools/ctld-tools
shell: bash
run: |
set -euo pipefail
./dist/ctld-tools.exe serve --no-browser --port 8765 &
exe_pid=$!
trap 'kill "$exe_pid" 2>/dev/null || true' EXIT
for _ in $(seq 1 40); do
curl -sf -m 3 http://127.0.0.1:8765/api/health >/dev/null && break
sleep 1
done
curl -sf -m 5 http://127.0.0.1:8765/api/health >/dev/null \
|| { echo "::error::exe did not start serving"; exit 1; }
check() { # path, min bytes, label
size=$(curl -sf -m 10 -o /dev/null -w '%{size_download}' "http://127.0.0.1:8765$1") \
|| { echo "::error::$3 not served ($1)"; exit 1; }
[ "$size" -ge "$2" ] \
|| { echo "::error::$3 served but only $size bytes ($1)"; exit 1; }
echo "ok: $3 — $size bytes"
}
check / 200 "bundled index.html"
check /hero-troop-insertion.webp 10000 "header/background photo"
check /favicon.svg 100 "favicon"
check /api/schema?lang=fr 10000 "schema (FR)"
check /api/i18n?lang=fr 2000 "translations (FR)"
check /api/defaults 10000 "default catalogue"
check /api/dcs-types 10000 "DCS type list"
- name: Attach ctld-tools.exe to the release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${{ github.ref_name }}" tools/ctld-tools/dist/ctld-tools.exe