Skip to content

Commit c4edc70

Browse files
Eric Migicovskyclaude
andcommitted
ci: build a dual-slot release PBZ for the QA boards on each PR
The Build Firmware job is single-slot and a debug build, so its PBZ cannot be the 'to' of an upgrade test: OTA writes into the watch's inactive slot (needs both slots), and the watch refuses to apply a debug PBZ over the release 'from'. The hardware-lab release-QA dispatch (coredevices/unicorn) needs a merged dual-slot RELEASE PBZ, the same shape as a release asset. Add build-qa-firmware: for obelix@pvt and getafix@dvt2, build both release slots and merge with tools/merge_pbz.py in one job per board (no cross-job artifact passing), uploading qa-firmware-<board> (the merged normal_<board>_<ver>.pbz + pebbleos_loghash_dict.json). Gated by the same paths-filter as the rest, and kept out of build-firmware-status so a QA-artifact hiccup never blocks a firmware PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Eric Migicovsky <eric@repebble.com>
1 parent 521464b commit c4edc70

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

.github/workflows/build-firmware.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,81 @@ jobs:
118118
"s3://${{ vars.LOG_HASH_BUCKET_NAME }}/${{ steps.build_id.outputs.BUILD_ID }}-${{ github.sha }}-normal.json" \
119119
--endpoint-url "${{ vars.LOG_HASH_BUCKET_ENDPOINT }}"
120120
121+
# Dual-slot RELEASE PBZ for the hardware-lab release-QA boards. The build-firmware job above is
122+
# single-slot AND a debug build, so it cannot be the "to" of an upgrade test: OTA writes into the
123+
# watch's *inactive* slot (needs both slots), and the watch refuses to apply a debug PBZ over the
124+
# release "from". The release-QA dispatch (coredevices/unicorn) needs a merged dual-slot RELEASE
125+
# PBZ, the same shape as a release asset — so build both slots (release) and merge, in one job per
126+
# board, no cross-job artifact passing. Only the two QA-hardware boards; kept out of
127+
# build-firmware-status so a QA-artifact hiccup never blocks a firmware PR.
128+
build-qa-firmware:
129+
needs: changes-firmware
130+
if: needs.changes-firmware.outputs.should-build == 'true'
131+
runs-on: ubuntu-24.04
132+
133+
container:
134+
image: ghcr.io/coredevices/pebbleos-docker:v6
135+
136+
strategy:
137+
matrix:
138+
board:
139+
- obelix@pvt
140+
- getafix@dvt2
141+
142+
steps:
143+
- name: Mark Github workspace as safe
144+
run: git config --system --add safe.directory "${GITHUB_WORKSPACE}"
145+
146+
- name: Checkout
147+
uses: actions/checkout@v5
148+
with:
149+
fetch-depth: 0
150+
submodules: true
151+
152+
- name: Rebase onto target branch
153+
uses: ./.github/actions/rebase
154+
with:
155+
submodules: true
156+
157+
- name: Install Python dependencies
158+
run: |
159+
pip install -U pip
160+
pip install -r requirements.txt
161+
162+
- name: Set artifact board name
163+
id: artifact_board
164+
run: echo "NAME=$(printf '%s' "$BOARD" | tr @ _)" >> "$GITHUB_OUTPUT"
165+
env:
166+
BOARD: ${{ matrix.board }}
167+
168+
- name: Build both release slots and merge into a dual-slot PBZ
169+
run: |
170+
set -euo pipefail
171+
name='${{ steps.artifact_board.outputs.NAME }}'
172+
mkdir -p out
173+
for slot in 0 1; do
174+
./waf configure --board '${{ matrix.board }}' -DCONFIG_FIRMWARE_SLOT=$slot -DCONFIG_RELEASE=y
175+
./waf build
176+
./waf bundle
177+
cp build/normal_*_slot${slot}.pbz .
178+
done
179+
s0=$(ls normal_*_slot0.pbz | head -1)
180+
s1=$(ls normal_*_slot1.pbz | head -1)
181+
# Version string is embedded in the bundle name (git describe), e.g.
182+
# normal_obelix_pvt_v4.35.0-2-gdeadbee_slot0.pbz -> v4.35.0-2-gdeadbee.
183+
ver=$(basename "$s0" | sed -E "s/^normal_${name}_//; s/_slot0\.pbz$//")
184+
python3 tools/merge_pbz.py --slot0-pbz "$s0" --slot1-pbz "$s1" \
185+
--output "out/normal_${name}_${ver}.pbz"
186+
# Ship the loghash dict alongside so the QA fwlog step can dehash release logs.
187+
cp build/pebbleos_loghash_dict.json out/ 2>/dev/null || true
188+
ls -la out
189+
190+
- name: Store merged QA firmware
191+
uses: actions/upload-artifact@v6
192+
with:
193+
name: qa-firmware-${{ steps.artifact_board.outputs.NAME }}
194+
path: out/**
195+
121196
build-firmware-status:
122197
needs: [changes-firmware, build-firmware]
123198
if: always()

0 commit comments

Comments
 (0)