Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 44 additions & 0 deletions .github/actions/build-wolfcert-cli/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-License-Identifier: GPL-3.0-or-later
name: build-wolfcert-cli
description: >
Build wolfSSL (cached, config `full`) and wolfCert with the CLIs and test
server enabled, then export WOLFCERT_BUILD so the interop scripts'
wolfcert_bin() helper resolves wolfcert-client / wolfcert-server.

inputs:
wolfssl-ref:
description: "wolfSSL git ref to build"
required: false
default: master

runs:
using: composite
steps:
- name: Install build dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake pkg-config python3

- name: Build/restore wolfSSL (full)
uses: ./.github/actions/build-wolfssl
with:
config: full
ref: ${{ inputs.wolfssl-ref }}
save: "false" # restore-only: nightly.yml owns the shared `full` cache
# (interop's 5 jobs run concurrently and would otherwise
# race to save the same key).

- name: Build wolfCert (CLIs + server)
shell: bash
run: |
set -euo pipefail
cmake -S . -B build \
-DWITH_WOLFSSL="$WOLFSSL_PREFIX" \
-DWOLFCERT_ENABLE_CLI=ON \
-DWOLFCERT_ENABLE_SERVER=ON
cmake --build build -j "$(nproc)"
echo "WOLFCERT_BUILD=${{ github.workspace }}/build" >> "$GITHUB_ENV"
# wolfCert links wolfSSL from the install prefix; make it findable at
# runtime for the CLI binaries the interop scripts invoke.
echo "LD_LIBRARY_PATH=$WOLFSSL_PREFIX/lib:${LD_LIBRARY_PATH:-}" >> "$GITHUB_ENV"
107 changes: 107 additions & 0 deletions .github/actions/build-wolfssl/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# SPDX-License-Identifier: GPL-3.0-or-later
name: build-wolfssl
description: >
Build and cache a named wolfSSL configuration for wolfCert. The install
prefix is cached (via actions/cache) keyed on the resolved wolfSSL commit
plus a hash of the exact ./configure flags, so a hit skips the whole build.
On pull requests the cache is restore-only; scheduled runs pass save=true to
(re)seed it. Exposes the install prefix as the `prefix` output and the
WOLFSSL_PREFIX environment variable.

inputs:
config:
description: "wolfSSL config name understood by scripts/ci/build-wolfssl.sh"
required: true
ref:
description: "wolfSSL git ref to build (branch, tag or SHA)"
required: false
default: master
save:
description: "Save the cache after a miss (true on scheduled reseed, false on PR)"
required: false
default: "false"

outputs:
prefix:
description: "Absolute path to the wolfSSL install prefix"
value: ${{ steps.meta.outputs.prefix }}
cache-hit:
description: "Whether the wolfSSL prefix was restored from cache"
value: ${{ steps.restore.outputs.cache-hit }}

runs:
using: composite
steps:
- name: Resolve flags, wolfSSL commit and cache key
id: meta
shell: bash
run: |
set -euo pipefail
script="${GITHUB_ACTION_PATH}/../../../scripts/ci/build-wolfssl.sh"
repo="${WOLFSSL_REPO:-https://github.com/wolfSSL/wolfssl.git}"

# Exact configure flags -> the single source of truth for the key.
flags="$("$script" --print-flags "${{ inputs.config }}")"

# Resolve the ref to a commit so a moving branch (master) refreshes the
# cache when upstream advances. A raw 40-hex SHA is used as-is (it
# cannot be ls-remote'd); for a branch/tag we REQUIRE resolution to
# succeed -- otherwise a transient network failure would silently fall
# back to the literal ref, producing a cache key that never refreshes.
ref='${{ inputs.ref }}'
if printf '%s' "$ref" | grep -Eq '^[0-9a-f]{40}$'; then
sha="$ref"
else
sha="$(git ls-remote "$repo" "$ref" | head -1 | awk '{print $1}')"
if [ -z "$sha" ]; then
echo "::error::could not resolve wolfSSL ref '$ref' via git ls-remote $repo" >&2
exit 1
fi
fi

cfg_hash="$(printf '%s\n%s\n%s\n%s\n%s\n%s\n' \
"$sha" "$flags" "${CC:-}" "${CFLAGS:-}" "${RUNNER_OS}" "${RUNNER_ARCH}" \
| sha256sum | cut -c1-16)"

Comment thread
philljj marked this conversation as resolved.
prefix="${GITHUB_WORKSPACE}/.wolfssl-install/${{ inputs.config }}"
key="wolfssl-${RUNNER_OS}-${RUNNER_ARCH}-${{ inputs.config }}-${sha:0:12}-${cfg_hash}"

{
echo "prefix=$prefix"
echo "sha=$sha"
echo "key=$key"
} >> "$GITHUB_OUTPUT"

# Exact-key match only (no restore-keys): a stale prefix from a different
# wolfSSL commit or flag set would carry a valid-looking wolfssl.pc, and the
# idempotent build script would then short-circuit on it and silently use
# the wrong config. Forcing a clean rebuild on any key change avoids that.
- name: Restore cached wolfSSL prefix
id: restore
uses: actions/cache/restore@v4
with:
path: ${{ steps.meta.outputs.prefix }}
key: ${{ steps.meta.outputs.key }}

- name: Build wolfSSL (cache miss)
if: steps.restore.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
"${GITHUB_ACTION_PATH}/../../../scripts/ci/build-wolfssl.sh" \
"${{ inputs.config }}" \
--prefix "${{ steps.meta.outputs.prefix }}" \
--ref "${{ inputs.ref }}"

- name: Save wolfSSL prefix to cache (reseed)
if: inputs.save == 'true' && steps.restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ steps.meta.outputs.prefix }}
key: ${{ steps.meta.outputs.key }}

- name: Export prefix
shell: bash
run: |
echo "WOLFSSL_PREFIX=${{ steps.meta.outputs.prefix }}" >> "$GITHUB_ENV"
echo "PKG_CONFIG_PATH=${{ steps.meta.outputs.prefix }}/lib/pkgconfig:${PKG_CONFIG_PATH:-}" >> "$GITHUB_ENV"
140 changes: 140 additions & 0 deletions .github/workflows/interop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# SPDX-License-Identifier: GPL-3.0-or-later
name: Interop

# Third-party EST/SCEP interop. Best-effort: a dependency that fails to install
# makes its script exit 77 (the automake "skip" convention wired into
# tests/interop/lib/common.sh via need()), which we treat as a neutral pass.
# A real interop regression (any other non-zero) fails the job.
on:
schedule:
- cron: "0 4 * * *"
workflow_dispatch:

concurrency:
group: interop-${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: read

env:
WOLFSSL_REF: master

jobs:
# OpenSSL is always present -> a cheap lower-bound cross-check.
openssl:
name: openssl cms/pkcs7 cross-check
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-wolfcert-cli
with:
wolfssl-ref: ${{ env.WOLFSSL_REF }}
- name: Run openssl_cms.sh
run: |
set +e
bash tests/interop/openssl_cms.sh; rc=$?
[ "$rc" -eq 77 ] && { echo "::notice::openssl_cms skipped (dep missing)"; exit 0; }
exit "$rc"

micromdm-scep:
name: micromdm/scep
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-wolfcert-cli
with:
wolfssl-ref: ${{ env.WOLFSSL_REF }}
- name: Install micromdm scep
continue-on-error: true
run: sudo apt-get update && sudo apt-get install -y scep
- name: Run scep_micromdm.sh
run: |
set +e
bash tests/interop/scep_micromdm.sh; rc=$?
[ "$rc" -eq 77 ] && { echo "::notice::micromdm/scep skipped (dep missing)"; exit 0; }
exit "$rc"

globalsign-est:
name: globalsign/est
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-wolfcert-cli
with:
wolfssl-ref: ${{ env.WOLFSSL_REF }}
- uses: actions/setup-go@v5
with:
go-version: "stable"
- name: Install globalsign est (estserver/estclient)
continue-on-error: true
run: |
go install github.com/globalsign/est/cmd/estserver@latest
go install github.com/globalsign/est/cmd/estclient@latest
- name: Run est_globalsign.sh
run: |
# setup-go puts binaries in $(go env GOPATH)/bin. The script uses
# GLOBALSIGN_EST_BIN_DIR to disambiguate from libest's same-named bins.
GLOBALSIGN_EST_BIN_DIR="$(go env GOPATH)/bin"
export GLOBALSIGN_EST_BIN_DIR
export PATH="$GLOBALSIGN_EST_BIN_DIR:$PATH"
set +e
bash tests/interop/est_globalsign.sh; rc=$?
[ "$rc" -eq 77 ] && { echo "::notice::globalsign/est skipped (dep missing)"; exit 0; }
exit "$rc"

libest:
name: cisco/libest
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-wolfcert-cli
with:
wolfssl-ref: ${{ env.WOLFSSL_REF }}
- name: Build Cisco libest from source
continue-on-error: true
run: |
set -euo pipefail
sudo apt-get install -y libssl-dev
git clone --depth 1 https://github.com/cisco/libest "$RUNNER_TEMP/libest"
cd "$RUNNER_TEMP/libest"
./configure --prefix="$RUNNER_TEMP/libest-install" --with-ssl-dir=/usr
make -j "$(nproc)"
make install
echo "$RUNNER_TEMP/libest-install/bin" >> "$GITHUB_PATH"
- name: Run est_libest.sh
run: |
set +e
bash tests/interop/est_libest.sh; rc=$?
[ "$rc" -eq 77 ] && { echo "::notice::libest skipped (dep missing)"; exit 0; }
exit "$rc"

stepca:
name: smallstep/step-ca
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build-wolfcert-cli
with:
wolfssl-ref: ${{ env.WOLFSSL_REF }}
- uses: actions/setup-go@v5
with:
go-version: "stable"
- name: Install step-ca and step CLI
continue-on-error: true
run: |
go install github.com/smallstep/certificates/cmd/step-ca@latest
go install github.com/smallstep/cli/cmd/step@latest
- name: Run est_stepca.sh
run: |
gobin="$(go env GOPATH)/bin"
export PATH="$gobin:$PATH"
set +e
bash tests/interop/est_stepca.sh; rc=$?
[ "$rc" -eq 77 ] && { echo "::notice::step-ca skipped (dep missing)"; exit 0; }
exit "$rc"
57 changes: 57 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-3.0-or-later
name: Lint

# Cheap, wolfSSL-free checks that fail fast before the expensive build matrix
# matters: source license headers and CMake<->autoconf source-list parity.
on:
# See pr.yml: push only on default branches so PR runs aren't doubled.
pull_request:
push:
branches:
- main
- master

concurrency:
group: lint-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
license-headers:
name: GPL license headers
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Check every C source opens with the GPL block
shell: bash
run: |
set -euo pipefail
missing=0
while IFS= read -r f; do
hdr="$(head -n 20 "$f")"
if ! grep -q "wolfSSL Inc." <<<"$hdr" \
|| ! grep -q "GNU General Public License" <<<"$hdr"; then
echo "MISSING license header: $f"
missing=1
fi
done < <(git ls-files 'src/*.c' 'src/**/*.c' 'wolfcert/*.h' \
'cli/*.c' 'tests/*.c' 'tests/*.h' \
'tests/**/*.c' 'tests/**/*.h')
if [ "$missing" -ne 0 ]; then
echo "One or more sources lack the GPL copyright block (copy it"
echo "verbatim from any existing .c/.h)."
exit 1
fi
echo "license headers OK"

buildsystem-parity:
name: CMake <-> autoconf source parity
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Check library source lists match
run: scripts/ci/check-buildsystem-parity.sh
Loading
Loading