chore(security): supported-versions matrix for 1.36.0 #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |