Skip to content

Commit ce5fd48

Browse files
committed
Add wolfCOSE and wolfIP compatibility checks
1 parent 88c766b commit ce5fd48

4 files changed

Lines changed: 215 additions & 25 deletions

File tree

.github/workflows/cross-library.yml

Lines changed: 119 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ name: cross-library (reusable)
22

33
# Reusable engine for compile-testing a downstream wolfSSL product against the
44
# wolfSSL in this checkout. It builds wolfSSL once from this checkout (the PR
5-
# merge commit) with the flags a product needs, then compiles the product
6-
# against that install at both the product's default-branch HEAD and its highest
7-
# release tag (compile-only, no `make check`).
5+
# merge commit), then builds the product against that install at both the
6+
# product's default-branch HEAD and its highest release tag. A caller can also
7+
# select an inline Makefile build/test sequence for a project whose native CI
8+
# uses one.
89
#
910
# The wolfSSL build runs once and is shared: the build-wolfssl job installs
1011
# wolfSSL and uploads it as an artifact, and the compile matrix (head, latest)
@@ -32,8 +33,14 @@ on:
3233
default: ''
3334
type: string
3435
script:
35-
description: 'Build script name under .github/workflows/cross-library/scripts/'
36-
required: true
36+
description: 'Build script name under .github/workflows/cross-library/scripts/; defaults to <product>.sh in script mode'
37+
required: false
38+
default: ''
39+
type: string
40+
build_mode:
41+
description: 'Build implementation: script (default) or makefile (inline in this workflow)'
42+
required: false
43+
default: 'script'
3744
type: string
3845
apt_packages:
3946
description: 'Extra apt packages needed to build the product'
@@ -240,31 +247,91 @@ jobs:
240247
echo "Resolved ${{ matrix.ref_mode }} ref for $REPO: $ref"
241248
echo "ref=$ref" >> "$GITHUB_OUTPUT"
242249
243-
# Compile-only (never `make check`). A compile failure is allowed ONLY if
244-
# a wolfSSL commit since the last release tag declared it with a
245-
# `breaks-<product>=<ref>` token (see check-break.sh); otherwise the job
246-
# fails, forcing intentional breaks to be recorded in a commit.
250+
# Build the product. Script-mode products use their existing adapters;
251+
# Makefile-mode products run the same commands as their native CI here so
252+
# their integration is reviewable without a second product-specific file.
253+
# A build failure is allowed ONLY if a wolfSSL commit since the last release
254+
# tag declared it with a breaks-<product>=<ref> token (see check-break.sh);
255+
# otherwise the job fails, forcing intentional breaks to be recorded in a
256+
# commit. The output gates the optional maintained-HEAD smoke test.
247257
# PRODUCT_CONFIGURE is intentionally unquoted so multiple flags split.
248258
- name: Compile ${{ inputs.product }} against wolfSSL
259+
id: product_build
249260
env:
261+
BUILD_MODE: ${{ inputs.build_mode }}
250262
REPO: ${{ inputs.repo }}
251263
PRODUCT_CONFIGURE: ${{ inputs.product_configure }}
252264
PRODUCT: ${{ inputs.product }}
265+
PRODUCT_SCRIPT: ${{ inputs.script }}
253266
REF: ${{ steps.ref.outputs.ref }}
254267
MODE: ${{ matrix.ref_mode }}
255268
run: |
256269
S=.github/workflows/cross-library/scripts
257270
set +e
258-
# shellcheck disable=SC2086 # $PRODUCT_CONFIGURE must word-split into flags
259-
"$S/${{ inputs.script }}" -t "$REF" \
260-
"$GITHUB_WORKSPACE/wolfssl-install" "$REPO" $PRODUCT_CONFIGURE
271+
(
272+
set -euo pipefail
273+
case "$BUILD_MODE:$PRODUCT" in
274+
script:*)
275+
# Keep the allowed adapter list explicit: workflow_call inputs
276+
# must not select an arbitrary executable from the checkout.
277+
product_script="${PRODUCT_SCRIPT:-${PRODUCT}.sh}"
278+
case "$product_script" in
279+
wolfclu.sh|wolfmqtt.sh|wolfpkcs11.sh|wolfprovider.sh|wolfssh.sh|wolftpm.sh)
280+
;;
281+
*)
282+
echo "::error::unsupported cross-library product script: $product_script"
283+
exit 2
284+
;;
285+
esac
286+
# shellcheck disable=SC2086 # $PRODUCT_CONFIGURE must word-split into flags
287+
"$S/$product_script" -t "$REF" \
288+
"$GITHUB_WORKSPACE/wolfssl-install" "$REPO" $PRODUCT_CONFIGURE
289+
;;
290+
makefile:wolfcose)
291+
case "$REPO" in
292+
*://*|git@*) product_url="$REPO" ;;
293+
*) product_url="https://github.com/${REPO}.git" ;;
294+
esac
295+
git clone --depth 1 --branch "$REF" "$product_url" wolfCOSE
296+
cd wolfCOSE
297+
# Match wolfCOSE's hosted Makefile build, explicitly using the
298+
# staged wolfSSL instead of a host /usr/local installation.
299+
cflags="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os"
300+
cflags+=" -Wall -Wextra -Wpedantic -Wshadow -Wconversion"
301+
cflags+=" -Wvla -Werror=vla -ffunction-sections -fdata-sections -fstack-usage"
302+
cflags+=" -I./include -isystem $GITHUB_WORKSPACE/wolfssl-install/include"
303+
ldflags="-L$GITHUB_WORKSPACE/wolfssl-install/lib -Wl,-rpath,$GITHUB_WORKSPACE/wolfssl-install/lib -lwolfssl"
304+
make "-j$(nproc)" CFLAGS="$cflags" LDFLAGS="$ldflags"
305+
;;
306+
makefile:wolfip)
307+
case "$REPO" in
308+
*://*|git@*) product_url="$REPO" ;;
309+
*) product_url="https://github.com/${REPO}.git" ;;
310+
esac
311+
git clone --depth 1 --branch "$REF" "$product_url" wolfip
312+
cd wolfip
313+
# wolfIP v1.0 predates generic WOLFSSL_PREFIX support on Linux,
314+
# so point its header probe and link step at the staged install.
315+
export WOLFSSL_PREFIX="$GITHUB_WORKSPACE/wolfssl-install"
316+
export PKG_CONFIG_PATH="$WOLFSSL_PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
317+
export EXTRA_CFLAGS="${EXTRA_CFLAGS:+$EXTRA_CFLAGS }-I$WOLFSSL_PREFIX/include"
318+
export LDFLAGS="${LDFLAGS:+$LDFLAGS }-L$WOLFSSL_PREFIX/lib -Wl,-rpath,$WOLFSSL_PREFIX/lib"
319+
make "-j$(nproc)" build/test-wolfssl
320+
;;
321+
*)
322+
echo "::error::unsupported cross-library build mode/product: $BUILD_MODE/$PRODUCT"
323+
exit 2
324+
;;
325+
esac
326+
)
261327
rc=$?
262328
set -e
263329
264330
# The breaks-<product>= mechanism applies ONLY to the latest release
265331
# tag. A head/master break is never waivable, never consults the
266332
# ledger, and must be fixed.
267333
if [ "$rc" -eq 0 ]; then
334+
echo "compiled=true" >> "$GITHUB_OUTPUT"
268335
if [ "$MODE" = "latest" ] && "$S/check-break.sh" "$PRODUCT" "$REF" >/tmp/brk 2>/dev/null; then
269336
echo "::warning::$PRODUCT ($REF) compiled OK but a break is still declared, remove the stale breaks-$PRODUCT=$REF token:"
270337
cat /tmp/brk
@@ -277,6 +344,7 @@ jobs:
277344
if [ "$MODE" = "latest" ]; then
278345
# Released, immutable tag: allowed only if the exact tag is declared.
279346
if "$S/check-break.sh" "$PRODUCT" "$REF"; then
347+
echo "compiled=false" >> "$GITHUB_OUTPUT"
280348
echo "::warning::$PRODUCT $REF failed to compile, but this break is DECLARED (see above). Treating as a known/tracked break."
281349
exit 0
282350
fi
@@ -295,3 +363,42 @@ jobs:
295363
echo " * putting up a matching fix on $PRODUCT's $REF branch, then re-running this job."
296364
fi
297365
exit 1
366+
367+
# The Makefile-mode smoke suite covers the maintained default-branch HEAD,
368+
# after a real successful build. Older releases retain compile-only
369+
# coverage because their own runtime suites may not support the current
370+
# wolfSSL baseline.
371+
- name: Run ${{ inputs.product }} smoke tests
372+
if: ${{ inputs.build_mode == 'makefile' && matrix.ref_mode == 'head' && steps.product_build.outputs.compiled == 'true' }}
373+
env:
374+
PRODUCT: ${{ inputs.product }}
375+
WOLFSSL_INSTALL: ${{ github.workspace }}/wolfssl-install
376+
run: |
377+
set -euxo pipefail
378+
case "$PRODUCT" in
379+
wolfcose)
380+
cd "$GITHUB_WORKSPACE/wolfCOSE"
381+
export LD_LIBRARY_PATH="$WOLFSSL_INSTALL/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
382+
cflags="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os"
383+
cflags+=" -Wall -Wextra -Wpedantic -Wshadow -Wconversion"
384+
cflags+=" -Wvla -Werror=vla -ffunction-sections -fdata-sections -fstack-usage"
385+
cflags+=" -I./include -isystem $WOLFSSL_INSTALL/include"
386+
ldflags="-L$WOLFSSL_INSTALL/lib -Wl,-rpath,$WOLFSSL_INSTALL/lib -lwolfssl"
387+
make test CFLAGS="$cflags" LDFLAGS="$ldflags"
388+
make tool-test CFLAGS="$cflags" LDFLAGS="$ldflags"
389+
;;
390+
wolfip)
391+
cd "$GITHUB_WORKSPACE/wolfip"
392+
export WOLFSSL_PREFIX="$WOLFSSL_INSTALL"
393+
export PKG_CONFIG_PATH="$WOLFSSL_PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
394+
export EXTRA_CFLAGS="${EXTRA_CFLAGS:+$EXTRA_CFLAGS }-I$WOLFSSL_PREFIX/include"
395+
export LDFLAGS="${LDFLAGS:+$LDFLAGS }-L$WOLFSSL_PREFIX/lib -Wl,-rpath,$WOLFSSL_PREFIX/lib"
396+
export LD_LIBRARY_PATH="$WOLFSSL_PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
397+
make "-j$(nproc)" unit-esp
398+
./build/test/unit-esp
399+
;;
400+
*)
401+
echo "::error::unsupported cross-library smoke test"
402+
exit 1
403+
;;
404+
esac

.github/workflows/cross-library/README.md

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
# Cross-library compile testing
1+
# Cross-library compatibility testing
22

33
Compile tests the wolfSSL product family (wolfSSH, wolfCLU, wolfTPM, wolfMQTT,
4-
wolfPKCS11, wolfProvider) against **this** wolfSSL, so a wolfSSL change that
5-
would stop a downstream product from *compiling* is caught in CI.
6-
7-
**Compile only. There is no runtime testing here** (the product scripts run
8-
`make`, never `make check`). Each product is built twice: at the HEAD of its
9-
default branch and at its latest tagged release.
4+
wolfPKCS11, wolfProvider, wolfCOSE, wolfIP) against **this** wolfSSL, so a
5+
wolfSSL change that would stop a downstream product from *compiling* is caught
6+
in CI.
7+
8+
Each product is built twice: at the HEAD of its default branch and at its
9+
latest tagged release. Most products use a small product adapter. wolfCOSE and
10+
wolfIP use their native Makefile commands inline in the reusable workflow and
11+
also run deterministic, unprivileged smoke tests after a successful HEAD build.
12+
Release tags retain compile-only coverage because their older runtime suites may
13+
not support the current wolfSSL baseline; privileged/network-emulator tests
14+
remain in those products' own CI.
1015

1116
> Note: the workflow `.yml` files (the reusable engine `cross-library.yml` and
1217
> the per-product `cross-<product>.yml` callers) live in `.github/workflows/`
1318
> itself, because GitHub only discovers workflows directly in that directory,
14-
> not in subfolders. Everything else (these scripts) lives here.
19+
> not in subfolders. Shared helpers and legacy product adapters live here.
1520
1621
## Layout
1722

@@ -35,11 +40,14 @@ The engine (`cross-library.yml`) runs one job in a clean container
3540
required `wolfssl_configure` flags and installs it to a local dir.
3641
4. **`resolve-ref.sh`** resolves the ref to build: the highest version tag
3742
(`ref_mode: latest`) or the default branch (`ref_mode: head`).
38-
5. **`<product>.sh`** clones the product at that ref and compiles it against the
39-
installed wolfSSL (`--with-wolfssl=<install dir>`).
43+
5. The selected build mode clones the product at that ref and compiles it
44+
against the installed wolfSSL. Script mode uses `<product>.sh`; Makefile mode
45+
keeps the product's native build commands inline in `cross-library.yml`.
4046
6. If the compile fails, **`check-break.sh`** decides whether it was a
4147
*declared* break (allowed, tracked) or an *undeclared* one (job fails). See
4248
below.
49+
7. A Makefile-mode caller runs its inline smoke suite only after a successful
50+
default-branch HEAD build. A smoke-test failure is always a failure.
4351

4452
## Scripts
4553

@@ -50,7 +58,8 @@ The engine (`cross-library.yml`) runs one job in a clean container
5058
| `resolve-ref.sh <repo> <mode>` | Echo the ref for `head` (default branch) or `latest` (highest tag). |
5159
| `latest-tag.sh <repo>` | Poll the highest version tag (`git ls-remote --sort=-v:refname`, robust to mixed tag styles). |
5260
| `check-break.sh <product> <ref>` | Break declaration check (see below). |
53-
| `<product>.sh [-t <ref>] <install> <repo> [product_configure...]` | Per-product build. Most just call `cross_build_autotools`; `wolfprovider.sh` also passes `--with-openssl`. |
61+
| `<product>.sh [-t <ref>] <install> <repo> [product_configure...]` | Per-product build adapter for script mode. Most just call `cross_build_autotools`; `wolfprovider.sh` also passes `--with-openssl`. |
62+
| Inline `makefile` cases in `cross-library.yml` | Native Makefile build and maintained-HEAD smoke commands for wolfCOSE and wolfIP. |
5463

5564
## Break declarations
5665

@@ -93,6 +102,9 @@ Because the token names the exact tag, it automatically stops matching once the
93102
product releases a newer tag, forcing a fresh, explicit declaration if the new
94103
release is still broken.
95104

105+
Break declarations apply only to compile compatibility. If the maintained
106+
product HEAD compiles and then its optional smoke test fails, the job is red.
107+
96108
The failure message depends on which leg broke:
97109

98110
- **`latest` (a released tag)**: the tag is immutable, so the job explains the
@@ -107,8 +119,11 @@ The failure message depends on which leg broke:
107119

108120
1. Copy an existing `cross-<product>.yml` caller and set `product`, `repo`,
109121
`wolfssl_configure` (the wolfSSL flags that product documents), optional
110-
`product_configure`, `script`, and optional `apt_packages`.
111-
2. Add a `scripts/<product>.sh`. If it is a standard autotools project, it is
122+
`product_configure`, `script`, and optional `apt_packages`. Script mode is
123+
the default and uses `scripts/<product>.sh` when `script` is omitted; set
124+
`script` explicitly only when its filename differs.
125+
2. Add a `scripts/<product>.sh` for script mode. If it is a standard autotools
126+
project, it is
112127
just:
113128
```sh
114129
#!/usr/bin/env bash
@@ -118,6 +133,10 @@ The failure message depends on which leg broke:
118133
```
119134
Non-autotools products (see `wolfprovider.sh`) can `_prepare "$@"` and then
120135
run their own build steps.
136+
3. For a project whose own CI is Makefile-based, set `build_mode: makefile` and
137+
add an explicitly allowlisted inline build and maintained-HEAD smoke case to
138+
`cross-library.yml`. Keep privileged, hardware, and network-emulator flows
139+
in the downstream project.
121140

122141
Get each product's required `wolfssl_configure` from that product's own
123142
README or CI, not by guessing. The flags matter (e.g. wolfPKCS11 and
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: wolfCOSE cross-library
2+
3+
# START OF COMMON SECTION
4+
on:
5+
push:
6+
branches: [ 'release/**' ]
7+
pull_request:
8+
types: [opened, synchronize, reopened, ready_for_review]
9+
branches: [ '*' ]
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
permissions:
16+
contents: read
17+
# END OF COMMON SECTION
18+
19+
jobs:
20+
cross-library:
21+
uses: ./.github/workflows/cross-library.yml
22+
with:
23+
product: wolfcose
24+
repo: wolfSSL/wolfCOSE
25+
# Match wolfCOSE's complete supported algorithm configuration.
26+
wolfssl_configure: >-
27+
--enable-ecc --enable-ed25519 --enable-ed448 --enable-curve25519
28+
--enable-curve448 --enable-aesgcm --enable-aesccm --enable-aescbc
29+
--enable-sha384 --enable-sha512 --enable-keygen --enable-hkdf
30+
--enable-aeskeywrap --enable-chacha --enable-poly1305 --enable-mldsa
31+
--enable-rsapss
32+
# wolfCOSE's native CI is Makefile-based; keep the matching commands
33+
# inline in the reusable workflow rather than in a product shell adapter.
34+
build_mode: makefile

.github/workflows/cross-wolfip.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: wolfIP cross-library
2+
3+
# START OF COMMON SECTION
4+
on:
5+
push:
6+
branches: [ 'release/**' ]
7+
pull_request:
8+
types: [opened, synchronize, reopened, ready_for_review]
9+
branches: [ '*' ]
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
permissions:
16+
contents: read
17+
# END OF COMMON SECTION
18+
19+
jobs:
20+
cross-library:
21+
uses: ./.github/workflows/cross-library.yml
22+
with:
23+
product: wolfip
24+
repo: wolfSSL/wolfip
25+
# Match wolfIP's standard Linux CI configuration.
26+
wolfssl_configure: --enable-all --enable-md5
27+
# wolfIP's native CI is Makefile-based; keep the matching commands
28+
# inline in the reusable workflow rather than in a product shell adapter.
29+
build_mode: makefile
30+
apt_packages: check

0 commit comments

Comments
 (0)