Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/build-firmware.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,40 @@ jobs:
name: qa-firmware-${{ steps.artifact_board.outputs.NAME }}
path: out/**

# Once the dual-slot QA firmware is built, kick off the hardware-lab release-QA in
# coredevices/unicorn against THIS run's qa-firmware artifact (erase -> PRF -> pair -> OTA ->
# functional pass on a real phone + watch), using the most recently tagged coreapp release. The
# unicorn run posts a `unicorn/release-qa` commit status back on this PR's commit. Internal PRs
# only (forks have no secrets); needs UNICORN_DISPATCH_TOKEN — a PAT with actions:write on unicorn.
dispatch-release-qa:
needs: build-qa-firmware
# Org members / collaborators only: author_association is MEMBER for org members, OWNER for the
# repo owner, COLLABORATOR for added collaborators — external contributors (CONTRIBUTOR/NONE) are
# excluded, so an outside PR can't spend the hardware lab.
if: >-
github.event_name == 'pull_request' &&
needs.build-qa-firmware.result == 'success' &&
github.event.pull_request.head.repo.full_name == github.repository &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
runs-on: ubuntu-24.04
# One in-flight QA per PR: a newer push supersedes the older dispatch instead of queueing extras.
concurrency:
group: release-qa-dispatch-${{ github.event.pull_request.number }}
cancel-in-progress: true
Comment on lines +214 to +216

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce per-PR cancellation in the remote workflow

When two pushes reach this job far enough apart for the first dispatch command to finish—the normal case because each run first rebuilds firmware—there is no longer a local job for this concurrency group to cancel. gh workflow run only creates the remote workflow_dispatch event and returns, so the already-dispatched Unicorn run remains queued or running in the other repository and obsolete hardware-lab runs accumulate despite the stated one-in-flight behavior. Deduplication or cancellation needs to be enforced in Unicorn, or this job must explicitly cancel the prior remote run.

Useful? React with 👍 / 👎.

steps:
- name: Dispatch the hardware-lab release-QA (coredevices/unicorn)
env:
GH_TOKEN: ${{ secrets.UNICORN_DISPATCH_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the cross-repository token out of PR-controlled workflows

Because this workflow runs on pull_request, a same-repository PR passes the repository check while its version of this YAML still controls the run step. Such a PR can replace the command with one that exfiltrates GH_TOKEN, gaining the token's cross-repository Actions write access to Unicorn; filtering out forks does not protect against compromised or malicious internal branches. Perform the secret-bearing dispatch from workflow code loaded from the trusted default branch, such as a carefully validated workflow_run workflow.

Useful? React with 👍 / 👎.

run: |
if [ -z "${GH_TOKEN:-}" ]; then
echo "::warning::UNICORN_DISPATCH_TOKEN not set — add a PAT with actions:write on coredevices/unicorn to run the hardware release-QA automatically"
exit 0
fi
# to_pbz_run_id = this Build Firmware run (its qa-firmware-<board> artifact is the "to").
# coreapp_run_id omitted -> unicorn uses the most recently tagged coreapp release.
gh workflow run one-off-pebbleos-test.yml -R coredevices/unicorn \
-f to_pbz_run_id=${{ github.run_id }}

build-firmware-status:
needs: [changes-firmware, build-firmware]
if: always()
Expand Down
Loading