Build Pipeline
Build Engines
Two reusable workflows handle all builds. They share the same runner setup and KAS invocation but differ in what happens with the output.
buildkas-target.yaml — development builds
Used by onpush-scarthgap.yaml, manual-scarthgap.yaml, schedule-pvtests.yaml, and manual-pvtests.yaml.
- Runs
kas buildinside the KAS container on a self-hosted runner. - Copies build artifacts to GitHub Actions artifacts (wic images, pvrexports, SDK, pvtest-distro).
- Does not upload to S3 and does not create a GitHub Release.
buildkas-upload.yaml — release builds
Used by release.yaml (tag builds only).
- Same build steps as
buildkas-target.yaml. - Additionally calls
upload.shto push artifacts to S3 and updatereleases.json.
Runner environment
| Detail | Value |
|---|---|
| Runner label | self-hosted |
| Container image | ghcr.io/pantacor/kas/kas:next-v7 |
| sstate cache | /shared/sstate (Docker volume shared) |
| Download dir | /shared/dldir (Docker volume shared) |
| Build user | builder (non-root, container switches with su - builder) |
| Temp dir | tmp-scarthgap |
Artifacts
Every build produces some subset of the following:
| Artifact name | Contents | Engine |
|---|---|---|
<target>-<machine> | wic flash image (*.rootfs.wic*) | both |
pvrexports-<machine> | pvrexport tarballs (*pvrexport.tgz) | both |
pantavisor-bsp-<machine> | BSP pvrexport only | both |
pvtest-distro-<machine> | unpacked appengine distro directory | both |
tezi-<target>-<machine> | Toradex TEZI image (*pv_teziimg.tar.xz) | both |
sdk-artifact-<machine> | Yocto SDK installer (panta*.sh) | both |
S3 Distribution (upload.sh)
upload.sh is called by buildkas-upload.yaml once per machine. It:
- Bundles the wic image and pvrexports into a tarball.
- Pushes the bundle to
s3://<BUCKET>/meta-pantavisor/<TAG>/<MACHINE>/. - Reads the existing
releases.jsonfrom S3, appends an entry for this machine/tag, and writes it back.
releases.json is the discovery index used by the Pantavisor ecosystem to find the latest image URLs and SHA256 checksums.
S3 path layout
s3://<BUCKET>/meta-pantavisor/
<tag>/
<machine>/ ← bundle for this specific tag + machine
latest/
stable/
badges/ ← per-machine badge JSON, updated after every stable tag build
release-candidate/
badges/ ← per-machine badge JSON, updated after every RC tag build
Stable vs release-candidate classification
upload.sh and upload-badges both check whether the tag contains -rc:
| Tag pattern | Classification | S3 latest path |
|---|---|---|
028, 029 | stable | latest/stable/ |
028-rc1, 028-rc9 | release-candidate | latest/release-candidate/ |
CI Badges (upload-badges)
After all build jobs finish, the summary job in release.yaml calls upload-badges. The script:
- Queries the GitHub API for all jobs in the current run that match
contains("build ("). - Maps each job's conclusion to a shields.io color (
brightgreen/red/lightgrey/yellow). - Writes a JSON file per machine:
{"schemaVersion":1,"label":"<machine>","message":"passing","color":"brightgreen"}. - Uploads each JSON to
s3://<BUCKET>/meta-pantavisor/latest/<stable|release-candidate>/badges/<machine>.json. - Uploads a
tag.jsonbadge showing the tag name.
The badge URLs in README.md and docs/ci/status.md point to these S3 objects via https://img.shields.io/endpoint?url=<S3-URL>. Shields.io fetches the JSON on render and produces an SVG badge.
pvtests Pipeline
pvtests run against the docker-x86_64-scarthgap appengine distro image. They require a dedicated pvtest-runner runner with Docker available.
The call-pvtests.yaml reusable workflow:
- Downloads the
pvtest-distro-docker-x86_64-scarthgapartifact. - Installs Docker images via
test.docker.sh install-docker. - Runs
test.docker.sh run <test_path>with--retry 3for remote tests. - Appends the SUMMARY section of
test.docker.logto the step summary. - Uploads the pvtest workspace (logs, valgrind output) as an artifact.
- Cleans up Docker containers and images.
test_path controls which tests run:
local— tests that run entirely on the runner (no network to Pantahub)remote— tests that connect to Pantahub (requirePH_USER/PH_PASSsecrets)- empty — run all tests
In release.yaml, pvtest-remote runs with if: always() so it executes even if pvtest-local fails, and its results don't block the summary job.
Component Auto-Updates
schedule-updates.yaml runs update-components.sh every 8 hours. The script reads .github/scripts/components.json, which lists each tracked component with its recipe glob, upstream branch, and GitHub org. For each component:
- Fetches the latest commit SHA from the upstream branch via
git ls-remote. - If the SHA differs from the current
SRCREVin the recipe, updates the recipe in-place. - Appends a short git log to the commit message body for review.
If any updates were found, the workflow opens (or force-updates) a PR on auto-update/components.