diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 25a3b812..4c21521a 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -9,6 +9,7 @@ jobs: matrix: include: - name: Ubuntu GCC + enabled: true os: ubuntu-latest compiler: gcc cflags: -Wall -Wextra @@ -16,6 +17,7 @@ jobs: cmake-args: -DMINIZIP_ENABLE_BZIP2=ON - name: Ubuntu GCC -O3 + enabled: true os: ubuntu-latest compiler: gcc cflags: -O3 -Wall -Wextra @@ -23,6 +25,7 @@ jobs: cmake-args: -DMINIZIP_ENABLE_BZIP2=ON - name: Ubuntu Clang + enabled: true os: ubuntu-latest compiler: clang cflags: -Wall -Wextra @@ -30,6 +33,7 @@ jobs: cmake-args: -DMINIZIP_ENABLE_BZIP2=ON - name: Ubuntu Clang Debug + enabled: true os: ubuntu-latest compiler: clang cflags: -Wall -Wextra @@ -38,6 +42,7 @@ jobs: cmake-args: -DMINIZIP_ENABLE_BZIP2=ON - name: Windows MSVC Win32 + enabled: true os: windows-latest compiler: cl cflags: /W3 @@ -45,6 +50,7 @@ jobs: pkgtgt: PACKAGE - name: Windows MSVC Win64 + enabled: true os: windows-latest compiler: cl cflags: /W3 @@ -52,6 +58,7 @@ jobs: pkgtgt: PACKAGE - name: Windows GCC + enabled: true os: windows-latest compiler: gcc cflags: -Wall -Wextra @@ -59,6 +66,7 @@ jobs: pkgtgt: package - name: macOS Clang + enabled: true os: macos-latest compiler: clang cflags: -Wall -Wextra @@ -66,44 +74,59 @@ jobs: cmake-args: -DMINIZIP_ENABLE_BZIP2=ON - name: macOS GCC + enabled: true os: macos-latest compiler: gcc-12 cflags: -Wall -Wextra pkgtgt: package cmake-args: -DMINIZIP_ENABLE_BZIP2=ON + - name: S390X Native GCC + enabled: ${{ github.repository == 'fneddy/zlib' && 'true' || false }} + os: ${{ github.repository == 'fneddy/zlib' && 'S390X' || 'ubuntu-latest' }} + compiler: gcc + cflags: -Wall -Wextra + cmake-args: -DMINIZIP_ENABLE_BZIP2=OFF + pkgtgt: package + steps: - name: Checkout repository + if: matrix.enabled uses: actions/checkout@v4 - name: Install packages (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && matrix.enabled run: | choco install --no-progress ninja - name: Install packages (Linux) - if: runner.os == 'Linux' + if: runner.os == 'Linux' && matrix.os != 'S390X' && matrix.enabled run: | sudo apt install libbz2-dev + - name: Generate project files + if: matrix.enabled run: cmake -S . -B ../build ${{ matrix.cmake-args }} -D CMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} -DZLIB_BUILD_MINIZIP=ON env: CC: ${{ matrix.compiler }} CFLAGS: ${{ matrix.cflags }} - name: Compile source code + if: matrix.enabled run: cmake --build ../build --config ${{ matrix.build-config || 'Release' }} - name: Run test cases + if: matrix.enabled run: ctest -C Release --output-on-failure --max-width 120 working-directory: ../build - name: create packages + if: matrix.enabled run: cmake --build ../build --config ${{ matrix.build-config || 'Release' }} -t ${{ matrix.pkgtgt }} - name: Upload build errors uses: actions/upload-artifact@v4 - if: failure() + if: failure() && matrix.enabled == true with: name: ${{ matrix.name }} (cmake) path: | diff --git a/.github/workflows/configure.yml b/.github/workflows/configure.yml index f19272c7..e9e4df6b 100644 --- a/.github/workflows/configure.yml +++ b/.github/workflows/configure.yml @@ -9,12 +9,14 @@ jobs: matrix: include: - name: Ubuntu GCC + enabled: true os: ubuntu-latest compiler: gcc configure-args: --warn # Test out of source builds - name: Ubuntu GCC OSB + enabled: true os: ubuntu-latest compiler: gcc configure-args: --warn @@ -22,6 +24,7 @@ jobs: src-dir: ../zlib - name: Ubuntu GCC ARM SF + enabled: true os: ubuntu-latest compiler: arm-linux-gnueabi-gcc configure-args: --warn @@ -30,6 +33,7 @@ jobs: qemu-run: qemu-arm -L /usr/arm-linux-gnueabi - name: Ubuntu GCC ARM HF + enabled: true os: ubuntu-latest compiler: arm-linux-gnueabihf-gcc configure-args: --warn @@ -38,6 +42,7 @@ jobs: qemu-run: qemu-arm -L /usr/arm-linux-gnueabihf - name: Ubuntu GCC AARCH64 + enabled: true os: ubuntu-latest compiler: aarch64-linux-gnu-gcc configure-args: --warn @@ -46,6 +51,7 @@ jobs: qemu-run: qemu-aarch64 -L /usr/aarch64-linux-gnu - name: Ubuntu GCC PPC + enabled: true os: ubuntu-latest compiler: powerpc-linux-gnu-gcc configure-args: --warn --static @@ -56,6 +62,7 @@ jobs: ldflags: -static - name: Ubuntu GCC PPC64 + enabled: true os: ubuntu-latest compiler: powerpc64-linux-gnu-gcc configure-args: --warn --static @@ -66,6 +73,7 @@ jobs: ldflags: -static - name: Ubuntu GCC PPC64LE + enabled: true os: ubuntu-latest compiler: powerpc64le-linux-gnu-gcc configure-args: --warn @@ -73,7 +81,9 @@ jobs: packages: qemu-system qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross qemu-run: qemu-ppc64le -L /usr/powerpc64le-linux-gnu + # if on base repo use the native workflow runner, else QEMU - name: Ubuntu GCC S390X + enabled: true os: ubuntu-latest compiler: s390x-linux-gnu-gcc configure-args: --warn --static @@ -83,27 +93,37 @@ jobs: cflags: -static ldflags: -static + - name: Native S390X GCC + enabled: ${{ github.repository == 'fneddy/zlib' && 'true' || false }} + os: ${{ github.repository == 'fneddy/zlib' && 'S390X' || 'ubuntu-latest' }} + compiler: gcc + configure-args: --warn + - name: macOS GCC + enabled: true os: macos-latest compiler: gcc-12 configure-args: --warn - name: macOS Clang + enabled: true os: macos-latest compiler: clang configure-args: --warn steps: - name: Checkout repository + if: matrix.enabled uses: actions/checkout@v4 - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages + if: runner.os == 'Linux' && matrix.packages && matrix.enabled run: | sudo apt-get update sudo apt-get install -y ${{ matrix.packages }} - name: Generate project files + if: matrix.enabled run: | [ -d ${{ matrix.build-dir || '.' }} ] || mkdir ${{ matrix.build-dir || '.' }} cd ${{ matrix.build-dir || '.' }} @@ -115,10 +135,12 @@ jobs: CHOST: ${{ matrix.chost }} - name: Compile source code + if: matrix.enabled run: make -j2 working-directory: ${{ matrix.build-dir }} - name: Run test cases + if: matrix.enabled run: | make test make cover @@ -128,7 +150,7 @@ jobs: - name: Upload build errors uses: actions/upload-artifact@v4 - if: failure() + if: failure() && matrix.enabled with: name: ${{ matrix.name }} (configure) path: | diff --git a/contrib/README.contrib b/contrib/README.contrib index 5e5f9505..36f14ae9 100644 --- a/contrib/README.contrib +++ b/contrib/README.contrib @@ -55,3 +55,6 @@ untgz/ by Pedro A. Aranda Gutierrez vstudio/ by Gilles Vollant Building a minizip-enhanced zlib with Microsoft Visual Studio Includes vc11 from kreuzerkrieg and vc12 from davispuh + +s390x/ by Eduard Stefes [!NOTE] +> This is a copy of the s390x self-hosted action runner scripts from +> https://github.com/zlib-ng/zlib-ng/tree/a0fa24710c8faa1a746a20cfd5c7c24571e15ca4/arch/s390/self-hosted-builder + +Given complexity of DFLTCC machine instruction, it is not clear whether +QEMU TCG will ever support it. At the time of writing, one has to have +access to an IBM z15+ VM or LPAR in order to test DFLTCC support. Since +DFLTCC is a non-privileged instruction, neither special VM/LPAR +configuration nor root are required. + +zlib CI uses a self-hosted builder, provided by marist university +for the DFLTCC testing. There is no official IBM Z GitHub Actions runner, +so we build one inspired by `anup-kodlekere/gaplib`. +Future updates to actions-runner might need an updated patch. The .net +version number patch has been separated into a separate file to avoid a +need for constantly changing the patch. + +## Configuring the builder. + +### Install prerequisites. +``` +sudo dnf install podman +``` + +### Create a config file, needs github personal access token. +Access token needs permissions; Repo Admin RW, Org Self-hosted runners RW. +For details, consult +https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-a-repository + +#### Create file /etc/actions-runner: +``` +REPO=/ +PAT_TOKEN= +``` + +#### Set permissions on /etc/actions-runner: +``` +chmod 0600 /etc/actions-runner +``` + +### Add actions-runner service. +``` +sudo cp self-hosted-builder/actions-runner.service /etc/systemd/system/ +sudo systemctl daemon-reload +``` + +### Autostart actions-runner. +``` +$ sudo systemctl enable --now actions-runner +``` + +### Add auto-rebuild cronjob +``` +sudo cp self-hosted-builder/actions-runner-rebuild.sh /etc/cron.weekly/ +chmod +x /etc/cron.weekly/actions-runner-rebuild.sh +``` + +## Building / Rebuilding the container +``` +sudo /etc/cron.weekly/actions-runner-rebuild.sh +``` diff --git a/contrib/s390x/self-hosted-builder/actions-runner b/contrib/s390x/self-hosted-builder/actions-runner new file mode 100755 index 00000000..9d443f93 --- /dev/null +++ b/contrib/s390x/self-hosted-builder/actions-runner @@ -0,0 +1,59 @@ +#!/bin/bash + +# +# Ephemeral runner startup script. +# +# Expects the following environment variables: +# +# - REPO= +# - PAT_TOKEN= +# + +set -e -u + +# Validate required environment variables +if [ -z "${REPO:-}" ] || [ -z "${PAT_TOKEN:-}" ]; then + echo "Error: REPO and/or PAT_TOKEN environment variables not found" + exit 1 +fi + +# Check the cached registration token. +TOKEN_FILE=registration-token.json +if [ -f $TOKEN_FILE ]; then + set +e + EXPIRES=$(jq --raw-output .EXPIRES "$TOKEN_FILE" 2>/dev/null) + STATUS=$? + set -e +else + STATUS=1 +fi +if [[ $STATUS -ne 0 || $(date +%s) -ge $(date -d "$EXPIRES" +%s) ]]; then + # Refresh the cached registration token. + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $PAT_TOKEN" \ + "https://api.github.com/repos/$REPO/actions/runners/registration-token" \ + -o "$TOKEN_FILE" +fi + +REG_TOKEN=$(jq --raw-output .token "$TOKEN_FILE") +if [ $REG_TOKEN = "null" ]; then + echo "Failed to get registration token" + exit 1 +fi + +# (Re-)register the runner. +./config.sh remove --token "$REG_TOKEN" || true +set -x +./config.sh \ + --url "https://github.com/$REPO" \ + --token "$REG_TOKEN" \ + --unattended \ + --disableupdate \ + --replace \ + --labels S390X \ + --ephemeral + +# Run one job. +./run.sh diff --git a/contrib/s390x/self-hosted-builder/actions-runner-rebuild.sh b/contrib/s390x/self-hosted-builder/actions-runner-rebuild.sh new file mode 100644 index 00000000..a3b9bcd2 --- /dev/null +++ b/contrib/s390x/self-hosted-builder/actions-runner-rebuild.sh @@ -0,0 +1,49 @@ +#!/usr/bin/bash +set -ex + +TMPDIR="$(mktemp -d)" + +if [ -f actions-runner.Dockerfile ]; then + MODE=1 + cp actions-runner.Dockerfile actions-runner entrypoint $TMPDIR + cd $TMPDIR +else + MODE=2 + cd $TMPDIR + wget https://raw.githubusercontent.com/fneddy/zlib/refs/heads/s390x_native_ci/contrib/s390x/self-hosted-builder/actions-runner.Dockerfile + wget https://raw.githubusercontent.com/fneddy/zlib/refs/heads/s390x_native_ci/contrib/s390x/self-hosted-builder/actions-runner + wget https://raw.githubusercontent.com/fneddy/zlib/refs/heads/s390x_native_ci/contrib/s390x/self-hosted-builder/entrypoint +fi + +# Stop service +systemctl stop actions-runner || true + +# Delete old container +podman container rm gaplib-actions-runner || true + +# Delete old image +podman image rm localhost/zlib/actions-runner || true + +# Build new image +podman build --squash -f actions-runner.Dockerfile --tag zlib/actions-runner . 2>&1 | tee /var/log/actions-runner-build.log + +# Create new container +podman create --replace --name=gaplib-actions-runner --env-file=/etc/actions-runner --init \ + --volume=actions-runner-temp:/home/actions-runner zlib/actions-runner 2>&1 | tee -a /var/log/actions-runner-build.log + +# Start service +systemctl start actions-runner || true + +# Cleanup +podman image prune -af || true + +# Clean up tempfile +if [ "$MODE" == "2" ] ; then + cd $TMPDIR + rm actions-runner.Dockerfile + rm actions-runner + rm entrypoint + cd .. + rmdir $TMPDIR + echo "Deleted tempfiles." +fi diff --git a/contrib/s390x/self-hosted-builder/actions-runner.Dockerfile b/contrib/s390x/self-hosted-builder/actions-runner.Dockerfile new file mode 100644 index 00000000..d8213d00 --- /dev/null +++ b/contrib/s390x/self-hosted-builder/actions-runner.Dockerfile @@ -0,0 +1,45 @@ +# Self-Hosted IBM Z Github Actions Runner. + +FROM almalinux:9 + +RUN dnf update -y -q && \ + dnf install -y -q --enablerepo=crb wget git which sudo jq sed \ + cmake make automake autoconf m4 libtool ninja-build python3-pip \ + gcc gcc-c++ clang llvm-toolset glibc-all-langpacks langpacks-en \ + glibc-static libstdc++-static libstdc++-devel libxslt-devel libxml2-devel + +RUN dnf install -y -q dotnet-sdk-8.0 && \ + echo "Using SDK - `dotnet --version`" + +RUN cd /tmp && \ + git clone -q https://github.com/actions/runner && \ + cd runner && \ + git checkout main -b build && \ + wget https://github.com/anup-kodlekere/gaplib/raw/refs/heads/main/build-files/runner-sdk-8.s390x.patch && \ + git apply runner-sdk-8.s390x.patch && \ + sed -i'' -e /version/s/8......\"$/$8.0.100\"/ src/global.json + + +RUN cd /tmp/runner/src && \ + ./dev.sh layout && \ + ./dev.sh package && \ + rm -rf /root/.dotnet /root/.nuget + +RUN useradd -c "Action Runner" -m actions-runner && \ + usermod -L actions-runner + +RUN tar -xf /tmp/runner/_package/*.tar.gz -C /home/actions-runner && \ + chown -R actions-runner:actions-runner /home/actions-runner + +# Cleanup +RUN rm -rf /tmp/runner /var/cache/dnf/* /tmp/runner.patch /tmp/global.json && \ + dnf clean all + +USER actions-runner + +# Scripts. +COPY --chmod=555 entrypoint /usr/bin/ +COPY --chmod=555 actions-runner /usr/bin/ +WORKDIR /home/actions-runner +ENTRYPOINT ["/usr/bin/entrypoint"] +CMD ["/usr/bin/actions-runner"] diff --git a/contrib/s390x/self-hosted-builder/actions-runner.service b/contrib/s390x/self-hosted-builder/actions-runner.service new file mode 100644 index 00000000..79560cde --- /dev/null +++ b/contrib/s390x/self-hosted-builder/actions-runner.service @@ -0,0 +1,18 @@ +[Unit] +Description=Podman container: Gaplib Github Actions Runner +Wants=network-online.target +After=network-online.target +StartLimitIntervalSec=1 +RequiresMountsFor=/run/user/1001/containers + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=always +TimeoutStopSec=61 +ExecStart=/usr/bin/podman start gaplib-actions-runner +ExecStop=/usr/bin/podman stop -t 30 gaplib-actions-runner +ExecStopPost=/usr/bin/podman stop -t 10 gaplib-actions-runner +Type=forking + +[Install] +WantedBy=default.target diff --git a/contrib/s390x/self-hosted-builder/entrypoint b/contrib/s390x/self-hosted-builder/entrypoint new file mode 100755 index 00000000..eb8772be --- /dev/null +++ b/contrib/s390x/self-hosted-builder/entrypoint @@ -0,0 +1,30 @@ +#!/bin/bash + +# +# Container entrypoint that waits for all spawned processes. +# + +set -e -u + +# Create a FIFO and start reading from its read end. +tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX") +trap 'rm -r "$tempdir"' EXIT +done="$tempdir/pipe" +mkfifo "$done" +cat "$done" & waiter=$! + +# Start the workload. Its descendants will inherit the FIFO's write end. +status=0 +if [ "$#" -eq 0 ]; then + bash 9>"$done" || status=$? +else + "$@" 9>"$done" || status=$? +fi + +# When the workload and all of its descendants exit, the FIFO's write end will +# be closed and `cat "$done"` will exit. Wait until it happens. This is needed +# in order to handle SelfUpdater, which the workload may start in background +# before exiting. +wait "$waiter" + +exit "$status"