diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..472275324 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,335 @@ +name: ci + +on: + pull_request: + push: + branches: + - master + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # Core + - build: unit + os: ubuntu-latest + # Modules + - build: go-1.21 + os: ubuntu-latest + - build: go-1.22 + os: ubuntu-latest + - build: java-21 + os: ubuntu-latest + - build: java-18 + os: ubuntu-latest + - build: java-17 + os: ubuntu-latest + - build: node-20 + os: ubuntu-latest + - build: node-21 + os: ubuntu-latest + - build: perl + os: ubuntu-latest + - build: php-8.3 + os: ubuntu-latest + - build: python-3.11 + os: ubuntu-latest + - build: python-3.12 + os: ubuntu-latest + - build: ruby-3.2 + os: ubuntu-latest + - build: ruby-3.3 + os: ubuntu-latest + - build: wasm + os: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # Creates and outputs directories used by tests (/usr/local is unfriendly) + - name: Configure directories + id: dir + run: | + PREFIX=${HOME}/.unit + BIN=${PREFIX}/bin + VAR=${PREFIX}/var + mkdir -p $BIN + mkdir -p $VAR + + echo "prefix=${PREFIX}" >> "$GITHUB_OUTPUT" + echo "bin=${BIN}" >> "$GITHUB_OUTPUT" + echo "bin=${BIN}" >> "$GITHUB_PATH" + echo "var=${VAR}" >> "$GITHUB_OUTPUT" + cat "$GITHUB_OUTPUT" + + # Provides module, language version and testpath from build name + - name: Output build metadata + id: metadata + run: | + # Split the build name by '-' into module and version + IFS='-' read -r module version <<< "${{ matrix.build }}" + + 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" + + cat "$GITHUB_OUTPUT" + + # https://github.com/actions/runner-images/issues/2821 + - name: Kill mono process + run: | + sudo systemctl stop mono-xsp4.service + sudo systemctl mask mono-xsp4.service + sudo systemctl status mono-xsp4.service || true + PID=$(sudo lsof -t -i :8084) + echo "Killing PID $PID" + sudo kill -9 $PID + + ## + ## njs + ## + + - name: Clone njs repository + uses: actions/checkout@v4 + with: + repository: nginx/njs + ref: '${{ steps.metadata.outputs.njs_version }}' + path: njs + + - name: Make njs + run: | + ./configure --no-libxml2 --no-zlib + make -j4 -k + working-directory: njs + + ## + ## Unit + ## + + - name: Configure unit + run: | + ./configure \ + --prefix=${{ steps.dir.outputs.prefix }} \ + --sbindir=${{ steps.dir.outputs.bin }} \ + --logdir=${{ steps.dir.outputs.var }}/log \ + --log=${{ steps.dir.outputs.var }}/log/unit/unit.log \ + --runstatedir=${{ steps.dir.outputs.var }}/run \ + --pid=${{ steps.dir.outputs.var }}/run/unit/unit.pid \ + --control=unix:${{ steps.dir.outputs.var }}/run/unit/control.sock \ + --modules=${{ steps.dir.outputs.prefix }}/lib/unit/modules \ + --statedir=${{ steps.dir.outputs.var }}/state/unit \ + --tests \ + --openssl \ + --njs \ + --cc-opt="-I njs/src/ -I njs/build" \ + --ld-opt="-L njs/build" \ + --debug + + - name: Make unit + run: | + make -j4 -k || make + + ## + ## Go + ## + + - uses: actions/setup-go@v4 + with: + go-version: '${{ steps.metadata.outputs.version }}' + 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@v4 + with: + distribution: temurin + java-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'java' + + - name: Configure java + run: | + ./configure java + if: steps.metadata.outputs.module == 'java' + + - name: Make java + run: | + 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@v5 + with: + python-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'python' + + - name: Configure python3 + run: | + ./configure python --config=python3-config + if: steps.metadata.outputs.module == 'python' + + - name: Make python3 + run: | + 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 + if: steps.metadata.outputs.module == 'ruby' + + - name: Make ruby + run: | + make ruby + if: steps.metadata.outputs.module == 'ruby' + + ## + ## Wasm + ## + + - name: Make wasmtime + run: | + make -C pkg/contrib .wasmtime + if: steps.metadata.outputs.module == 'wasm' + + - name: Configure wasm + run: | + ./configure wasm --include-path=pkg/contrib/wasmtime/crates/c-api/include --lib-path=pkg/contrib/wasmtime/target/release + if: steps.metadata.outputs.module == 'wasm' + + - name: Make wasm + run: | + make wasm + if: steps.metadata.outputs.module == 'wasm' + + ## + ## Tests + ## + + # Install python3 if not present + - uses: actions/setup-python@v5 + with: + python-version: '3' + if: steps.metadata.outputs.module != 'wasm' + + - name: Install pytest + run: | + pip install pytest + if: steps.metadata.outputs.module != 'wasm' + + - name: Run ${{ steps.metadata.outputs.module }} tests + run: | + pytest --print-log ${{ steps.metadata.outputs.testpath }} + # Skip pytest if wasm build, as there are no tests yet + if: steps.metadata.outputs.module != 'wasm'