Skip to content

chore(update): point post-update banner at apl-feed status (#92) #156

chore(update): point post-update banner at apl-feed status (#92)

chore(update): point post-update banner at apl-feed status (#92) #156

name: Image boot
on:
push:
branches: [main, dev]
workflow_dispatch:
inputs:
image_contract:
description: Contract to run (legacy, new, or all)
type: choice
options: [all, legacy, new]
default: all
image_channel:
description: Image release channel to select
required: false
default: stable
image_arch:
description: Image architecture to select
required: false
default: arm64
image_asset_regex:
description: Optional regex used to select the release asset
required: false
default: ''
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
image-boot-smoke:
name: image boot (${{ matrix.image_contract }} contract)
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
image_contract: [legacy, new]
include:
- image_contract: legacy
image_release_repo: airplanes-live/image-releases
runner: ubuntu-24.04-arm
- image_contract: new
image_release_repo: airplanes-live/image
runner: ubuntu-24.04-arm
# Per-cell gating happens at step level: actionlint correctly rejects
# `matrix` context in job-level `if:` (matrix is expanded later in the
# evaluation pipeline). Every step below references this guard so the
# skipped-cell job runs zero meaningful steps.
steps:
- name: Skip this matrix cell if not selected (dispatch input)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.image_contract != 'all' && matrix.image_contract != github.event.inputs.image_contract
run: |
echo "Skipping matrix cell ${{ matrix.image_contract }} — dispatch selected ${{ github.event.inputs.image_contract }}"
exit 0
- name: Checkout feed
if: github.event_name == 'push' || github.event.inputs.image_contract == 'all' || matrix.image_contract == github.event.inputs.image_contract
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install QEMU smoke dependencies
if: github.event_name == 'push' || github.event.inputs.image_contract == 'all' || matrix.image_contract == github.event.inputs.image_contract
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates \
binutils \
cpio \
curl \
gh \
initramfs-tools-core \
git \
jq \
kmod \
parted \
p7zip-full \
qemu-system-arm \
qemu-user-static \
rsync \
file \
unzip \
xz-utils \
zstd
- name: Run image boot
if: github.event_name == 'push' || github.event.inputs.image_contract == 'all' || matrix.image_contract == github.event.inputs.image_contract
env:
GH_TOKEN: ${{ github.token }}
AIRPLANES_IMAGE_RELEASE_REPO: ${{ matrix.image_release_repo }}
AIRPLANES_IMAGE_CONTRACT: ${{ matrix.image_contract }}
# Same channel-vs-event mapping as ci.yml's mounted-image-upgrade-new:
# main-bound runs use stable channel (looks for the stable-named
# asset in stable releases); dev-bound runs use dev channel (looks
# for the dev-named asset, picked up via the rolling dev-latest
# prerelease). Manual dispatch can still override via the input.
AIRPLANES_IMAGE_CHANNEL: ${{ github.event.inputs.image_channel || (github.event_name == 'push' && github.ref == 'refs/heads/main') && 'stable' || 'dev' }}
AIRPLANES_IMAGE_ARCH: ${{ github.event.inputs.image_arch || 'arm64' }}
AIRPLANES_IMAGE_ASSET_REGEX: ${{ github.event.inputs.image_asset_regex || '' }}
# Push to main → only stable releases (production track).
# Push to dev / dispatch → release-any (also picks the rolling
# dev-latest prerelease published by airplanes-live/image's
# build-image.yml).
AIRPLANES_IMAGE_SOURCE_TIERS: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') && 'release-stable' || 'release-any' }}
AIRPLANES_BOOT_SMOKE_WORK_DIR: ${{ runner.temp }}/airplanes-image-boot
# KEEP_WORK_DIR=1 preserves $WORK_DIR/qemu-logs across the script's
# cleanup trap so the failure-artifact upload step below can read
# them. Without this, the cleanup wipes the directory before the
# upload runs.
AIRPLANES_BOOT_SMOKE_KEEP_WORK_DIR: '1'
run: |
sudo --preserve-env=GH_TOKEN,AIRPLANES_IMAGE_RELEASE_REPO,AIRPLANES_IMAGE_CONTRACT,AIRPLANES_IMAGE_CHANNEL,AIRPLANES_IMAGE_ARCH,AIRPLANES_IMAGE_ASSET_REGEX,AIRPLANES_IMAGE_SOURCE_TIERS,AIRPLANES_BOOT_SMOKE_WORK_DIR,AIRPLANES_BOOT_SMOKE_KEEP_WORK_DIR \
bash test/image-boot.sh
- name: Upload QEMU logs on failure
if: failure() && (github.event_name == 'push' || github.event.inputs.image_contract == 'all' || matrix.image_contract == github.event.inputs.image_contract)
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: image-boot-${{ matrix.image_contract }}-logs
path: ${{ runner.temp }}/airplanes-image-boot/qemu-logs
if-no-files-found: warn