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
41 changes: 40 additions & 1 deletion .github/actions/ccache-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ description: >
directory from a previous run, and prepend the ccache compiler-symlink
dir to PATH. Subsequent gcc/cc/g++/c++/clang invocations are
transparently intercepted by ccache, so no other workflow step needs to
change.
change. On scheduled (cron) runs the cache is reseeded from clean
compiles (CCACHE_RECACHE) instead of only being updated incrementally,
so it can't drift indefinitely.

inputs:
workflow-id:
Expand All @@ -21,6 +23,15 @@ inputs:
description: 'Per-job ccache max size (passed to ccache -M).'
required: false
default: '500M'
read-only:
description: >
When 'true', restore the cache but do NOT save it (no post-job
upload). Callers should set this to the result of the expression
github.event_name == 'pull_request' so PR runs consume the shared
cache read-only - no per-PR entries, no churn - while scheduled/push
runs (read-only false) refresh it.
required: false
default: 'false'

runs:
using: 'composite'
Expand All @@ -41,7 +52,10 @@ runs:
exit 1
fi

# read-only=false (default): restore + post-job save (the run_id in the
# key never hits, so it always saves its contribution).
- name: Restore + save ccache
if: inputs.read-only != 'true'
uses: actions/cache@v5
with:
path: ~/.ccache
Expand All @@ -52,6 +66,19 @@ runs:
restore-keys: |
ccache-${{ inputs.workflow-id }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.config-hash }}-
ccache-${{ inputs.workflow-id }}-${{ runner.os }}-${{ runner.arch }}-
# read-only=true: restore the shared cache but never upload (PR runs).
- name: Restore ccache (read-only)
Comment thread
dgarske marked this conversation as resolved.
if: inputs.read-only == 'true'
uses: actions/cache/restore@v5
with:
path: ~/.ccache
# Same key shape as the save branch, for symmetry. This branch never
# saves, so the run_id/run_attempt primary key is never an exact hit -
# the restore-keys below always supply the most recent seeded cache.
key: ccache-${{ inputs.workflow-id }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.config-hash }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
ccache-${{ inputs.workflow-id }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.config-hash }}-
ccache-${{ inputs.workflow-id }}-${{ runner.os }}-${{ runner.arch }}-

- name: Configure ccache and PATH
shell: bash
Expand All @@ -76,6 +103,18 @@ runs:
echo "$CCACHE_LIBEXEC" >> "$GITHUB_PATH"
echo "CCACHE_DIR=$HOME/.ccache" >> "$GITHUB_ENV"

# On the scheduled (cron) refresh, force every compile to miss the
# cache and re-store a fresh result (CCACHE_RECACHE still writes, it
# just skips lookups). This reseeds the shared cache from clean
# compiles instead of only layering deltas onto whatever accumulated,
# so a bad/stale entry can't live forever. The cache is still saved
# (read-only is false on schedule), and PR/push runs are unaffected -
# they keep their warm hits. Cost: the scheduled jobs recompile fully.
- name: Force fresh compiles on scheduled reseed
if: github.event_name == 'schedule'
shell: bash
run: echo "CCACHE_RECACHE=1" >> "$GITHUB_ENV"

- name: Show ccache stats (initial)
shell: bash
run: ccache -s
68 changes: 63 additions & 5 deletions .github/actions/install-apt-deps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,65 @@ inputs:
description: 'Cache apt archives (disable for dynamic package names)'
required: false
default: 'true'
ghcr-debs-tag:
description: >
Tag of a prebuilt .deb bundle published to
ghcr.io/<owner>/wolfssl-ci-debs by the ci-deps-image workflow
(e.g. "ubuntu-24.04-minimal"). When set, the packages are installed
offline from that bundle and the apt cache path below is skipped; on
that happy path the apt mirror is not contacted. The offline install
is all-or-nothing (a single --no-download install of the whole set),
so any failure - bundle missing, not public, or not covering every
requested package - falls back to the apt path. Always safe to set;
leave empty to use apt only.
required: false
default: ''
runs:
using: 'composite'
steps:
# Preferred path: install from a prebuilt .deb bundle pulled from ghcr,
# entirely offline (--no-download), so a flaky/timing-out apt mirror
# cannot break the build. Best-effort: on any failure we leave
# "satisfied" unset and the apt steps below run unchanged. The bundle
# image must be PUBLIC so anonymous `docker pull` works (including from
# fork PRs whose GITHUB_TOKEN cannot read private packages).
- name: Install from ghcr .deb bundle (offline)
id: ghcr
if: inputs.ghcr-debs-tag != ''
shell: bash
run: |
set -u
command -v docker >/dev/null 2>&1 || { echo "::notice::docker unavailable; using apt"; exit 0; }
# Hardcode the upstream owner: the bundle is only ever published under
# ghcr.io/wolfssl by ci-deps-image (gated to the wolfssl org), so fork
# PRs read the public upstream image too rather than a nonexistent
# ghcr.io/<fork>/wolfssl-ci-debs.
IMG="ghcr.io/wolfssl/wolfssl-ci-debs:${{ inputs.ghcr-debs-tag }}"
if ! docker pull -q "$IMG" >/dev/null 2>&1; then
echo "::notice::ghcr bundle $IMG unavailable; using apt"
exit 0
fi
cid=$(docker create "$IMG" 2>/dev/null) || { echo "::notice::cannot open bundle; using apt"; exit 0; }
rm -rf "$RUNNER_TEMP/ghcr-debs"; mkdir -p "$RUNNER_TEMP/ghcr-debs"
docker cp "$cid:/debs/." "$RUNNER_TEMP/ghcr-debs/" >/dev/null 2>&1 || true
docker rm "$cid" >/dev/null 2>&1 || true
ls "$RUNNER_TEMP"/ghcr-debs/*.deb >/dev/null 2>&1 || { echo "::notice::bundle had no .debs; using apt"; exit 0; }
sudo cp "$RUNNER_TEMP"/ghcr-debs/*.deb /var/cache/apt/archives/
NO_REC=""
if [ "${{ inputs.no-install-recommends }}" = "true" ]; then
NO_REC="--no-install-recommends"
fi
# --no-download forbids any network fetch: if the bundle is missing
# a package this fails cleanly (nothing installed) and we fall back.
if sudo DEBIAN_FRONTEND=noninteractive apt-get install -y $NO_REC --no-download ${{ inputs.packages }}; then
echo "satisfied=true" >> "$GITHUB_OUTPUT"
echo "Installed offline from $IMG: ${{ inputs.packages }}"
else
echo "::notice::offline install incomplete for $IMG; using apt"
fi

- name: Compute cache key
if: inputs.cache == 'true'
if: inputs.cache == 'true' && steps.ghcr.outputs.satisfied != 'true'
id: cache-key
shell: bash
run: |
Expand All @@ -35,7 +89,7 @@ runs:
echo "restore-key=apt-deps-${{ runner.os }}-${{ runner.arch }}-${OS_VERSION}-" >> $GITHUB_OUTPUT

- name: Restore apt cache
if: inputs.cache == 'true'
if: inputs.cache == 'true' && steps.ghcr.outputs.satisfied != 'true'
id: apt-cache
uses: actions/cache/restore@v5
with:
Expand All @@ -44,7 +98,7 @@ runs:
restore-keys: ${{ steps.cache-key.outputs.restore-key }}

- name: Pre-seed apt archives from cache
if: inputs.cache == 'true' && steps.apt-cache.outputs.cache-hit == 'true'
if: inputs.cache == 'true' && steps.apt-cache.outputs.cache-hit == 'true' && steps.ghcr.outputs.satisfied != 'true'
shell: bash
run: |
if [ -d ~/apt-cache ] && ls ~/apt-cache/*.deb >/dev/null 2>&1; then
Expand All @@ -53,6 +107,7 @@ runs:
fi

- name: Install packages
if: steps.ghcr.outputs.satisfied != 'true'
shell: bash
env:
APT_CACHE_HIT: ${{ steps.apt-cache.outputs.cache-hit }}
Expand Down Expand Up @@ -90,16 +145,19 @@ runs:
DELAY=$((DELAY * 2))
done

# PR runs never write the apt cache (no churn); only push/schedule runs
# refresh it. The make-check family does not need it anyway - it installs
# from the ghcr bundle above.
- name: Collect .deb files for cache
if: inputs.cache == 'true' && steps.apt-cache.outputs.cache-hit != 'true'
if: inputs.cache == 'true' && github.event_name != 'pull_request' && steps.apt-cache.outputs.cache-hit != 'true' && steps.ghcr.outputs.satisfied != 'true'
shell: bash
run: |
mkdir -p ~/apt-cache
cp /var/cache/apt/archives/*.deb ~/apt-cache/ 2>/dev/null || true
echo "Cached $(ls ~/apt-cache/*.deb 2>/dev/null | wc -l) .deb files"

- name: Save apt cache
if: inputs.cache == 'true' && steps.apt-cache.outputs.cache-hit != 'true'
if: inputs.cache == 'true' && github.event_name != 'pull_request' && steps.apt-cache.outputs.cache-hit != 'true' && steps.ghcr.outputs.satisfied != 'true'
uses: actions/cache/save@v5
with:
path: ~/apt-cache
Expand Down
80 changes: 80 additions & 0 deletions .github/ci-deps/packages-ubuntu-22.04-full.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# make-check family + interop apt packages for ubuntu-22.04 (the '-full'
# bundle: ghcr.io/<owner>/wolfssl-ci-debs:ubuntu-22.04-full). Superset of
# -minimal; interop workflows install their subset offline from it.
# Keep sorted; add a package when an interop workflow adds one.
autoconf
automake
bison
bridge-utils
build-essential
ca-certificates
cargo
ccache
chrpath
cmake
cpio
crossbuild-essential-arm64
crossbuild-essential-armel
crossbuild-essential-armhf
crossbuild-essential-riscv64
device-tree-compiler
dfu-util
diffstat
dos2unix
doxygen
file
flex
g++
g++-multilib
gawk
gcc
gcc-multilib
gcovr
git
git-core
gnupg
gperf
gtk-sharp3
help2man
iproute2
lcov
libcairo2-dev
libglib2.0-dev
libgtk2.0-0
liblocale-gettext-perl
libmagic1
libncurses5-dev
libpcap-dev
libpopt0
libsdl1.2-dev
libsdl2-dev
libssl-dev
libtool
libtool-bin
locales
make
net-tools
ninja-build
openssh-client
ovmf
parallel
pkg-config
python-is-python3
python3-dev
python3-pip
python3-ply
python3-setuptools
python3-tk
python3-wheel
qemu-kvm
qemu-user
rsync
socat
srecord
sudo
texinfo
uml-utilities
unzip
wget
xz-utils
zip
12 changes: 12 additions & 0 deletions .github/ci-deps/packages-ubuntu-22.04-minimal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# make-check family apt packages for ubuntu-22.04 (the '-minimal'
# bundle: ghcr.io/<owner>/wolfssl-ci-debs:ubuntu-22.04-minimal). UNION of
# every family workflow's list; superset is fine. Keep sorted.
autoconf
automake
build-essential
crossbuild-essential-arm64
crossbuild-essential-armel
crossbuild-essential-armhf
crossbuild-essential-riscv64
libtool
qemu-user
94 changes: 94 additions & 0 deletions .github/ci-deps/packages-ubuntu-24.04-full.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# make-check family + interop apt packages for ubuntu-24.04 (the '-full'
# bundle: ghcr.io/<owner>/wolfssl-ci-debs:ubuntu-24.04-full). Superset of
# -minimal; interop workflows install their subset offline from it.
# Keep sorted; add a package when an interop workflow adds one.
apache2
apache2-dev
autoconf
autoconf-archive
automake
autopoint
bubblewrap
build-essential
ccache
clang
clang-14
clang-19
cmake
g++-10
g++-11
g++-12
g++-9
gcc-10
gcc-11
gcc-12
gcc-9
gcc-multilib
gettext
gyp
jq
krb5-admin-server
krb5-kdc
krb5-otp
libbz2-dev
libc++-dev
libcap-dev
libcap-ng-dev
libcmocka-dev
libcppunit-dev
libcunit1
libcunit1-dev
libcunit1-doc
libcurl4-openssl-dev
libdb5.3-dev
libev-dev
libevent-2.1-7
libevent-dev
libffi-dev
libgdbm-dev
libgtest-dev
libidn2-dev
libio-socket-ssl-perl
libjansson-dev
libkrb5-dev
liblz4-dev
liblzma-dev
liblzo2-dev
libncursesw5-dev
libnghttp2-dev
libnl-genl-3-200
libnl-genl-3-dev
libnss-wrapper
libnss3-dev
libp11-dev
libpam-dev
libpam0g-dev
libpcre2-dev
libpsl-dev
libpsl5
libreadline-dev
librtlsdr-dev
libsecret-1-dev
libsocket-wrapper
libsqlite3-dev
libssl-dev
libtool
liburcu-dev
libuv1-dev
linux-libc-dev
make
man2html
meson
mono-complete
nghttp2
ninja-build
pkg-config
pkgconf
psmisc
python3-docutils
python3-impacket
python3-psutil
shellcheck
uuid-dev
valgrind
zlib1g-dev
Loading
Loading