Repository navigation
ci(firmware): build and attach firmware release assets #360
Description
Goal
CI builds the stock firmware images and attaches them — plus a README bundle and a manifest.json — to every firmware-v* GitHub release. Split from #304: this ticket is the pipeline; #304 keeps the sample sketches and the bare-board bench check.
Plan (signed off 2026-10-25)
Workflow — a new reusable .github/workflows/firmware-release-assets.yml:
workflow_call(inputstag,upload) — called by a newfirmware-assetsjob inrelease-please.ymlwhen a Firmware release is created, beside the existingfirmware-dependenciesjob. Only this path publishes, withgh release upload --clobber.pull_request(paths: the workflow itself +Firmware/release/**) — validation only: builds, checks sizes, packages, uploads the package as an Actions artifact. Never touches a release. Iterate here until the output is right.workflow_dispatch(inputsref,dry_run, default true) — a manual validation run against any tag or branch.
Build — existing tools only (PlatformIO, jq, envsubst, sha256sum, zip, gh), set up like the firmware-dependencies job. Explicit project list:
| Project | Board |
|---|---|
Firmware/Templates/SimGateway |
Gateway — RP2040 side |
Firmware/Templates/PanelBridge |
Gateway — STM32 side (PanelBridge) |
Firmware/Panels/PDU_Left / PDU_Right / PDU_Center |
PDU nodes 3 / 4 / 5 |
Firmware/Panels/Center_Armament is excluded (the board is deprecated).
Size validation — PlatformIO already fails a build over its board limit (e.g. the PDUs' maximum_size = 64512 keeps the calibration page free). The job also writes a flash / RAM table per board to the job summary.
Version — the tag minus firmware-v; dev for a validation run off a branch.
Assets
Flat on the release page — for the client (GitHub release assets can't have folders): manifest.json and one file per chip, .bin for STM32, .uf2 for the RP2040:
gateway-<v>.uf2, gateway-bridge-<v>.bin, pdu-left-<v>.bin, pdu-right-<v>.bin, pdu-center-<v>.bin.
One zip for people — folder per board, .elf for STM32 (the flash address is built in, so a hand flash can't land at the wrong address), .uf2 for the RP2040:
openskyhawk-firmware-<v>/
README.md what's in each folder, version rules, GPL note
CHANGES.md this release's notes
LICENSE GPL v2
manifest.json
gateway/ README.md · gateway-<v>.uf2 · gateway-bridge-<v>.elf
pdu-left/ README.md · pdu-left-<v>.elf (node 3)
pdu-right/ README.md · pdu-right-<v>.elf (node 4)
pdu-center/ README.md · pdu-center-<v>.elf (node 5)
No .hex (.elf + .bin cover ST-Link, PlatformIO and STM32CubeProgrammer).
manifest.json — release version; per file: name, board, target (NODE_ID, or the Gateway half), format, size, SHA-256.
README templates — committed under Firmware/release/ (top-level + per-board), placeholders filled with envsubst. One flashing method per board (Gateway: BOOTSEL + drag the UF2, then the bridge over ST-Link; PDU: ST-Link). The top README states that the GPL source for these binaries is the release's source archive of the same tag, and carries a pre-1.0 "don't mix versions across releases" note.
PlatformIO prerequisites (first step)
Templates/PanelBridgetargetsgenericSTM32F103CB; the Gateway PCB carries an STM32F103C8 → switch the build target to C8 (listed separately in the PR'sBEGIN_COMMIT_OVERRIDEso it shows in the changelog).- Third-party dependency pins land with feat(firmware)!: v1.0 freeze fixes — firmware version on the bus, config structs, pinned dependencies (#295) #359 (docs(firmware): v1.0 API + wire-format freeze review and compatibility policy #295 A7). Assets for 0.2.0 are built unpinned — accepted.
- The Gateway's
rpipicobuild is already proven on the Waveshare RP2040-Zero in practice — no change.
Order
Land this → validate on the PR → maintainer merges #321 (firmware-v0.2.0 gets the assets) → then #359.
Done when
- A PR validation run produces the expected zip, flat files and
manifest.json, with the size table in the summary. firmware-v0.2.0carries the assets.- The release's Gateway
.uf2and PanelBridge image flash and come up on the bench. (audit 2026-10-27) Not recorded before this ticket closed (it auto-closed with ci(firmware): build and attach firmware release assets (#360) #368, beforefirmware-v0.2.0existed). Carried to build(firmware): release bundle — sample sketches + prebuilt SimGateway / PanelBridge binaries #304's Done-when (its bare-board check, the single home for it).
Activity
ci(firmware): manual release-asset runs build the selected ref, not a…
ci(firmware): validation runs call the release-asset workflow from a …
ci(firmware): release assets build the caller's commit, never a passe…
ci(firmware): build and attach firmware release assets (#360) (#368)