Skip to content

feat(status): reorder by data flow, sharpen reception signals #253

feat(status): reorder by data flow, sharpen reception signals

feat(status): reorder by data flow, sharpen reception signals #253

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main, dev]
permissions:
contents: read
jobs:
lint:
name: lint
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install shellcheck
run: |
sudo apt-get update
sudo apt-get install -y shellcheck
- name: Run shellcheck (warning severity)
run: |
find . -name '*.sh' -not -path './.git/*' -print0 \
| xargs -0 shellcheck -S warning
- name: Run bash syntax check
run: |
find . -name '*.sh' -not -path './.git/*' -print0 \
| xargs -0 -n1 bash -n
unit-tests:
name: unit tests
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install bats, jq, curl, python3
run: |
sudo apt-get update
sudo apt-get install -y bats jq curl python3
- name: Run bats suite
run: bats test/
script-install:
name: script install (${{ matrix.image_label }}, ${{ matrix.path }})
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
image:
- debian:13-slim
- ubuntu:24.04
path:
- bundle
- bootstrap
include:
# `image_label` carries the display-friendly form (no `:slim` /
# `:24.04` suffix). Matrix `include:` with a partial match adds
# the new key to all combinations sharing the matched value, so
# each of the 4 cells ends up with both `image` (the actual docker
# tag, load-bearing) and `image_label` (display only).
- image: debian:13-slim
image_label: debian:13
- image: ubuntu:24.04
image_label: ubuntu:24
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Pin local branch ref to HEAD
env:
BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name }}
run: |
current="$(git -C "$PWD" rev-parse --abbrev-ref HEAD)"
if [[ "$current" != "$BRANCH" ]]; then
git -C "$PWD" branch -f "$BRANCH" HEAD
fi
- name: Run script install
env:
FEED_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name }}
IMAGE: ${{ matrix.image }}
TEST_PATH: ${{ matrix.path }}
run: |
docker run --rm \
-e AIRPLANES_FEED_REPO=file:///workspace \
-e AIRPLANES_FEED_BRANCH="$FEED_BRANCH" \
-e AIRPLANES_TEST_PATH="$TEST_PATH" \
-v "$PWD:/workspace:ro" \
"$IMAGE" \
bash /workspace/test/script-install.sh
image-build-mode:
name: image build mode
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Checkout feed
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
path: feed
- name: Checkout image updater
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
repository: airplanes-live/airplanes-update
path: airplanes-update
- name: Run image build mode
run: |
docker run --rm \
-e AIRPLANES_FEED_DIR=/feed \
-e AIRPLANES_UPDATE_DIR=/airplanes-update \
-v "$PWD/feed:/feed:ro" \
-v "$PWD/airplanes-update:/airplanes-update:ro" \
debian:13-slim \
bash /feed/test/image-build-mode.sh
mounted-image-upgrade-legacy:
name: mounted image upgrade (legacy contract)
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Checkout feed
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install image smoke dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gh \
git \
jq \
parted \
p7zip-full \
rsync \
unzip \
xz-utils
- name: Run mounted image upgrade (legacy contract)
env:
# The driver uses the lib/image-source.sh library which reads GH_TOKEN
# (gh CLI convention). github.token is sufficient for cross-repo
# release downloads against the public airplanes-live/image-releases.
GH_TOKEN: ${{ github.token }}
AIRPLANES_IMAGE_RELEASE_REPO: airplanes-live/image-releases
AIRPLANES_IMAGE_CONTRACT: legacy
AIRPLANES_RELEASE_ROOTFS_WORK_DIR: ${{ runner.temp }}/airplanes-mounted-image-upgrade-legacy
run: |
sudo --preserve-env=GH_TOKEN,AIRPLANES_IMAGE_RELEASE_REPO,AIRPLANES_IMAGE_CONTRACT,AIRPLANES_RELEASE_ROOTFS_WORK_DIR \
bash test/mounted-image-upgrade.sh
mounted-image-upgrade-new:
# Mirror of mounted-image-upgrade-legacy, against airplanes-live/image.
# Tier list picks release-stable on PRs targeting main / pushes to main
# (production track), release-any otherwise (development track, which
# accepts the rolling dev-latest prerelease published by airplanes-live/
# image's build-image.yml on every dev push).
name: mounted image upgrade (new contract)
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Checkout feed
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install image smoke dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gh \
git \
jq \
parted \
p7zip-full \
rsync \
unzip \
xz-utils
- name: Run mounted image upgrade (new contract)
env:
GH_TOKEN: ${{ github.token }}
AIRPLANES_IMAGE_RELEASE_REPO: airplanes-live/image
AIRPLANES_IMAGE_CONTRACT: new
# CHANNEL maps the asset name we're looking for:
# stable channel → `airplanes-feeder-stable-arm64.img.xz` (in tagged stable releases)
# dev channel → `airplanes-feeder-dev-arm64.img.xz` (in the rolling dev-latest prerelease)
# When testing against a `main`-bound change we want the stable build;
# otherwise we want the latest dev build (rolling prerelease).
AIRPLANES_IMAGE_CHANNEL: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') && 'stable' || (github.event_name == 'pull_request' && github.base_ref == 'main') && 'stable' || 'dev' }}
AIRPLANES_IMAGE_SOURCE_TIERS: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') && 'release-stable' || (github.event_name == 'pull_request' && github.base_ref == 'main') && 'release-stable' || 'release-any' }}
AIRPLANES_RELEASE_ROOTFS_WORK_DIR: ${{ runner.temp }}/airplanes-mounted-image-upgrade-new
run: |
sudo --preserve-env=GH_TOKEN,AIRPLANES_IMAGE_RELEASE_REPO,AIRPLANES_IMAGE_CONTRACT,AIRPLANES_IMAGE_CHANNEL,AIRPLANES_IMAGE_SOURCE_TIERS,AIRPLANES_RELEASE_ROOTFS_WORK_DIR \
bash test/mounted-image-upgrade.sh
webconfig-drift:
name: webconfig drift
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- name: Checkout feed
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
path: feed
- name: Pin local "dev" branch to PR HEAD
run: |
# Force-label the PR head as "dev" locally so the install path the
# smoke exercises matches what production code paths look for. The
# image's stage-06 release-channel allowlist (and feed update.sh)
# only accepts {main, dev}, so a real PR branch name like
# "feature/foo" would be refused even though it carries the code we
# want under test. Branch labels are local only — origin is unchanged.
# Skip when already on dev (push-to-dev event) — git refuses to
# force-update the worktree's current branch, and the rename would
# be a no-op anyway.
current="$(git -C feed rev-parse --abbrev-ref HEAD)"
if [[ "$current" != "dev" ]]; then
git -C feed branch -f dev HEAD
fi
- name: Checkout image regression harness
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
repository: airplanes-live/image
ref: dev
path: image
- name: Run webconfig drift check against feed PR head
env:
AIRPLANES_FEED_BRANCH: dev
run: bash image/test/update-regression-smoke.sh feed
- name: Upload drift artifacts on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: webconfig-drift-artifacts
path: ${{ runner.temp }}/update-regression
script-upgrade:
name: script upgrade (${{ matrix.source.display }})
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
source:
# `stable` axis tracks origin/main HEAD — the currently-released
# script-installed feeders. Catches regressions in the
# "main → candidate" upgrade path as main moves.
- label: stable
display: stable main
ref: main
# `legacy` axis pins a pre-schema-split commit so historical
# regression coverage survives the dev→main merge that introduces
# the MLAT_USER / MLAT_ENABLED split. Update only when retiring
# the coverage deliberately.
- label: legacy
display: pre-schema-split pin
ref: 9318d02efd70488f831cbcb84ca3ec4cb9cc9ece
steps:
- name: Checkout source (${{ matrix.source.label }})
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ matrix.source.ref }}
path: source
persist-credentials: false
- name: Pin source branch label to main
run: |
current="$(git -C source rev-parse --abbrev-ref HEAD)"
if [[ "$current" != "main" ]]; then
git -C source branch -f main HEAD
fi
- name: Checkout candidate (PR / branch HEAD)
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: candidate
persist-credentials: false
- name: Pin candidate branch label to dev
run: |
# Force-label the candidate as "dev" so update.sh's release-channel
# allowlist accepts it without env-var bypass — same trick the
# webconfig-drift job uses.
current="$(git -C candidate rev-parse --abbrev-ref HEAD)"
if [[ "$current" != "dev" ]]; then
git -C candidate branch -f dev HEAD
fi
- name: Prepare diagnostics directory
run: mkdir -p "${{ runner.temp }}/script-upgrade"
- name: Run script upgrade
run: |
docker run --rm \
-e AIRPLANES_SOURCE_REPO=file:///source \
-e AIRPLANES_CANDIDATE_REPO=file:///candidate \
-v "$PWD/source:/source:ro" \
-v "$PWD/candidate:/candidate:ro" \
-v "${{ runner.temp }}/script-upgrade:/tmp/script-upgrade-diag" \
debian:13-slim \
bash /candidate/test/script-upgrade.sh
- name: Upload diagnostics on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: script-upgrade-diagnostics-${{ matrix.source.label }}
path: ${{ runner.temp }}/script-upgrade