mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
Build and install-test the arm64 package in CI
The arm64 .deb that ships to single-board hosts was floor-checked and never installed anywhere in the pipeline, so a packaging fault that only appears on arm64 would reach a user first. CI's package job becomes a two-leg matrix, building natively on an ubuntu-24.04-arm runner beside the amd64 leg, and each leg fails unless the package it produced is its own architecture. The install job gains one arm64 leg on ubuntu22, the oldest supported distribution: a fresh install and a daemon start. The upgrade, purge and conffile scenarios stay amd64-only. The displayed names of the existing checks are unchanged. The parity guard now reads each install leg's arch. Only amd64 legs are compared with the local distro list; an arm64 leg must name a known distro and is reported as GitHub-only. Without this, deleting the amd64 ubuntu22 leg would have passed, because the arm64 leg still supplied the distro name.
This commit is contained in:
+53
-10
@@ -40,6 +40,10 @@ env:
|
||||
# unreliable on GitHub-hosted runners.
|
||||
# tor-directory — same; live Tor dependency.
|
||||
#
|
||||
# Deliberate GitHub-only: the arm64 install leg (ubuntu22). The local host is
|
||||
# x86_64 and has no arm64 execution; the leg is compared by distribution only
|
||||
# and does not stand in for the amd64 leg of the same distribution.
|
||||
#
|
||||
# The two runners express the same work in different matrix shapes, and the
|
||||
# parity guard compares through that shape rather than around it: chaos legs
|
||||
# are compared per scenario (and per flag) via their `scenario:` field,
|
||||
@@ -787,11 +791,24 @@ jobs:
|
||||
# floor violation stops the run.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
deb-package:
|
||||
name: Build .deb
|
||||
runs-on: ubuntu-latest
|
||||
name: Build .deb${{ matrix.deb_arch == 'arm64' && ' (arm64)' || '' }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [build, test]
|
||||
if: ${{ !inputs.skip_integration }}
|
||||
|
||||
# The arm64 leg builds natively on an arm runner so the arm64 package the
|
||||
# release ships is install-tested too (job 5). Being one job, both legs
|
||||
# gate job 5 and the dns-resolver job: an arm64 build failure skips the
|
||||
# amd64 install legs on that run as well.
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
deb_arch: amd64
|
||||
- os: ubuntu-24.04-arm
|
||||
deb_arch: arm64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
|
||||
@@ -824,11 +841,23 @@ jobs:
|
||||
path: ${{ runner.temp }}/deb-builder-image.tar
|
||||
key: ${{ steps.builder.outputs.key }}
|
||||
|
||||
# The package path is the script's last line of stdout. A leg that
|
||||
# produced the other architecture's package goes red here rather than
|
||||
# handing an amd64 package to the arm64 install leg.
|
||||
- name: Build the .deb in the pinned build container
|
||||
timeout-minutes: 30
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
bash packaging/debian/build-deb-container.sh --output-dir deploy \
|
||||
--image-archive "$RUNNER_TEMP/deb-builder-image.tar"
|
||||
--image-archive "$RUNNER_TEMP/deb-builder-image.tar" \
|
||||
| tee "$RUNNER_TEMP/build-deb-container.log"
|
||||
deb=$(tail -n 1 "$RUNNER_TEMP/build-deb-container.log")
|
||||
[ -f "$deb" ] || { echo "build-deb-container.sh did not name a package: '$deb'" >&2; exit 1; }
|
||||
case "$deb" in
|
||||
*_${{ matrix.deb_arch }}.deb) ;;
|
||||
*) echo "Package $deb is not ${{ matrix.deb_arch }}" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
# On a cache miss the archive exists only if the script built the image
|
||||
# and saved it, so its presence is what says there is something to save.
|
||||
@@ -856,8 +885,8 @@ jobs:
|
||||
- name: Upload the .deb
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: fips-deb
|
||||
path: deploy/fips_*.deb
|
||||
name: fips-deb-${{ matrix.deb_arch }}
|
||||
path: deploy/fips_*_${{ matrix.deb_arch }}.deb
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
@@ -901,7 +930,7 @@ jobs:
|
||||
- name: Download the .deb
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: fips-deb
|
||||
name: fips-deb-amd64
|
||||
path: _deb
|
||||
|
||||
- name: Run dns-resolver test
|
||||
@@ -944,11 +973,12 @@ jobs:
|
||||
#
|
||||
# The legs keep `type: deb-install` and `scenario:` because
|
||||
# testing/check-ci-parity.sh reads those to match this matrix against the local
|
||||
# suite's distro list; the steps below use `scenario:` only.
|
||||
# suite's distro list; it reads `arch:` too, and compares only the amd64 legs
|
||||
# with the local run. The steps below use `scenario:` and `arch:`.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
deb-install:
|
||||
name: Deb install (${{ matrix.scenario }})
|
||||
runs-on: ubuntu-latest
|
||||
name: Deb install (${{ matrix.scenario }}${{ matrix.arch == 'arm64' && ' arm64' || '' }})
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
||||
needs: [deb-package]
|
||||
if: ${{ !inputs.skip_integration }}
|
||||
|
||||
@@ -958,14 +988,27 @@ jobs:
|
||||
include:
|
||||
- type: deb-install
|
||||
scenario: debian12
|
||||
arch: amd64
|
||||
- type: deb-install
|
||||
scenario: debian13
|
||||
arch: amd64
|
||||
- type: deb-install
|
||||
scenario: ubuntu22
|
||||
arch: amd64
|
||||
- type: deb-install
|
||||
scenario: ubuntu24
|
||||
arch: amd64
|
||||
- type: deb-install
|
||||
scenario: ubuntu26
|
||||
arch: amd64
|
||||
# The arm64 package on the oldest supported distribution: a fresh
|
||||
# install and a daemon start. Deliberately GitHub-only (the local host
|
||||
# is x86_64), and deliberately one leg: the upgrade, purge and
|
||||
# conffile paths run under debian12 on amd64 only and stay
|
||||
# unexercised on arm64.
|
||||
- type: deb-install
|
||||
scenario: ubuntu22
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
||||
@@ -973,7 +1016,7 @@ jobs:
|
||||
- name: Download the .deb
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: fips-deb
|
||||
name: fips-deb-${{ matrix.arch }}
|
||||
path: _deb
|
||||
|
||||
- name: Run deb-install scenario
|
||||
|
||||
@@ -283,6 +283,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
warning and a rebuild, never a failed build. A cached image is not refreshed
|
||||
from apt or the base image until the base image name, the toolchain or
|
||||
`Dockerfile.build` changes, as was already true of a developer's machine.
|
||||
- CI now builds the arm64 `.deb` on an arm64 runner and installs it on Ubuntu
|
||||
22.04, the oldest supported distribution, starting the daemon, on every push
|
||||
and pull request. Until now the arm64 package was floor-checked and never
|
||||
installed anywhere in the pipeline. Its upgrade, purge and conffile paths
|
||||
remain unexercised; those run on amd64 only. The parity check reads each
|
||||
install leg's architecture, so the arm64 leg is reported as GitHub-only and
|
||||
cannot stand in for a missing amd64 leg of the same distribution.
|
||||
|
||||
## [0.5.1] - 2026-09-06
|
||||
|
||||
|
||||
@@ -195,8 +195,10 @@ below. **Only the `.deb` is exercised by an install test**, by the
|
||||
`deb-install` suite across debian12, debian13, ubuntu22, ubuntu24 and
|
||||
ubuntu26; neither the AUR package nor the flake is. That suite runs on
|
||||
every push and pull request, on x86_64, against a `.deb` built by the same
|
||||
pinned container as the released one. It does not run at a tag, and the
|
||||
arm64 package is install-tested by nothing: no workflow installs a published
|
||||
pinned container as the released one. The arm64 package, built the same way
|
||||
on an arm64 runner, is installed and its daemon started on ubuntu22 on every
|
||||
push and pull request as well; its upgrade, purge and conffile paths are not
|
||||
exercised. The suite does not run at a tag: no workflow installs a published
|
||||
artifact, so the released packages are checked by
|
||||
hand. OpenWrt is a musl
|
||||
target rather than glibc, and it takes an `.ipk` on 24.x and earlier or
|
||||
|
||||
+3
-1
@@ -110,7 +110,9 @@ it the suite builds one through `packaging/debian/build-deb-container.sh`.
|
||||
|
||||
Installs the built `.deb` in systemd containers for each
|
||||
target distro and verifies unit enablement, conffile placement and
|
||||
end-to-end `.fips` resolution as a user would meet it.
|
||||
end-to-end `.fips` resolution as a user would meet it. GitHub CI also
|
||||
installs the arm64 package on ubuntu22 on an arm64 runner, a leg the
|
||||
local run cannot have and the parity check reports as GitHub-only.
|
||||
|
||||
### [boringtun/](boringtun/) -- WireGuard Throughput Baseline
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
# unreliable on GitHub-hosted runners.
|
||||
# tor-directory — same; live Tor dependency.
|
||||
#
|
||||
# Deliberate GitHub-only (NOT in the local run), with reason:
|
||||
# deb-install ubuntu22 on arm64 — the local host is x86_64 and cannot run an
|
||||
# arm64 package. The GitHub leg installs the arm64 package
|
||||
# and starts the daemon on an arm runner.
|
||||
#
|
||||
# What is compared, and at what granularity:
|
||||
# chaos — per scenario, plus its flags. GitHub fans each scenario
|
||||
# into its own matrix leg carrying `scenario:` (and
|
||||
@@ -21,7 +26,11 @@
|
||||
# deb-install — per distro. GitHub splits into per-distro legs carrying
|
||||
# `scenario:`, in a job of their own; local runs the same
|
||||
# distro set in one suite, enumerated by ALL_SCENARIOS in
|
||||
# deb-install/test.sh.
|
||||
# deb-install/test.sh. A leg's `arch:` defaults to amd64,
|
||||
# and only amd64 legs are compared with the local set, so
|
||||
# an arm64 leg cannot stand in for a missing amd64 leg of
|
||||
# the same distro. An arm64 leg must name a distro the
|
||||
# local suite knows; any other arch is unidentifiable.
|
||||
# everything else — per suite name.
|
||||
#
|
||||
# dns-resolver is the one leg still compared at leg granularity rather than
|
||||
@@ -153,6 +162,10 @@ if not include:
|
||||
f"{ci_yml_path}; cannot verify CI parity", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
github_chaos, github_deb, github = {}, set(), set()
|
||||
# Deliberate GitHub-only install legs on another architecture, by distro. Kept
|
||||
# out of github_deb: were they in it, deleting the amd64 leg of a distro that
|
||||
# also has an arm64 leg would leave the distro in the set and pass.
|
||||
github_deb_extra = {}
|
||||
malformed = []
|
||||
for leg in include:
|
||||
if "suite" not in leg and "scenario" not in leg:
|
||||
@@ -166,8 +179,15 @@ for leg in include:
|
||||
continue
|
||||
if kind == "chaos":
|
||||
github_chaos[str(leg["scenario"])] = str(leg.get("chaos_flags", ""))
|
||||
else:
|
||||
continue
|
||||
arch = str(leg.get("arch", "amd64"))
|
||||
if arch == "amd64":
|
||||
github_deb.add(str(leg["scenario"]))
|
||||
elif arch == "arm64":
|
||||
github_deb_extra.setdefault(arch, set()).add(str(leg["scenario"]))
|
||||
else:
|
||||
malformed.append(f"deb-install leg {leg['scenario']} has arch "
|
||||
f"{arch}, which is neither amd64 nor arm64")
|
||||
elif "suite" in leg:
|
||||
github.add(str(leg["suite"]))
|
||||
else:
|
||||
@@ -233,6 +253,12 @@ chaos_flag_drift = sorted(
|
||||
)
|
||||
deb_local_only = sorted(local_deb - github_deb)
|
||||
deb_github_only = sorted(github_deb - local_deb)
|
||||
# An extra-arch leg for a distro the local suite does not know is still drift.
|
||||
deb_github_only += sorted(
|
||||
f"{d} ({arch})"
|
||||
for arch, distros in github_deb_extra.items()
|
||||
for d in distros - local_deb
|
||||
)
|
||||
|
||||
problems = (local_only or github_only or chaos_local_only or chaos_github_only
|
||||
or chaos_flag_drift or deb_local_only or deb_github_only
|
||||
@@ -290,5 +316,9 @@ print("CI parity OK: both runners cover the same work "
|
||||
print(f" {len(github)} suites, {len(github_chaos)} chaos scenarios "
|
||||
f"(flags compared), {len(github_deb)} deb-install distros "
|
||||
f"— {total} legs on each side.")
|
||||
for arch, distros in sorted(github_deb_extra.items()):
|
||||
legs = "leg" if len(distros) == 1 else "legs"
|
||||
print(f" plus {len(distros)} GitHub-only {arch} install {legs} "
|
||||
f"({', '.join(sorted(distros))}).")
|
||||
sys.exit(0)
|
||||
PY
|
||||
|
||||
@@ -114,6 +114,11 @@
|
||||
# unreliable on GitHub-hosted runners.
|
||||
# tor-directory — same; live Tor dependency.
|
||||
#
|
||||
# Deliberate GitHub-only (NOT in this local run), with reason:
|
||||
# deb-install ubuntu22 on arm64 — this host is x86_64 and cannot run an
|
||||
# arm64 package. The guard compares it by distro only and
|
||||
# does not let it stand in for the amd64 ubuntu22 leg.
|
||||
#
|
||||
# The two runners express the same work in different matrix shapes, and the
|
||||
# guard compares through that shape rather than around it: chaos legs are
|
||||
# compared per scenario (and per flag), deb-install legs per distro. The one
|
||||
|
||||
Reference in New Issue
Block a user