Skip to content

chore(security): supported-versions matrix for 1.36.0 #1

chore(security): supported-versions matrix for 1.36.0

chore(security): supported-versions matrix for 1.36.0 #1

Workflow file for this run

name: "Build & Test (Linux)"
on:
pull_request:
paths:
- configure
- 'auto/**'
- 'go/**'
- 'src/**'
- 'test/**'
- 'pkg/contrib/**'
- 'pkg/eol.json'
- '.github/workflows/build-test.yml'
push:
branches: master
paths:
- configure
- 'auto/**'
- 'go/**'
- 'src/**'
- 'test/**'
- 'pkg/contrib/**'
- 'pkg/eol.json'
- '.github/workflows/build-test.yml'
env:
# OpenSSL patch version built from source (see "Build OpenSSL" step). Only the
# patch level lives here; the 3.6 "slot" (/opt/openssl-3.6, OPENSSL36_* vars)
# is stable across patch bumps and intentionally not templated.
OPENSSL_VERSION: 3.6.2
jobs:
# Single source of truth for the test matrix. The version-tested language
# modules (go/java/node/php/python/ruby) are derived from pkg/eol.json; the
# fixed extras below are not runtime-versioned in CI. Excluded on purpose:
# per-version perl (tested against the runner's system perl), python "-slim"
# and the "minimal" image — those are Docker packaging flavors, not test axes.
prepare:
runs-on: ubuntu-latest
outputs:
builds: ${{ steps.list.outputs.builds }}
steps:
- uses: actions/checkout@v5
- name: Derive build list from pkg/eol.json
id: list
run: |
builds=$(jq -c '
["unit", "perl", "wasm", "wasm-wasi-component"]
+ [ .runtimes | to_entries[]
| select(.key | IN("go", "java", "node", "php", "ruby"))
| .key as $rt | .value[] | $rt + "-" + .version ]
+ [ .runtimes.python[] | "python-" + .version ]
' pkg/eol.json)
echo "builds=${builds}" >> "$GITHUB_OUTPUT"
test:
needs: prepare
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
build: ${{ fromJSON(needs.prepare.outputs.builds) }}
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v5
# Provides module, language version and testpath from build name
- name: Output build metadata
id: metadata
run: |
if [ "${{ matrix.build }}" = "wasm-wasi-component" ]; then
module="wasm-wasi-component"
else
# Split the build name by '-' into module and version
IFS='-' read -r module version <<< "${{ matrix.build }}"
fi
testpath="test/test_${module}*"
# Run all tests for "unit" and "python"
# Python is the default module for tests
if [ "$module" = "unit" ] || [ "$module" = "python" ]; then
testpath="test"
fi
echo "module=${module}" >> "$GITHUB_OUTPUT"
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "testpath=${testpath}" >> "$GITHUB_OUTPUT"
NJS_VERSION=$(sed -n "s/NJS_VERSION := \(.*\)/\1/p" pkg/contrib/src/njs/version)
echo "njs_version=${NJS_VERSION}" >> "$GITHUB_OUTPUT"
WASMTIME_VERSION=$(sed -n "s/WASMTIME_VERSION := \(.*\)/\1/p" pkg/contrib/src/wasmtime/version)
echo "wasmtime_version=${WASMTIME_VERSION}" >> "$GITHUB_OUTPUT"
cat "$GITHUB_OUTPUT"
# https://github.com/actions/runner-images/issues/2821
- name: Kill mono process
run: |
set +e
sudo systemctl status mono-xsp4.service
if [ $? -ne 0 ]; then
true
else
sudo systemctl stop mono-xsp4.service
sudo systemctl mask mono-xsp4.service
sudo systemctl status mono-xsp4.service
PID=$(sudo lsof -t -i :8084)
echo "Killing PID $PID"
sudo kill -9 $PID
fi
- name: Install packages
run: sudo apt-get -y install libbrotli-dev ccache
# ccache transparently caches C object files across runs. The Debian
# ccache package ships compiler symlinks in /usr/lib/ccache; putting it
# first on PATH makes `cc`/`gcc` resolve to ccache for njs, unit and the
# OpenSSL build with no configure changes. Falls back to real cc on any
# miss, so it can only speed things up, never break the build.
- name: Cache ccache
uses: actions/cache@v6
with:
path: ~/.ccache
key: ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-${{ github.run_id }}
restore-keys: |
ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-
- name: Enable ccache
run: |
echo "/usr/lib/ccache" >> "$GITHUB_PATH"
echo "CCACHE_DIR=$HOME/.ccache" >> "$GITHUB_ENV"
echo "CCACHE_MAXSIZE=500M" >> "$GITHUB_ENV"
- name: Cache OpenSSL 3.6
id: cache-openssl36
uses: actions/cache@v6
with:
path: /opt/openssl-3.6
key: openssl-${{ env.OPENSSL_VERSION }}-${{ runner.os }}-${{ runner.arch }}
- name: Build OpenSSL 3.6
if: steps.cache-openssl36.outputs.cache-hit != 'true'
run: |
sudo apt-get -y install build-essential
cd /tmp
wget -q "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
tar -xzf "openssl-${OPENSSL_VERSION}.tar.gz"
cd "openssl-${OPENSSL_VERSION}"
./Configure --prefix=/opt/openssl-3.6 shared no-docs
make -j$(nproc)
sudo mkdir -p /opt/openssl-3.6
sudo make install_sw
- name: Set OpenSSL 3.6 build environment
# Keep OpenSSL 3.6 isolated in /opt/openssl-3.6.
# Mixing libssl.so.3 (3.3) with libcrypto.so.3 (3.6) breaks sudo,
# so we never overwrite system libraries.
# Export the two helper variables used in later steps.
run: |
OSSL=/opt/openssl-3.6
LIBDIR=$( [ -d "$OSSL/lib64" ] && echo "$OSSL/lib64" || echo "$OSSL/lib" )
echo "OPENSSL36_INCDIR=${OSSL}/include" >> $GITHUB_ENV
echo "OPENSSL36_LIBDIR=${LIBDIR}" >> $GITHUB_ENV
##
## njs
##
- name: Cache njs
id: cache-njs
uses: actions/cache@v6
with:
path: njs
key: njs-freeunitorg-${{ steps.metadata.outputs.njs_version }}-${{ runner.os }}-${{ runner.arch }}
- name: Clone njs repository
if: steps.cache-njs.outputs.cache-hit != 'true'
uses: actions/checkout@v5
with:
repository: freeunitorg/njs
ref: '${{ steps.metadata.outputs.njs_version }}'
path: njs
- name: Make njs
if: steps.cache-njs.outputs.cache-hit != 'true'
run: |
./configure --no-libxml2 --no-zlib
make -j4 -k
working-directory: njs
##
## Unit
##
- name: Configure unit
# LD_LIBRARY_PATH is set only for this step so that auto/feature
# test binaries load OpenSSL 3.6 at runtime. It is NOT exported
# globally — doing so would break sudo (sudoers.so links against
# system libssl 3.3 which requires OPENSSL_3.3.0 from libcrypto,
# a symbol version that 3.6 does not export in the same slot).
env:
LD_LIBRARY_PATH: ${{ env.OPENSSL36_LIBDIR }}
run: |
./configure \
--tests \
--openssl \
--njs \
--zlib \
--zstd \
--brotli \
--otel \
--cc-opt="-I${OPENSSL36_INCDIR} -I njs/src/ -I njs/build" \
--ld-opt="-L${OPENSSL36_LIBDIR} -Wl,-rpath,${OPENSSL36_LIBDIR} -L njs/build"
- name: Make unit
run: |
make -j4 -k || make
##
## Go
##
- uses: actions/setup-go@v6
with:
go-version: '${{ steps.metadata.outputs.version }}'
cache: false
if: steps.metadata.outputs.module == 'go'
- name: Configure go
run: |
./configure go --go-path=
if: steps.metadata.outputs.module == 'go'
- name: Make go
run: |
make go
make go-install
if: steps.metadata.outputs.module == 'go'
##
## Java
##
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '${{ steps.metadata.outputs.version }}'
if: steps.metadata.outputs.module == 'java'
- name: Configure java
run: |
sudo ./configure java
if: steps.metadata.outputs.module == 'java'
- name: Make java
run: |
sudo make java
if: steps.metadata.outputs.module == 'java'
##
## Node
##
- uses: actions/setup-node@v4
with:
node-version: '${{ steps.metadata.outputs.version }}'
if: steps.metadata.outputs.module == 'node'
- name: Install node-gyp
run: |
npm install -g node-gyp
if: steps.metadata.outputs.module == 'node'
- name: Configure node
run: |
./configure nodejs
if: steps.metadata.outputs.module == 'node'
- name: Make node
run: |
make node-local-install DESTDIR=node
if: steps.metadata.outputs.module == 'node'
##
## Perl
##
# Uses default Actions VM Perl
# https://github.com/actions/runner-images#available-images
- name: Install libperl-dev
run: |
sudo apt-get install libperl-dev
if: steps.metadata.outputs.module == 'perl'
- name: Configure perl
run: |
./configure perl
if: steps.metadata.outputs.module == 'perl'
- name: Make perl
run: |
make perl
if: steps.metadata.outputs.module == 'perl'
##
## PHP
##
- uses: shivammathur/setup-php@v2
with:
php-version: '${{ steps.metadata.outputs.version }}'
extensions: none
env:
update: true
if: steps.metadata.outputs.module == 'php'
- name: Configure php
run: |
./configure php
if: steps.metadata.outputs.module == 'php'
- name: Make php
run: |
make php
if: steps.metadata.outputs.module == 'php'
##
## Python 3
##
- uses: actions/setup-python@v6
with:
python-version: '${{ steps.metadata.outputs.version }}'
if: steps.metadata.outputs.module == 'python'
- name: Configure python3
run: |
sudo ./configure python --config=python3-config
if: steps.metadata.outputs.module == 'python'
- name: Make python3
run: |
sudo make python3
if: steps.metadata.outputs.module == 'python'
##
## Ruby
##
- uses: ruby/setup-ruby@v1
with:
ruby-version: '${{ steps.metadata.outputs.version }}'
if: steps.metadata.outputs.module == 'ruby'
- name: Install rack
run: |
gem install rack
if: steps.metadata.outputs.module == 'ruby'
- name: Configure ruby
run: |
./configure ruby --module=ruby
if: steps.metadata.outputs.module == 'ruby'
- name: Make ruby
run: |
make ruby
if: steps.metadata.outputs.module == 'ruby'
##
## Wasm
##
- name: Cache wasmtime
id: cache-wasmtime
if: steps.metadata.outputs.module == 'wasm'
uses: actions/cache@v6
with:
path: pkg/contrib/wasmtime/artifacts
key: wasmtime-${{ steps.metadata.outputs.wasmtime_version }}-${{ runner.os }}-${{ runner.arch }}
- name: Make wasmtime
run: |
make -C pkg/contrib .wasmtime
if: steps.metadata.outputs.module == 'wasm' && steps.cache-wasmtime.outputs.cache-hit != 'true'
- name: Configure wasm
run: |
./configure wasm --include-path=pkg/contrib/wasmtime/artifacts/include --lib-path=pkg/contrib/wasmtime/artifacts/lib
if: steps.metadata.outputs.module == 'wasm'
- name: Make wasm
run: |
make wasm
if: steps.metadata.outputs.module == 'wasm'
##
## wasm-wasi-component
##
- name: Setup rust
run: |
curl https://sh.rustup.rs | sh -s -- -y
if: steps.metadata.outputs.module == 'wasm-wasi-component'
# Prebuilt binary instead of `cargo install cargo-component` (which
# compiles it from source on every run). Same tool, much faster.
- name: Install cargo-component
uses: taiki-e/install-action@v2
with:
tool: cargo-component
if: steps.metadata.outputs.module == 'wasm-wasi-component'
- name: Configure wasm-wasi-component
run: |
./configure wasm-wasi-component
if: steps.metadata.outputs.module == 'wasm-wasi-component'
- name: Make wasm-wasi-component
run: |
CLANG_PATH=/usr/bin/clang-15 \
BINDGEN_EXTRA_CLANG_ARGS="-I../../njs/src -I../../njs/build" \
make wasm-wasi-component
if: steps.metadata.outputs.module == 'wasm-wasi-component'
##
## Tests
##
- name: Cache Cargo artifacts
if: steps.metadata.outputs.module == 'unit' || steps.metadata.outputs.module == 'python'
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
test/fake_upstream/target
test/fake_otlp/target
key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('test/fake_upstream/Cargo.lock', 'test/fake_otlp/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-cargo-
- name: Install Rust toolchain
if: steps.metadata.outputs.module == 'unit' || steps.metadata.outputs.module == 'python'
run: rustup toolchain install stable --no-self-update --profile minimal
- name: Build fake_upstream
if: steps.metadata.outputs.module == 'unit' || steps.metadata.outputs.module == 'python'
run: |
cargo build --release --manifest-path test/fake_upstream/Cargo.toml
sudo cp test/fake_upstream/target/release/fake_upstream /usr/local/bin/
- name: Build fake_otlp
if: steps.metadata.outputs.module == 'unit' || steps.metadata.outputs.module == 'python'
run: |
cargo build --release --manifest-path test/fake_otlp/Cargo.toml
sudo cp test/fake_otlp/target/release/fake_otlp /usr/local/bin/
# /home/runner will be root only after calling sudo above
# Ensure all users and processes can execute
- name: Fix permissions
run: |
sudo chmod -R +x /home/runner
namei -l ${{ github.workspace }}
# Install python3 if not present
- uses: actions/setup-python@v6
with:
python-version: '3'
if: steps.metadata.outputs.module != 'wasm'
- name: Install pytest
run: |
sudo apt install -y python3-pytest
if: steps.metadata.outputs.module != 'wasm'
- name: Run ${{ steps.metadata.outputs.module }} tests
run: |
if [ "${{ matrix.build }}" == "wasm-wasi-component" ]; then
pytest-3 --print-log ${{ steps.metadata.outputs.testpath }}
else
sudo -E pytest-3 --print-log ${{ steps.metadata.outputs.testpath }}
fi
if: steps.metadata.outputs.module != 'wasm'
# C unit-test suite (src/test/ -> build/tests): HTTP parser, port/IPC
# fault-injection, lvlhsh, mp, rbtree, base64, utf8, clone creds, etc.
# Previously compiled but never executed in CI; runs here on every PR as its
# own check, like the language tests. sudo mirrors the pytest suite so
# privilege-sensitive cases (clone creds) work.
c-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install packages
run: |
sudo apt-get -y update
sudo apt-get -y install build-essential libssl-dev libpcre2-dev
- name: Configure unit (--tests)
run: ./configure --openssl --tests
- name: Build C tests
run: make -j4 tests
- name: Run C tests
run: sudo ./build/tests
- name: Run libunit close-provenance test
run: ./build/unit_close_test