-
Notifications
You must be signed in to change notification settings - Fork 8
501 lines (447 loc) · 22.5 KB
/
Copy pathrelease.yml
File metadata and controls
501 lines (447 loc) · 22.5 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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
build:
name: ${{ matrix.label }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
label: linux-x86_64
# macos-13 (Intel) dropped — GitHub runner queue is unreliable.
- os: macos-14
label: macos-arm64
- os: windows-2022
label: windows-x86_64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
# -----------------------------------------------------------------
# Platform-specific dependency install (kept in sync with build.yml).
# -----------------------------------------------------------------
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
set -euxo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates curl gnupg lsb-release \
build-essential cmake ninja-build pkg-config patchelf icoutils \
libopencv-dev \
libgl1-mesa-dev libglu1-mesa-dev \
libx11-dev libxext-dev \
libxinerama-dev libxcursor-dev libxi-dev libxrandr-dev \
libwayland-dev libxkbcommon-dev wayland-protocols \
libusb-1.0-0-dev libudev-dev \
libgtk-3-dev
# See comment in build.yml — Intel's hosted key is stale, pull from keyserver over HTTP.
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xFB0B24895113F120&options=mr" \
| sudo gpg --dearmor -o /etc/apt/keyrings/librealsense.gpg
sudo chmod 0644 /etc/apt/keyrings/librealsense.gpg
# Intel only publishes the apt repo for select Ubuntu LTS codenames
# (bionic/focal/jammy/noble). On a newer/interim release the repo 404s
# and `apt-get update` fails, so fall back to the newest supported LTS
# (its binaries are forward-compatible).
RS_CODENAME="$(lsb_release -cs)"
# Fall back to the newest supported LTS ONLY when the repo definitively
# lacks this codename (Intel returns 403/404 for unsupported releases).
# Retry first so a transient network error doesn't silently retarget the
# distro — a real outage then fails loudly at apt-get update instead.
RS_HTTP="$(curl -sSL -o /dev/null -w '%{http_code}' --retry 3 --retry-connrefused \
"https://librealsense.intel.com/Debian/apt-repo/dists/${RS_CODENAME}/Release" || echo 000)"
if [ "$RS_HTTP" = "403" ] || [ "$RS_HTTP" = "404" ]; then
echo "librealsense apt repo has no '${RS_CODENAME}' (HTTP $RS_HTTP); falling back to noble"
RS_CODENAME=noble
fi
echo "deb [signed-by=/etc/apt/keyrings/librealsense.gpg] https://librealsense.intel.com/Debian/apt-repo ${RS_CODENAME} main" \
| sudo tee /etc/apt/sources.list.d/librealsense.list
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
librealsense2-dev librealsense2-utils librealsense2-udev-rules
- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
set -euxo pipefail
brew update
brew install cmake ninja opencv librealsense dylibbundler
# See build.yml for rationale: the Intel SDK installer has no working
# silent flag, so librealsense comes from vcpkg, restaged into the
# path CMakeLists.txt hardcodes.
- name: Export GHA cache env (for vcpkg x-gha binary cache)
if: runner.os == 'Windows'
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Install Windows dependencies
if: runner.os == 'Windows'
timeout-minutes: 25
shell: pwsh
env:
VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite'
run: |
$ErrorActionPreference = 'Stop'
choco install opencv --version=4.10.0 -y --no-progress
$opencvDir = "C:\tools\opencv\build"
if (-not (Test-Path "$opencvDir\OpenCVConfig.cmake")) {
$opencvDir = Get-ChildItem -Path "C:\tools\opencv" -Recurse -Filter "OpenCVConfig.cmake" | Select-Object -First 1 -ExpandProperty Directory | Select-Object -ExpandProperty FullName
}
"OpenCV_DIR=$opencvDir" | Out-File -FilePath $env:GITHUB_ENV -Append
"$opencvDir\x64\vc16\bin" | Out-File -FilePath $env:GITHUB_PATH -Append
& "C:\vcpkg\vcpkg.exe" install realsense2:x64-windows --triplet=x64-windows
if ($LASTEXITCODE -ne 0) { throw "vcpkg install realsense2:x64-windows failed (exit $LASTEXITCODE)." }
$vcpkgInstalled = "C:\vcpkg\installed\x64-windows"
$vcpkgLib = "$vcpkgInstalled\lib\realsense2.lib"
$vcpkgDll = "$vcpkgInstalled\bin\realsense2.dll"
$vcpkgInc = "$vcpkgInstalled\include\librealsense2"
foreach ($p in @($vcpkgLib, $vcpkgDll, $vcpkgInc)) {
if (-not (Test-Path $p)) { throw "vcpkg did not produce $p" }
}
$intelDir = "C:\Program Files (x86)\Intel RealSense SDK 2.0"
New-Item -ItemType Directory -Force -Path "$intelDir\lib\x64", "$intelDir\bin\x64", "$intelDir\include" | Out-Null
Copy-Item $vcpkgLib -Destination "$intelDir\lib\x64\realsense2.lib" -Force
Copy-Item $vcpkgDll -Destination "$intelDir\bin\x64\realsense2.dll" -Force
Copy-Item $vcpkgInc -Destination "$intelDir\include\librealsense2" -Recurse -Force
# -----------------------------------------------------------------
# Configure + build. Windows pinned to x64 VS generator (the SDK and
# OpenCV we installed are x64-only).
# -----------------------------------------------------------------
- name: Configure (Windows x64)
if: runner.os == 'Windows'
run: cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release
- name: Configure (Linux / macOS)
if: runner.os != 'Windows'
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- name: Build
run: cmake --build build --config Release --parallel
# -----------------------------------------------------------------
# Package: produce a platform-native installer.
# Linux -> .deb (dpkg-deb, depends on system libgtk-3/libgl/libusb)
# macOS -> .dmg containing a self-contained .app bundle
# Windows -> NSIS .exe installer (Start menu shortcut, Add/Remove entry)
# -----------------------------------------------------------------
- name: Derive version from tag
id: ver
shell: bash
run: |
# ref_name on a tag push is "v1.2.3" — strip leading 'v' to get "1.2.3".
VERSION="${GITHUB_REF_NAME#v}"
# Releases triggered via workflow_dispatch / branch push won't have a v-tag;
# use a 0.0.0+sha fallback so the packaging step still works.
if [[ "$VERSION" == "$GITHUB_REF_NAME" && ! "$GITHUB_REF_NAME" =~ ^[0-9] ]]; then
VERSION="0.0.0-${GITHUB_SHA::7}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Resolved version: $VERSION"
- name: Package (Linux .deb)
if: runner.os == 'Linux'
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
set -euxo pipefail
PKG="ir-tracking-app"
STAGE="$RUNNER_TEMP/deb-staging"
rm -rf "$STAGE"
mkdir -p "$STAGE/DEBIAN" "$STAGE/usr/bin" "$STAGE/usr/lib/$PKG" \
"$STAGE/usr/share/applications" "$STAGE/usr/share/icons/hicolor/256x256/apps"
# Binary + bundled libs under /usr/lib/<pkg>/ with $ORIGIN rpath.
cp build/ir-tracking-app "$STAGE/usr/lib/$PKG/"
# Bundle the application's private compute libraries — RealSense,
# OpenCV, and whatever THOSE pull in (TBB, protobuf, image codecs, ...)
# — so the package never relies on the host shipping the exact sonames
# we built against. Those drift across Ubuntu 22.04/24.04/26.04
# (libtbb.so.2 -> .so.12, libprotobuf.so.23 absent on 26.04, etc.).
#
# We compute this set as the *dependency closure of the RealSense +
# OpenCV libraries only*, not of the whole binary. That deliberately
# excludes the GL / X11 / Wayland / GTK / C++-runtime stack (the binary
# links those directly, but RealSense/OpenCV do not depend on them), so
# we can never accidentally bundle e.g. libgtk-3 and break the user's
# desktop integration. Those host libraries come from Depends instead.
# (The previous hand-written allow-list missed libprotobuf.so.23 and
# crashed on any host without it.)
mapfile -t ROOTS < <(ldd build/ir-tracking-app \
| awk '/=> \// && /lib(realsense2|opencv)/ { print $3 }' | sort -u)
declare -A SEEN
queue=("${ROOTS[@]}")
while ((${#queue[@]})); do
cur="${queue[0]}"; queue=("${queue[@]:1}")
if [[ -n "${SEEN[$cur]:-}" ]]; then continue; fi
SEEN["$cur"]=1
while read -r dep; do
if [[ -n "$dep" && -z "${SEEN[$dep]:-}" ]]; then queue+=("$dep"); fi
done < <(ldd "$cur" 2>/dev/null | awk '/=> \//{print $3}')
done
# Copy the closure, except the host C/C++/system runtime (ABI-stable
# and present on every target — bundling an older copy would be wrong).
RUNTIME='^(ld-linux|libc|libm|libdl|libpthread|librt|libresolv|libstdc\+\+|libgcc_s|libatomic|libz|liblzma|libzstd|libbz2|libudev|libusb-1\.0|libcrypt)\.'
for lib in "${!SEEN[@]}"; do
base="$(basename "$lib")"
if printf '%s' "$base" | grep -qE "$RUNTIME"; then continue; fi
cp -L "$lib" "$STAGE/usr/lib/$PKG/"
done
# $ORIGIN rpath on the binary AND every bundled lib. RUNPATH does not
# propagate to a library's *own* dependencies, so without rpath on the
# bundled .so files their private deps (libopencv_core -> libtbb.so.2,
# libopencv_dnn -> libprotobuf.so.23) would be searched only on the
# host and fail wherever those sonames are gone.
patchelf --set-rpath '$ORIGIN' "$STAGE/usr/lib/$PKG/ir-tracking-app"
shopt -s nullglob # don't iterate a literal '*.so*' if the closure were ever empty
for so in "$STAGE/usr/lib/$PKG/"*.so*; do
patchelf --set-rpath '$ORIGIN' "$so"
done
shopt -u nullglob
# Launcher shim on PATH.
cat > "$STAGE/usr/bin/$PKG" <<SH
#!/usr/bin/env bash
exec /usr/lib/$PKG/ir-tracking-app "\$@"
SH
chmod 0755 "$STAGE/usr/bin/$PKG"
# Desktop entry so the app shows in app launchers.
cat > "$STAGE/usr/share/applications/$PKG.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=IR Tracking App
Comment=Intel RealSense IR retro-reflective marker tracking
Exec=$PKG
Icon=$PKG
Categories=Science;Graphics;
Terminal=false
EOF
# App icon for desktop launchers (the .desktop above references it by
# name). Extract the 256px frame from the multi-resolution .ico.
icotool -x -w 256 -h 256 \
-o "$STAGE/usr/share/icons/hicolor/256x256/apps/$PKG.png" \
resources/app_icon.ico
# RealSense udev rules so a NON-root user can access the camera. Without
# these the USB device nodes are root-only and the app just reports
# "No RealSense devices found" even with a camera attached. Shipped by
# Intel's librealsense2-udev-rules (installed on the runner) and
# reloaded by the postinst below.
RULES_SRC="$(ls /lib/udev/rules.d/60-librealsense2-udev-rules.rules \
/usr/lib/udev/rules.d/60-librealsense2-udev-rules.rules 2>/dev/null | head -1)"
install -Dm644 "$RULES_SRC" \
"$STAGE/lib/udev/rules.d/60-librealsense2-udev-rules.rules"
# postinst/postrm: reload udev so the rules take effect without a reboot.
cat > "$STAGE/DEBIAN/postinst" <<'SH'
#!/bin/sh
set -e
if command -v udevadm >/dev/null 2>&1; then
udevadm control --reload-rules || true
udevadm trigger || true
fi
# Refresh the icon cache / desktop database so the launcher entry and
# icon appear without a re-login.
command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache -q -f /usr/share/icons/hicolor 2>/dev/null || true
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q /usr/share/applications 2>/dev/null || true
exit 0
SH
cat > "$STAGE/DEBIAN/postrm" <<'SH'
#!/bin/sh
set -e
if command -v udevadm >/dev/null 2>&1; then
udevadm control --reload-rules || true
fi
exit 0
SH
chmod 0755 "$STAGE/DEBIAN/postinst" "$STAGE/DEBIAN/postrm"
# dpkg control metadata. Depends covers the host-provided runtime libs
# we deliberately do NOT bundle (the GL/GTK/X11/C++-runtime/USB stack).
# Names are the Ubuntu 22.04 ones; on 24.04/26.04 the t64 packages
# (e.g. libgtk-3-0t64) satisfy them via Provides, so one .deb installs
# on all three. libopengl0 provides libOpenGL.so.0, which the binary
# links directly — its omission was the original launch crash.
INSTALLED_KB=$(du -sk "$STAGE" --exclude=DEBIAN | cut -f1)
cat > "$STAGE/DEBIAN/control" <<EOF
Package: $PKG
Version: $VERSION
Section: graphics
Priority: optional
Architecture: amd64
Maintainer: Tianyu Song <tianyu@medivis.com>
Homepage: https://github.com/stytim/RealSense-ToolTracker
Depends: libc6, libstdc++6, libgcc-s1, libgtk-3-0, libgl1, libopengl0, libx11-6, libusb-1.0-0, libudev1, zlib1g
Installed-Size: $INSTALLED_KB
Description: Intel RealSense IR retro-reflective marker tool tracker
Tracks passive IR sphere markers from an Intel RealSense camera and
publishes the tool pose over UDP. See the GitHub README for usage.
EOF
OUT="${PKG}_${VERSION}_amd64.deb"
dpkg-deb --build --root-owner-group "$STAGE" "$OUT"
ls -lh "$OUT"
dpkg-deb -I "$OUT"
- name: Package (macOS .dmg)
if: runner.os == 'macOS'
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
set -euxo pipefail
APP_NAME="IR Tracking App"
# CMake now emits the .app bundle directly (Info.plist + icon already
# baked in). Self-contain it with dylibbundler and stamp the version.
BUILT_APP="build/ir-tracking-app.app"
test -d "$BUILT_APP" || { echo "Expected $BUILT_APP from the CMake build"; exit 1; }
APP_DIR="$RUNNER_TEMP/$APP_NAME.app"
rm -rf "$APP_DIR"
cp -R "$BUILT_APP" "$APP_DIR"
mkdir -p "$APP_DIR/Contents/Frameworks"
# Bundle dylibs into Contents/Frameworks/, with install names rewritten
# to @executable_path/../Frameworks/ so the .app is self-contained.
dylibbundler -od -b \
-x "$APP_DIR/Contents/MacOS/ir-tracking-app" \
-d "$APP_DIR/Contents/Frameworks" \
-p "@executable_path/../Frameworks/" \
|| true
# Stamp the release version into the CMake-generated Info.plist.
PLIST="$APP_DIR/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $VERSION" "$PLIST"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION" "$PLIST"
# Compose the DMG. UDZO = zlib-compressed read-only.
DMG_NAME="ir-tracking-app-${VERSION}-${{ matrix.label }}.dmg"
DMG_STAGING="$RUNNER_TEMP/dmg-staging"
rm -rf "$DMG_STAGING"
mkdir -p "$DMG_STAGING"
cp -R "$APP_DIR" "$DMG_STAGING/"
# Drag-to-/Applications affordance — a symlink the user can drop on.
ln -s /Applications "$DMG_STAGING/Applications"
hdiutil create \
-volname "$APP_NAME $VERSION" \
-srcfolder "$DMG_STAGING" \
-ov \
-format UDZO \
"$DMG_NAME"
ls -lh "$DMG_NAME"
- name: Package (Windows .exe installer)
if: runner.os == 'Windows'
shell: pwsh
env:
VERSION: ${{ steps.ver.outputs.version }}
run: |
$ErrorActionPreference = 'Stop'
# Stage every file that needs to end up in C:\Program Files\<App>\
$stage = "$env:RUNNER_TEMP\nsis-payload"
if (Test-Path $stage) { Remove-Item -Recurse -Force $stage }
New-Item -ItemType Directory -Force -Path $stage | Out-Null
$exe = "build\Release\ir-tracking-app.exe"
if (-not (Test-Path $exe)) { $exe = "build\ir-tracking-app.exe" }
Copy-Item $exe -Destination $stage
# Pull realsense2.dll and its vcpkg transitive deps (lz4.dll, etc.)
# straight from vcpkg's bin/ — the Intel-SDK restage dir only has
# realsense2.dll itself, which leaves the app missing lz4.dll at runtime.
$vcpkgBin = "C:\vcpkg\installed\x64-windows\bin"
Get-ChildItem -Path $vcpkgBin -Filter "*.dll" | Copy-Item -Destination $stage
$opencvBin = Join-Path $env:OpenCV_DIR "x64\vc16\bin"
Get-ChildItem -Path $opencvBin -Filter "opencv_world*.dll" `
| Where-Object { $_.Name -notmatch "d\.dll$" } `
| Copy-Item -Destination $stage
# NSIS comes preinstalled on windows-2022 runners under C:\Program Files (x86)\NSIS.
$makensis = "C:\Program Files (x86)\NSIS\makensis.exe"
if (-not (Test-Path $makensis)) {
choco install nsis -y --no-progress
}
if (-not (Test-Path $makensis)) {
throw "NSIS (makensis.exe) not found after install attempt."
}
$version = $env:VERSION
# NSIS's OutFile is resolved relative to the .nsi file's directory,
# so use an absolute path anchored at the workspace root — that
# way the upload-artifact glob can find it.
$outFileName = "ir-tracking-app-$version-${{ matrix.label }}-setup.exe"
$outFileAbs = Join-Path (Get-Location).Path $outFileName
$outFileNsi = $outFileAbs.Replace('\','\\')
$nsiPath = "$env:RUNNER_TEMP\installer.nsi"
$stageNsi = $stage.Replace('\','\\')
# NSIS script — install to Program Files\IR Tracking App, Start Menu
# shortcut + uninstaller + Add/Remove Programs entry.
$nsi = @"
!define APPNAME "IR Tracking App"
!define APPID "ir-tracking-app"
!define VERSION "$version"
!define COMPANY "Medivis"
!define DESCRIPTION "Intel RealSense IR retro-reflective marker tool tracker"
!define REGKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\`${APPID}"
Name "`${APPNAME} `${VERSION}"
OutFile "$outFileNsi"
Unicode true
InstallDir "`$PROGRAMFILES64\`${APPNAME}"
InstallDirRegKey HKLM "Software\`${APPNAME}" "InstallDir"
RequestExecutionLevel admin
ShowInstDetails show
ShowUninstDetails show
Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles
Section "Install"
SetOutPath "`$INSTDIR"
File /r "$stageNsi\\*"
CreateDirectory "`$SMPROGRAMS\`${APPNAME}"
CreateShortcut "`$SMPROGRAMS\`${APPNAME}\`${APPNAME}.lnk" "`$INSTDIR\ir-tracking-app.exe"
CreateShortcut "`$SMPROGRAMS\`${APPNAME}\Uninstall.lnk" "`$INSTDIR\Uninstall.exe"
WriteUninstaller "`$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\`${APPNAME}" "InstallDir" "`$INSTDIR"
WriteRegStr HKLM "`${REGKEY}" "DisplayName" "`${APPNAME}"
WriteRegStr HKLM "`${REGKEY}" "DisplayVersion" "`${VERSION}"
WriteRegStr HKLM "`${REGKEY}" "Publisher" "`${COMPANY}"
WriteRegStr HKLM "`${REGKEY}" "DisplayIcon" '"`$INSTDIR\ir-tracking-app.exe"'
WriteRegStr HKLM "`${REGKEY}" "UninstallString" '"`$INSTDIR\Uninstall.exe"'
WriteRegDWORD HKLM "`${REGKEY}" "NoModify" 1
WriteRegDWORD HKLM "`${REGKEY}" "NoRepair" 1
SectionEnd
Section "Uninstall"
Delete "`$INSTDIR\Uninstall.exe"
RMDir /r "`$INSTDIR"
Delete "`$SMPROGRAMS\`${APPNAME}\`${APPNAME}.lnk"
Delete "`$SMPROGRAMS\`${APPNAME}\Uninstall.lnk"
RMDir "`$SMPROGRAMS\`${APPNAME}"
DeleteRegKey HKLM "`${REGKEY}"
DeleteRegKey HKLM "Software\`${APPNAME}"
SectionEnd
"@
Set-Content -Path $nsiPath -Value $nsi -Encoding UTF8
& $makensis $nsiPath
if ($LASTEXITCODE -ne 0) { throw "makensis failed (exit $LASTEXITCODE)." }
Get-Item $outFileAbs | Format-List Length, Name
# -----------------------------------------------------------------
# Upload the installer for the release job to collect.
# -----------------------------------------------------------------
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ir-tracking-app-${{ matrix.label }}
path: |
*.deb
*.dmg
*-setup.exe
if-no-files-found: error
retention-days: 7
release:
name: Publish GitHub Release
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -lh artifacts
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
fail_on_unmatched_files: true