Skip to content

Commit c2ce23d

Browse files
authored
ci: expand build.yml to 4-arch matrix (amd64, arm64, armhf, riscv64) (#73)
1 parent 8ba873f commit c2ce23d

1 file changed

Lines changed: 142 additions & 69 deletions

File tree

.github/workflows/build.yml

Lines changed: 142 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,36 @@
11
# =============================================================================
2-
# Build and Test Workflow for libppd (x86_64 / ubuntu-latest)
2+
# Multi-Architecture Build & Test Workflow for libppd
33
#
4-
# Modelled on the libcupsfilters CI in the sister OpenPrinting repository.
5-
# Scope is intentionally restricted to a single native architecture
6-
# (x86_64 on ubuntu-latest) so the build runs quickly and deterministically
7-
# while still proving:
4+
# Modelled on the QEMU-based CI used in the sister OpenPrinting repositories
5+
# (libcupsfilters, cups-filters). Proves on every push / PR / manual dispatch
6+
# that libppd compiles end-to-end (libppd.la + every check_PROGRAMS binary)
7+
# and that every registered TEST in Makefile.am passes under
8+
# `make check V=1 VERBOSE=1` on FOUR architectures:
89
#
9-
# * The complete repository compiles end-to-end (libppd.la plus all
10-
# declared programs and tests under check_PROGRAMS) — not just that
11-
# the test binaries link against an already-built library.
12-
# * All registered TESTS pass (the 8 native C unit tests added in this
13-
# cycle: testppd, test_ppd_localize, test_ppd_cache, test_ppd_ipp,
14-
# test_ppd_mark, test_ppd_custom, test_ppd_attr, test_ppd_page,
15-
# test_ppd_conflicts). test_ppd_load_profile is intentionally
16-
# deregistered in Makefile.am pending mentor review of a latent
17-
# bug in ppdLutLoad().
10+
# * amd64 - native, ubuntu-latest
11+
# * arm64 - native, ubuntu-24.04-arm
12+
# * armhf - emulated via QEMU (armv7)
13+
# * riscv64 - emulated via QEMU
1814
#
19-
# The apt package list was derived from a direct scan of configure.ac:
15+
# The hermetic C unit tests exercised: testppd, test_ppd_localize,
16+
# test_ppd_cache, test_ppd_ipp, test_ppd_mark, test_ppd_custom,
17+
# test_ppd_attr, test_ppd_page, test_ppd_conflicts.
2018
#
21-
# * PKG_CHECK_MODULES([LIBCUPSFILTERS], [libcupsfilters]) -> libcupsfilters-dev
22-
# * PKG_CHECK_MODULES([ZLIB], [zlib]) -> zlib1g-dev
23-
# * AC_PATH_TOOL(CUPSCONFIG, [cups-config]) (cups3 absent
24-
# on ubuntu-latest, falls back to libcups2) -> libcups2-dev
25-
# * AC_CHECK_PROG(CUPS_GHOSTSCRIPT, gs) -> ghostscript
26-
# * AC_CHECK_PROG(CUPS_PDFTOPS, pdftops) -> poppler-utils
27-
# * AC_CHECK_PROG(CUPS_MUTOOL, mutool) -> mupdf-tools
28-
# * pdftocairo (Poppler renderer) -> poppler-utils
29-
# * AM_GNU_GETTEXT([external]) / AM_ICONV -> gettext, autopoint
30-
# * AC_PROG_CC, AC_PROG_CXX, AX_CXX_COMPILE_STDCXX([11]) -> build-essential
31-
# * LT_INIT -> libtool
32-
# * PKG_PROG_PKG_CONFIG -> pkg-config
33-
# * AC_PROG_INSTALL -> (provided by build-essential)
34-
#
35-
# All three of ghostscript / poppler-utils / mupdf-tools are installed so
36-
# the default ./configure (no --disable-* flags) succeeds — that gives us
37-
# the maximum-coverage build the user asked for ("comprehensive build,
38-
# rather than just checking if the unit tests run").
19+
# apt package list derived from libppd's configure.ac:
20+
# PKG_CHECK_MODULES([LIBCUPSFILTERS]) -> libcupsfilters-dev
21+
# PKG_CHECK_MODULES([ZLIB]) -> zlib1g-dev
22+
# AC_PATH_TOOL(CUPSCONFIG) -> libcups2-dev
23+
# AC_CHECK_PROG(gs / pdftops / mutool) -> ghostscript, poppler-utils,
24+
# mupdf-tools
25+
# AM_GNU_GETTEXT([external]) -> gettext, autopoint
26+
# AC_PROG_CC / CXX / LT_INIT / pkg-config -> build-essential, autoconf,
27+
# automake, libtool,
28+
# libtool-bin, pkg-config
29+
# transitive (poppler / qpdf renderers) -> libqpdf-dev, libpoppler-dev,
30+
# libpoppler-cpp-dev
3931
# =============================================================================
4032

41-
name: Build and Test (libppd)
33+
name: Build and Test (libppd, multi-arch)
4234

4335
on:
4436
push:
@@ -51,73 +43,154 @@ on:
5143

5244
jobs:
5345
build:
54-
name: Build & Test (x86_64)
55-
runs-on: ubuntu-latest
46+
name: Build & Test (${{ matrix.arch }})
47+
runs-on: ${{ matrix.runs-on }}
48+
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
include:
53+
- arch: amd64
54+
runs-on: ubuntu-latest
55+
use-qemu: false
56+
- arch: arm64
57+
runs-on: ubuntu-24.04-arm
58+
use-qemu: false
59+
- arch: armhf
60+
runs-on: ubuntu-latest
61+
use-qemu: true
62+
qemu-arch: armv7
63+
- arch: riscv64
64+
runs-on: ubuntu-latest
65+
use-qemu: true
66+
qemu-arch: riscv64
5667

5768
steps:
5869
- name: Checkout repository
5970
uses: actions/checkout@v4
6071

72+
- name: Save workspace directory
73+
run: echo "REPO_DIR=$(pwd)" >> $GITHUB_ENV
74+
6175
# -----------------------------------------------------------------------
62-
# System dependencies — derived from configure.ac (see header comment).
76+
# NATIVE LEG (amd64 on ubuntu-latest, arm64 on ubuntu-24.04-arm)
6377
# -----------------------------------------------------------------------
64-
- name: Install build & runtime dependencies
78+
- name: Install dependencies (native)
79+
if: matrix.use-qemu == false
6580
run: |
6681
set -ex
67-
sudo apt-get update --fix-missing -y
82+
sudo apt-get clean
83+
sudo apt-get update --fix-missing -y -o Acquire::Retries=3
84+
# Drop any pre-shipped libppd-dev so our local build wins
85+
sudo apt-get remove -y libppd-dev || true
6886
sudo apt-get install -y --no-install-recommends \
6987
build-essential \
7088
autoconf \
7189
automake \
7290
autopoint \
7391
libtool \
92+
libtool-bin \
7493
pkg-config \
7594
gettext \
95+
git \
96+
wget \
97+
tar \
7698
libcups2-dev \
7799
libcupsfilters-dev \
100+
libqpdf-dev \
101+
libpoppler-dev \
102+
libpoppler-cpp-dev \
78103
zlib1g-dev \
79104
ghostscript \
80105
poppler-utils \
81106
mupdf-tools
82107
83-
# -----------------------------------------------------------------------
84-
# Full build — autogen.sh regenerates configure / Makefile.in from the
85-
# autotools sources; configure runs without --disable-* flags so every
86-
# external renderer (gs / pdftops / mutool / pdftocairo) is exercised;
87-
# make -j$(nproc) builds the library AND every check_PROGRAMS binary,
88-
# surfacing any compiler errors or warnings as build output.
89-
# -----------------------------------------------------------------------
90-
- name: autogen.sh
91-
run: ./autogen.sh
92-
93-
- name: configure
94-
run: ./configure
95-
96-
- name: make
97-
run: make -j$(nproc) V=1
108+
- name: Build & test libppd (native)
109+
if: matrix.use-qemu == false
110+
run: |
111+
set -ex
112+
cd "$REPO_DIR"
113+
./autogen.sh
114+
./configure
115+
make -j$(nproc) V=1
116+
make check V=1 VERBOSE=1 || {
117+
echo "==== test-suite.log ===="
118+
test -f test-suite.log && cat test-suite.log
119+
echo "==== per-test logs ===="
120+
for f in $(find . -name '*.log' -not -name 'config.log'); do
121+
echo "---- $f ----"; cat "$f"
122+
done
123+
exit 1
124+
}
98125
99126
# -----------------------------------------------------------------------
100-
# Run the registered TESTS. V=1 and VERBOSE=1 expose both the
101-
# compile-line per object AND each test's stderr in the workflow log
102-
# on failure, matching the libcupsfilters CI pattern. We deliberately
103-
# do NOT pipe stderr away — a failing test prints its full diagnostic
104-
# before the step exits non-zero, and the test-suite.log artifact (see
105-
# next step) preserves the full automake summary for download.
127+
# EMULATED LEG (armhf via QEMU armv7, riscv64 via QEMU)
106128
# -----------------------------------------------------------------------
107-
- name: make check
108-
id: check
109-
run: make check V=1 VERBOSE=1
129+
- name: Set up QEMU
130+
if: matrix.use-qemu == true
131+
uses: docker/setup-qemu-action@v3
132+
with:
133+
platforms: ${{ matrix.qemu-arch }}
134+
135+
- name: Build & test libppd (emulated)
136+
if: matrix.use-qemu == true
137+
uses: uraimo/run-on-arch-action@v3
138+
with:
139+
arch: ${{ matrix.qemu-arch }}
140+
distro: ubuntu24.04
141+
dockerRunArgs: |
142+
--volume "${{ github.workspace }}:/workspace"
143+
install: |
144+
apt-get clean
145+
apt-get update --fix-missing -y -o Acquire::Retries=3
146+
DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
147+
apt-get remove -y libppd-dev 2>/dev/null || true
148+
apt-get install -y --no-install-recommends \
149+
build-essential \
150+
gcc g++ \
151+
autoconf \
152+
automake \
153+
autopoint \
154+
libtool \
155+
libtool-bin \
156+
pkg-config \
157+
gettext \
158+
git \
159+
wget \
160+
tar \
161+
libcups2-dev \
162+
libcupsfilters-dev \
163+
libqpdf-dev \
164+
libpoppler-dev \
165+
libpoppler-cpp-dev \
166+
zlib1g-dev \
167+
ghostscript \
168+
poppler-utils \
169+
mupdf-tools
170+
run: |
171+
set -ex
172+
cd /workspace
173+
./autogen.sh
174+
./configure
175+
make -j$(nproc) V=1
176+
make check V=1 VERBOSE=1 || {
177+
echo "==== test-suite.log ===="
178+
test -f test-suite.log && cat test-suite.log
179+
echo "==== per-test logs ===="
180+
for f in $(find . -name '*.log' -not -name 'config.log'); do
181+
echo "---- $f ----"; cat "$f"
182+
done
183+
exit 1
184+
}
110185
111186
# -----------------------------------------------------------------------
112-
# Artifact upload — only fires when `make check` failed. Captures the
113-
# top-level test-suite.log automake produces plus any per-test .log /
114-
# .trs files so the failure can be diagnosed offline.
187+
# ARTIFACT UPLOAD (all four legs, only on failure)
115188
# -----------------------------------------------------------------------
116-
- name: Upload test-suite.log on failure
117-
if: failure() && steps.check.conclusion == 'failure'
189+
- name: Upload test logs on failure
190+
if: failure()
118191
uses: actions/upload-artifact@v4
119192
with:
120-
name: libppd-test-suite-log-x86_64
193+
name: libppd-test-logs-${{ matrix.arch }}
121194
path: |
122195
test-suite.log
123196
**/*.log

0 commit comments

Comments
 (0)