mirror of
https://github.com/meshtastic/firmware.git
synced 2026-08-01 10:58:30 -04:00
* Package meshtasticd for Windows as an MSI Adds a --service flag connecting meshtasticd to the Service Control Manager, a WiX MSI installing it as an auto-start LocalSystem service with config in %ProgramData%\Meshtastic, and a CI step attaching the MSI to releases. * Address review comments Bind workflow expressions to env vars in run: bodies, and build the service status per call with an atomic checkpoint. * Fix service stop state and CI lint Latch the stop under a mutex so a startup report cannot walk the state back. Ignore the new workflows in semgrep and checkov, as main_matrix already is. * Drop the checkov ignore for the winget workflow Resolve the newest release inside the job instead of taking workflow_dispatch inputs, so CKV_GHA_7 no longer fires and checkov stays active on the file. * Carry the MSI architecture into the winget manifest Parse it from the asset name instead of defaulting to x64, and fail on a multi-arch release rather than validating one at random. * Restore release/.gitignore * Leave the main matrix alone Release attachment moves to the matrix rework in #11151. The MSI is still built and uploaded as a CI artifact. --------- Co-authored-by: Austin <vidplace7@gmail.com>
166 lines
6.2 KiB
YAML
166 lines
6.2 KiB
YAML
name: Build Windows Binary
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
windows_ver:
|
|
required: false
|
|
default: "2025"
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
build-Windows:
|
|
runs-on: windows-${{ inputs.windows_ver }}
|
|
# Only pushes to the default branch (develop) populate the cache; PR / merge_group runs
|
|
# restore it but never save, so they stop filling up the repo's Actions cache storage.
|
|
env:
|
|
SAVE_CACHE: ${{ github.event_name == 'push' && github.ref_name == github.event.repository.default_branch }}
|
|
defaults:
|
|
run:
|
|
# UCRT64 is the MinGW-w64 environment native-windows targets; the `msys`
|
|
# environment would link msys-2.0.dll and produce a Cygwin-style binary.
|
|
shell: msys2 {0}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v7
|
|
with:
|
|
submodules: recursive
|
|
# Keep the token out of .git/config so later steps and artifacts can't leak it.
|
|
persist-credentials: false
|
|
|
|
- name: Setup MSYS2 / UCRT64
|
|
id: msys2
|
|
uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: UCRT64
|
|
update: true
|
|
cache: true
|
|
# argp is not packaged for the mingw environments and is built below.
|
|
# Python is omitted too: MSYS2's reports a `mingw` platform tag no wheel matches.
|
|
install: >-
|
|
mingw-w64-ucrt-x86_64-gcc
|
|
mingw-w64-ucrt-x86_64-pkgconf
|
|
mingw-w64-ucrt-x86_64-yaml-cpp
|
|
mingw-w64-ucrt-x86_64-libuv
|
|
mingw-w64-ucrt-x86_64-jsoncpp
|
|
mingw-w64-ucrt-x86_64-openssl
|
|
mingw-w64-ucrt-x86_64-curl
|
|
mingw-w64-ucrt-x86_64-libusb
|
|
mingw-w64-ucrt-x86_64-cmake
|
|
mingw-w64-ucrt-x86_64-ninja
|
|
git
|
|
|
|
- name: Setup Python
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.14"
|
|
cache: pip
|
|
|
|
# framework-portduino calls argp_parse(); MSYS2 packages argp only for the
|
|
# msys runtime, which cannot link into a native binary. No install() rules.
|
|
- name: Build and install argp-standalone
|
|
run: |
|
|
git clone --depth 1 https://github.com/tom42/argp-standalone /tmp/argp
|
|
cd /tmp/argp
|
|
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release .
|
|
cmake --build build
|
|
cp include/argp-standalone/argp.h /ucrt64/include/argp.h
|
|
cp build/src/libargp-standalone.a /ucrt64/lib/libargp.a
|
|
|
|
- name: Install PlatformIO
|
|
shell: pwsh
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install platformio
|
|
|
|
- name: Restore PlatformIO cache
|
|
id: pio-cache
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
path: ~/.platformio/.cache
|
|
key: pio-windows-${{ inputs.windows_ver }}-${{ hashFiles('platformio.ini', 'variants/native/portduino.ini', 'variants/native/portduino/platformio.ini') }}
|
|
restore-keys: |
|
|
pio-windows-${{ inputs.windows_ver }}-
|
|
|
|
- name: Get release version string
|
|
shell: pwsh
|
|
id: version
|
|
run: echo "long=$(python ./bin/buildinfo.py long)" >> $env:GITHUB_OUTPUT
|
|
|
|
# Runs outside the MSYS2 shell so PlatformIO stays on the runner's
|
|
# CPython; the UCRT64 toolchain is reached through PATH instead.
|
|
- name: Build for Windows
|
|
shell: pwsh
|
|
run: |
|
|
$env:PATH = "${{ steps.msys2.outputs.msys2-location }}\ucrt64\bin;$env:PATH"
|
|
platformio run -e native-windows
|
|
env:
|
|
PKG_VERSION: ${{ steps.version.outputs.long }}
|
|
|
|
- name: Save PlatformIO cache
|
|
if: env.SAVE_CACHE == 'true' && steps.pio-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
path: ~/.platformio/.cache
|
|
key: pio-windows-${{ inputs.windows_ver }}-${{ hashFiles('platformio.ini', 'variants/native/portduino.ini', 'variants/native/portduino/platformio.ini') }}
|
|
|
|
- name: List output files
|
|
run: ls -lah .pio/build/native-windows/
|
|
|
|
# The env links statically, so only Windows system DLLs should appear here.
|
|
# A third-party DLL means the static link regressed.
|
|
- name: Verify the binary is self-contained
|
|
run: |
|
|
set -euo pipefail
|
|
bin=.pio/build/native-windows/meshtasticd.exe
|
|
test -f "$bin"
|
|
# `|| true` keeps grep's no-match exit out of `set -e`; an empty import
|
|
# table is caught by the test below instead of passing as "no deps".
|
|
deps=$(objdump -p "$bin" | grep -i 'DLL Name' || true)
|
|
test -n "$deps"
|
|
extra=$(printf '%s\n' "$deps" \
|
|
| grep -viE 'api-ms-win|KERNEL32|WS2_32|ADVAPI32|USER32|msvcrt|ucrtbase|bcrypt|IPHLPAPI|SHELL32|ole32|CRYPT32|SETUPAPI|CFGMGR32|WINMM|dbghelp' || true)
|
|
if [ -n "$extra" ]; then
|
|
printf '%s\n' "$extra"
|
|
echo "::error::meshtasticd.exe has non-system DLL dependencies (static link regressed)"
|
|
exit 1
|
|
fi
|
|
echo "OK: no third-party DLL dependencies"
|
|
|
|
- name: Smoke test the binary
|
|
run: |
|
|
.pio/build/native-windows/meshtasticd.exe --version
|
|
|
|
- name: Store binaries as an artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: firmware-windows-${{ inputs.windows_ver }}-${{ steps.version.outputs.long }}
|
|
overwrite: true
|
|
path: |
|
|
.pio/build/native-windows/meshtasticd.exe
|
|
|
|
- name: Install WiX
|
|
shell: pwsh
|
|
run: |
|
|
dotnet tool install --global wix --version 5.0.2
|
|
"$env:USERPROFILE\.dotnet\tools" | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8
|
|
& "$env:USERPROFILE\.dotnet\tools\wix.exe" extension add -g WixToolset.Util.wixext/5.0.2
|
|
|
|
- name: Build the MSI and winget manifests
|
|
shell: pwsh
|
|
run: ./bin/build-winget-package.ps1 -ReleaseTag "v$env:LONG_VERSION" -Validate
|
|
env:
|
|
LONG_VERSION: ${{ steps.version.outputs.long }}
|
|
|
|
- name: Store the MSI and winget manifests as an artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: meshtasticd-msi-${{ inputs.windows_ver }}-${{ steps.version.outputs.long }}
|
|
overwrite: true
|
|
path: |
|
|
release/winget/*.msi
|
|
release/winget/manifests/
|