Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e8ba1ea
ci: pause non-smoke workflows on draft PRs, add smoke preflight
aidangarske May 23, 2026
c1706da
ci: trim PR matrices and add paths-ignore (Phase A + E1)
aidangarske May 25, 2026
382c487
ci: gate heavy workflows on smoke via wait-for-smoke action (Phase F2)
aidangarske May 25, 2026
41cded3
ci: dynamic wolfSSL latest-stable resolution (Phase G)
aidangarske May 25, 2026
71a618c
ci: add retries, fail-fast: false, and nightly full sweep (Phase D + E2)
aidangarske May 25, 2026
abc0e72
ci: drop nightly-full-sweep.yml
aidangarske May 25, 2026
1f356ff
ci: drop nightly-sweep references from workflow comments
aidangarske May 25, 2026
da865b3
ci: collapse force_fail matrix axis into sequential test runs (Phase B)
aidangarske May 25, 2026
b16c654
ci: bake test deps into ghcr.io/wolfssl/wolfprovider-test-deps (Phase C)
aidangarske May 25, 2026
ab5ab8d
ci: per-owner test-deps image so fork PRs can publish their own (revi…
aidangarske May 25, 2026
b9adb95
docker: drop libunwind-dev; conflicts with libunwind-14-dev on bookworm
aidangarske May 25, 2026
fddae3e
ci: dynamic discover-versions; honest matrix labels (review fix)
aidangarske May 25, 2026
b249331
ci: split OSP integration tests to nightly + add ASan/UBSan
aidangarske May 25, 2026
2b2573d
ci: drop wait_for_smoke gates; PR workflows fire in parallel with smoke
aidangarske May 25, 2026
fb034b6
ci: test wolfSSL master + latest-stable everywhere via the resolver
aidangarske May 25, 2026
47441e1
ci: resolve OpenSSL latest upstream tag too; use it on source-built w…
aidangarske May 25, 2026
38f73c2
ci: make openssl-version.yml track upstream releases dynamically
aidangarske May 25, 2026
328bb0f
ci: openssl-version.yml moves to nightly (58 versions is too much per…
aidangarske May 25, 2026
f8ccb51
ci: fix sssd matrix parser error -- remove dead force_fail exclude
aidangarske May 25, 2026
f1fbf99
ci: drop concurrency: from OSP workflows -- caused mass cancellation
aidangarske May 25, 2026
1d70658
ci: drop fork guard on ghcr ORAS pull -- prevented nightly on forks
aidangarske May 25, 2026
98876f3
ci: publish-test-deps-image.yml: auto-mark package public after push
aidangarske May 25, 2026
04daf8c
ci: revert per-owner / auto-public docker plumbing (packages stay pri…
aidangarske May 25, 2026
fbd9ec7
ci: fire nightly-osp.yml on PR too (temporary, for PR #400 validation)
aidangarske May 25, 2026
cfda41f
ci: publish-test-deps-image.yml -- also fire on aidangarske/wolfProvider
aidangarske May 25, 2026
87f19ff
ci: publish-test-deps-image.yml -- align with bootstrap PR #402
aidangarske May 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/actions/wait-for-smoke/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: 'Wait for Smoke Test'
description: 'Polls the Smoke Test workflow for the current commit and fails if it failed.'

# Designed to be the leading job in pull_request-triggered workflows so that
# expensive integration CI does not run unless the smoke build passes.
#
# Push events bypass the wait entirely (we still get smoke results for those
# pushes, but other CI is not gated on push). For drafts, callers should
# skip dependent jobs via `if: github.event.pull_request.draft == false` -
# this action will still pass through if smoke is skipped or absent.

inputs:
workflow:
description: 'Name of the smoke workflow file to wait on'
required: false
default: 'smoke-test.yml'
timeout-seconds:
description: 'Maximum time to wait for smoke to complete'
required: false
default: '1800'
poll-seconds:
description: 'Polling interval'
required: false
default: '20'
github-token:
description: 'GITHUB_TOKEN with actions:read permission'
required: true

runs:
using: 'composite'
steps:
- name: Wait for smoke
shell: bash
env:
GH_TOKEN: ${{ inputs.github-token }}
SMOKE_WORKFLOW: ${{ inputs.workflow }}
TIMEOUT: ${{ inputs.timeout-seconds }}
POLL: ${{ inputs.poll-seconds }}
REPO: ${{ github.repository }}
run: |
set -u
# Only gate pull_request events. Push events are not gated.
if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "Not a pull_request event - skipping smoke gate."
exit 0
fi

HEAD_SHA="${{ github.event.pull_request.head.sha }}"
echo "Waiting for $SMOKE_WORKFLOW on $HEAD_SHA (timeout ${TIMEOUT}s)"

START=$(date +%s)
while :; do
NOW=$(date +%s)
ELAPSED=$((NOW - START))
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
echo "::error::Timed out after ${TIMEOUT}s waiting for $SMOKE_WORKFLOW on $HEAD_SHA"
exit 1
fi

# Look up the latest run for this workflow + head SHA.
RUN_JSON=$(gh api \
"repos/${REPO}/actions/workflows/${SMOKE_WORKFLOW}/runs?head_sha=${HEAD_SHA}&per_page=1" \
2>/dev/null || echo '{}')

STATUS=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].status // "missing"')
CONCLUSION=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].conclusion // ""')
RUN_URL=$(echo "$RUN_JSON" | jq -r '.workflow_runs[0].html_url // ""')

case "$STATUS" in
completed)
case "$CONCLUSION" in
success)
echo "Smoke test passed: $RUN_URL"
exit 0
;;
skipped|neutral)
echo "Smoke test was $CONCLUSION - treating as pass: $RUN_URL"
exit 0
;;
*)
echo "::error::Smoke test concluded as '$CONCLUSION': $RUN_URL"
exit 1
;;
esac
;;
missing)
echo "[$ELAPSED s] No smoke run yet for $HEAD_SHA"
;;
*)
echo "[$ELAPSED s] Smoke status=$STATUS ($RUN_URL)"
;;
esac

sleep "$POLL"
done
118 changes: 118 additions & 0 deletions .github/workflows/_discover-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Discover wolfSSL + OpenSSL versions

# Reusable workflow that resolves at run time:
# - latest wolfSSL v*-stable tag (from upstream wolfssl/wolfssl)
# - Debian Bookworm's stock OpenSSL version (matches what the
# wolfprov-patched .deb on ghcr.io was built against)
#
# Consumers use these outputs to populate matrix values so the
# matrix labels honestly reflect what the test actually installed.
# Today: latest -> v5.8.4-stable, openssl -> 3.0.20 (Bookworm stock).
# When Bookworm bumps OpenSSL or wolfSSL ships a new -stable, the
# resolver picks it up without a CI edit.

on:
workflow_call:
outputs:
wolfssl_ref:
description: 'Plain string, latest -stable e.g. v5.8.4-stable'
value: ${{ jobs.discover.outputs.wolfssl_ref }}
wolfssl_ref_array:
description: 'JSON array of master + latest -stable for matrix use'
value: ${{ jobs.discover.outputs.wolfssl_ref_array }}
openssl_ref:
description: 'Plain string. Bookworm stock OpenSSL (matches the wolfprov .deb).'
value: ${{ jobs.discover.outputs.openssl_ref }}
openssl_ref_array:
description: 'JSON array form of openssl_ref'
value: ${{ jobs.discover.outputs.openssl_ref_array }}
openssl_latest_ref:
description: 'Plain string, latest upstream openssl-3.x.y release tag (e.g. openssl-3.5.4)'
value: ${{ jobs.discover.outputs.openssl_latest_ref }}
openssl_latest_ref_array:
description: 'JSON array form of openssl_latest_ref'
value: ${{ jobs.discover.outputs.openssl_latest_ref_array }}
openssl_all_releases_array:
description: 'JSON array of every upstream openssl-3.X.Y release tag, sorted ascending. Used by openssl-version.yml so the sweep tracks upstream automatically.'
value: ${{ jobs.discover.outputs.openssl_all_releases_array }}

jobs:
discover:
name: Resolve wolfSSL + OpenSSL refs
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
wolfssl_ref: ${{ steps.resolve.outputs.wolfssl_ref }}
wolfssl_ref_array: ${{ steps.resolve.outputs.wolfssl_ref_array }}
openssl_ref: ${{ steps.resolve.outputs.openssl_ref }}
openssl_ref_array: ${{ steps.resolve.outputs.openssl_ref_array }}
openssl_latest_ref: ${{ steps.resolve.outputs.openssl_latest_ref }}
openssl_latest_ref_array: ${{ steps.resolve.outputs.openssl_latest_ref_array }}
openssl_all_releases_array: ${{ steps.resolve.outputs.openssl_all_releases_array }}
steps:
- name: Resolve versions
id: resolve
run: |
set -euo pipefail

# ---- wolfSSL: highest v*-stable tag from upstream ----
WOLFSSL=$(git ls-remote --tags --refs https://github.com/wolfSSL/wolfssl.git 'v*-stable' \
| awk -F/ '{print $NF}' | sort -V | tail -n 1)
if [ -z "${WOLFSSL:-}" ]; then
echo "::error::Could not resolve latest wolfSSL -stable tag"
exit 1
fi

# ---- OpenSSL (Debian Bookworm stock) ----
# The wolfprov-patched .deb on ghcr.io is built by patching
# Bookworm's stock libssl3 source, so this is the actual
# OpenSSL the Debian-container workflows end up linking against.
# Use docker to ask Bookworm's apt directly, then strip the
# Debian revision (3.0.20-1~deb12u1 -> 3.0.20).
OSSL_RAW=$(docker run --rm debian:bookworm sh -c \
'apt-get update -qq >/dev/null 2>&1 && apt-cache madison openssl | head -1' \
| awk '{print $3}')
if [ -z "${OSSL_RAW:-}" ]; then
echo "::error::Could not resolve Bookworm OpenSSL version"
exit 1
fi
OSSL=$(echo "$OSSL_RAW" | sed 's/-.*//')

# ---- OpenSSL (all upstream release tags, sorted) ----
# Used by openssl-version.yml so the sweep tracks upstream
# automatically as new releases ship. Release-shaped only:
# openssl-X.Y.Z, no -alpha/-beta/-pre. Floored at the
# historical oldest-supported version below so we don't
# silently re-introduce coverage of openssl-3.0.0/3.0.1/3.0.2
# that the static matrix used to exclude.
OSSL_FLOOR="openssl-3.0.3"
OSSL_ALL=$(git ls-remote --tags --refs https://github.com/openssl/openssl.git 'openssl-3.*' \
| awk -F/ '{print $NF}' \
| grep -E '^openssl-3\.[0-9]+\.[0-9]+$' \
| sort -V \
| awk -v floor="$OSSL_FLOOR" '$0 == floor {p=1} p')
if [ -z "${OSSL_ALL:-}" ]; then
echo "::error::Could not resolve upstream OpenSSL release tags (floor=$OSSL_FLOOR)"
exit 1
fi
# JSON array. jq -R reads each line as a string, -s collects
# them into an array, -c emits compact single-line JSON.
OSSL_ALL_JSON=$(printf '%s\n' "$OSSL_ALL" | jq -R . | jq -s -c .)
# Highest version (last after sort -V) is the resolved
# "latest" used by source-built workflows.
OSSL_LATEST=$(echo "$OSSL_ALL" | tail -n 1)

echo "wolfSSL latest -stable: $WOLFSSL (also testing master)"
echo "Bookworm OpenSSL: openssl-$OSSL (raw: $OSSL_RAW)"
echo "Upstream OpenSSL latest: $OSSL_LATEST"
echo "Upstream OpenSSL releases ($(echo "$OSSL_ALL" | wc -l) tags)"

{
echo "wolfssl_ref=$WOLFSSL"
echo "wolfssl_ref_array=[\"master\",\"$WOLFSSL\"]"
echo "openssl_ref=openssl-$OSSL"
echo "openssl_ref_array=[\"openssl-$OSSL\"]"
echo "openssl_latest_ref=$OSSL_LATEST"
echo "openssl_latest_ref_array=[\"$OSSL_LATEST\"]"
echo "openssl_all_releases_array=$OSSL_ALL_JSON"
} >> "$GITHUB_OUTPUT"
55 changes: 26 additions & 29 deletions .github/workflows/bind9.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
name: Bind9 Tests

# START OF COMMON SECTION
on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
# OSP integration test for Bind9 Tests. Runs nightly via the
# Nightly OSP Suite orchestrator (.github/workflows/nightly-osp.yml)
# or manually via workflow_dispatch. NOT triggered on PR/push --
# PR CI focuses on smoke + simple + cheap internal checks.

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# END OF COMMON SECTION
on:
workflow_call: {}
workflow_dispatch: {}

jobs:
discover_versions:
uses: ./.github/workflows/_discover-versions.yml

build_wolfprovider:
needs: discover_versions
uses: ./.github/workflows/build-wolfprovider.yml
with:
wolfssl_ref: ${{ matrix.wolfssl_ref }}
openssl_ref: ${{ matrix.openssl_ref }}
fips_ref: ${{ matrix.fips_ref }}
replace_default: ${{ matrix.replace_default }}
strategy:
fail-fast: false
matrix:
wolfssl_ref: [ 'v5.8.4-stable' ]
openssl_ref: [ 'openssl-3.5.4' ]
wolfssl_ref: ${{ fromJson(needs.discover_versions.outputs.wolfssl_ref_array) }}
openssl_ref: ${{ fromJson(needs.discover_versions.outputs.openssl_ref_array) }}
fips_ref: [ 'FIPS', 'non-FIPS' ]
replace_default: [ true ]

test_bind:
runs-on: ubuntu-22.04
needs: build_wolfprovider
needs: [build_wolfprovider, discover_versions]
container:
image: debian:bookworm
image: ghcr.io/wolfssl/wolfprovider-test-deps:bookworm
env:
DEBIAN_FRONTEND: noninteractive
# This should be a safe limit for the tests to run.
Expand All @@ -40,10 +42,9 @@ jobs:
fail-fast: false
matrix:
bind_ref: [ 'v9.18.28' ]
wolfssl_ref: [ 'v5.8.4-stable' ]
openssl_ref: [ 'openssl-3.5.4' ]
wolfssl_ref: ${{ fromJson(needs.discover_versions.outputs.wolfssl_ref_array) }}
openssl_ref: ${{ fromJson(needs.discover_versions.outputs.openssl_ref_array) }}
fips_ref: [ 'FIPS', 'non-FIPS' ]
force_fail: ['WOLFPROV_FORCE_FAIL=1', '']
replace_default: [ true ]
env:
WOLFSSL_PACKAGES_PATH: /tmp/wolfssl-packages
Expand Down Expand Up @@ -85,16 +86,6 @@ jobs:
${{ matrix.replace_default && '--replace-default' || '' }} \
${{ matrix.fips_ref == 'FIPS' && '--fips' || '' }}

- name: Install bind9 test dependencies
run: |
apt-get update
apt install -y build-essential automake libtool gnutls-bin \
pkg-config make libidn2-dev libuv1-dev libnghttp2-dev libcap-dev \
libjemalloc-dev zlib1g-dev libxml2-dev libjson-c-dev libcmocka-dev \
python3-pytest python3-dnspython python3-hypothesis patch iproute2 \
net-tools git
PERL_MM_USE_DEFAULT=1 cpan -i Net::DNS

- name: Checkout bind9
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -129,7 +120,13 @@ jobs:
make -j$(nproc)
./bin/tests/system/ifconfig.sh up

export ${{ matrix.force_fail }}
# --- normal mode ---
make -j$(nproc) check 2>&1 | tee bind9-test.log
TEST_RESULT=${PIPESTATUS[0]}
$GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $TEST_RESULT "" bind9

# --- force-fail mode ---
export WOLFPROV_FORCE_FAIL=1
make -j$(nproc) check 2>&1 | tee bind9-test.log
TEST_RESULT=${PIPESTATUS[0]}
$GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $TEST_RESULT ${{ matrix.force_fail }} bind9
$GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh $TEST_RESULT "WOLFPROV_FORCE_FAIL=1" bind9
Loading
Loading