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
99 changes: 63 additions & 36 deletions .github/workflows/build-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ name: Build Check
# A workflow_dispatch with no `refs` input, or the weekly schedule, sweeps
# all references.
#
# Each reference builds for its default target (default_target, else the
# first concrete supported_targets entry, else qemuarm64). A workflow_dispatch
# with a `targets` input builds every listed target for every selected
# reference instead, and `targets: all` builds each reference for every
# target in its own supported_targets list. Pairs the reference does not list
# in supported_targets are skipped with a notice. PRs and the schedule always
# use the default target.
#
# There is deliberately NO skip-list: a reference that cannot install or
# build goes red, every run, until the underlying problem (usually a
# missing package in the target's feed) is fixed. Red is the signal.
Expand All @@ -26,6 +34,10 @@ on:
description: Space-separated reference dirs to build (empty = all)
type: string
default: ""
targets:
description: Space-separated targets, or "all" for each reference's supported_targets (empty = default target)
type: string
default: ""
schedule:
# Weekly full sweep, Monday 06:00 UTC.
- cron: "0 6 * * 1"
Expand All @@ -44,7 +56,7 @@ jobs:
name: Detect references to build
runs-on: ubuntu-latest
outputs:
refs: ${{ steps.list.outputs.refs }}
pairs: ${{ steps.list.outputs.pairs }}
steps:
- uses: actions/checkout@v5
with:
Expand All @@ -57,6 +69,7 @@ jobs:
EVENT: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
INPUT_REFS: ${{ inputs.refs }}
INPUT_TARGETS: ${{ inputs.targets }}
run: |
set -euo pipefail
list_all() {
Expand All @@ -81,20 +94,57 @@ jobs:
out="$(list_all)"
;;
esac
json="$(printf '%s\n' $out | jq -R . | jq -sc 'map(select(length > 0))')"
echo "refs to build: $json"
echo "refs=$json" >> "$GITHUB_OUTPUT"
REFS="$out" python3 - <<'EOF'
import json, os, yaml

# dict.fromkeys drops repeats, which would collide on artifact names.
requested = list(dict.fromkeys(os.environ.get("INPUT_TARGETS", "").split()))
pairs = []
for ref in dict.fromkeys(os.environ["REFS"].split()):
try:
y = yaml.safe_load(open(f"{ref}/avocado.yaml")) or {}
except Exception as e:
# Keep the ref in the matrix so it fails in its own build job
# and does not block the other refs.
print(f"::warning title=unreadable config::{ref}: {e}")
explicit = [t for t in requested if t != "all"]
pairs += [{"ref": ref, "target": t} for t in explicit or ["qemuarm64"]]
continue
st = y.get("supported_targets")
targets = requested
if requested == ["all"]:
# "*" or a missing list cannot be expanded; use the default target.
targets = [s for s in st if s and s != "*"] if isinstance(st, list) else []
if not targets:
print(f"::notice title=all targets::{ref} has no explicit supported_targets, using its default target")
if not targets:
t = y.get("default_target")
if not t or t == "*":
t = next((s for s in st if s and s != "*"), None) if isinstance(st, list) else None
pairs.append({"ref": ref, "target": t or "qemuarm64"})
continue
for t in targets:
if isinstance(st, list) and "*" not in st and t not in st:
print(f"::notice title=skipped::{ref} does not support {t}")
continue
pairs.append({"ref": ref, "target": t})

out = json.dumps(pairs)
print(f"pairs to build: {out}")
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"pairs={out}\n")
EOF

build:
name: ${{ matrix.ref }}
name: ${{ matrix.ref }} (${{ matrix.target }})
needs: detect
if: needs.detect.outputs.refs != '[]'
if: needs.detect.outputs.pairs != '[]'
strategy:
# One failing reference must not stop the others — every changed
# reference reports its own result.
fail-fast: false
matrix:
ref: ${{ fromJSON(needs.detect.outputs.refs) }}
include: ${{ fromJSON(needs.detect.outputs.pairs) }}
runs-on: ubuntu-latest
# The heavy references (nvidia-*, jetson-trt, python-whisper) pull
# multi-GB feeds and docker images; give them room but cap a wedged
Expand Down Expand Up @@ -122,34 +172,11 @@ jobs:
- name: Install avocado CLI
uses: avocado-linux/actions/setup-avocado-cli@v1

- name: Resolve target
id: target
working-directory: ${{ matrix.ref }}
# Same resolution rule as scripts/build-check-references.sh:
# default_target if concrete, else the first concrete
# supported_targets entry, else qemuarm64.
run: |
target="$(python3 - <<'EOF'
import yaml
y = yaml.safe_load(open("avocado.yaml")) or {}
t = y.get("default_target")
if not t or t == "*":
st = y.get("supported_targets")
if isinstance(st, list):
t = next((s for s in st if s and s != "*"), None)
else:
t = None
print(t or "qemuarm64")
EOF
)"
echo "target: $target"
echo "target=$target" >> "$GITHUB_OUTPUT"

- name: avocado install (one retry)
id: install
working-directory: ${{ matrix.ref }}
env:
TARGET: ${{ steps.target.outputs.target }}
TARGET: ${{ matrix.target }}
run: |
set -uo pipefail
avocado clean -f >/dev/null 2>&1 || true
Expand All @@ -165,7 +192,7 @@ jobs:
id: build
working-directory: ${{ matrix.ref }}
env:
TARGET: ${{ steps.target.outputs.target }}
TARGET: ${{ matrix.target }}
# No retry: a build failure after a clean install is a real result.
run: avocado build --no-tui --target "$TARGET"

Expand All @@ -174,7 +201,7 @@ jobs:
if: always()
env:
REF: ${{ matrix.ref }}
TARGET: ${{ steps.target.outputs.target }}
TARGET: ${{ matrix.target }}
INSTALL_OUTCOME: ${{ steps.install.outcome }}
BUILD_OUTCOME: ${{ steps.build.outcome }}
run: |
Expand All @@ -189,7 +216,7 @@ jobs:
else result="FAIL @ build"; fi
row="| ${REF} | ${TARGET} | ${install_cell} | ${build_cell} | ${result} |"
mkdir -p results
printf '%s\n' "$row" > "results/${REF}.row"
printf '%s\n' "$row" > "results/${REF}--${TARGET}.row"
{
echo "| Reference | Target | install | build | Result |"
echo "|-----------|--------|:-------:|:-----:|--------|"
Expand All @@ -200,7 +227,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v6
with:
name: result-${{ matrix.ref }}
name: result-${{ matrix.ref }}--${{ matrix.target }}
path: results/
retention-days: 14

Expand All @@ -222,7 +249,7 @@ jobs:
report:
name: Aggregate report
needs: [detect, build]
if: always() && needs.detect.outputs.refs != '[]'
if: always() && needs.detect.outputs.pairs != '[]'
runs-on: ubuntu-latest
steps:
- name: Download result rows
Expand Down
Loading