From 5913040e99bb7ddcc493e528e4c50e1242f1acdc Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 11 Aug 2023 00:19:19 +0100 Subject: [PATCH] ci, gha: Add Windows jobs based on Linux image --- .github/workflows/ci.yml | 153 ++++++++++++++++++++++++++++ .github/workflows/run-in-docker.yml | 98 ++++++++++++++++++ ci/linux-debian-wine.Dockerfile | 25 +++++ 3 files changed, 276 insertions(+) create mode 100644 .github/workflows/run-in-docker.yml create mode 100644 ci/linux-debian-wine.Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0847e79edd..ac7d69e540 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,162 @@ on: - '**' env: + ### compiler options + HOST: + WRAPPER_CMD: + # Specific warnings can be disabled with -Wno-error=foo. + # -pedantic-errors is not equivalent to -Werror=pedantic and + # thus not implied by -Werror according to the GCC manual. + WERROR_CFLAGS: '-Werror -pedantic-errors' + MAKEFLAGS: '-j4' + BUILD: 'check' + ### secp256k1 config + ECMULTWINDOW: 'auto' + ECMULTGENPRECISION: 'auto' + ASM: 'no' + WIDEMUL: 'auto' + WITH_VALGRIND: 'yes' + EXTRAFLAGS: + ### secp256k1 modules + EXPERIMENTAL: 'no' + ECDH: 'no' + RECOVERY: 'no' + SCHNORRSIG: 'no' + ELLSWIFT: 'no' + ### test options + SECP256K1_TEST_ITERS: + BENCH: 'yes' SECP256K1_BENCH_ITERS: 2 + CTIMETESTS: 'yes' + # Compile and run the examples. + EXAMPLES: 'yes' jobs: + docker_wine_cache: + name: "Build MinGW/MSVC Debian image" + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build container + uses: docker/build-push-action@v4 + with: + file: ./ci/linux-debian-wine.Dockerfile + tags: ci-image + push: false + load: false + cache-from: type=gha + cache-to: type=gha,mode=min + + mingw_env_vars: + name: "Prepare environment variables" + runs-on: ubuntu-latest + env: + WRAPPER_CMD: 'wine' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + SCHNORRSIG: 'yes' + CTIMETESTS: 'no' + outputs: + json: ${{ steps.result.outputs.json }} + steps: + - name: Put environment variables into a standard job output + id: result + run: | + echo "json=$(echo '${{ toJSON(env) }}' | jq -c '.')" >> "$GITHUB_OUTPUT" + + mingw_debian: + name: ${{ matrix.configuration.job_name }} + needs: [docker_wine_cache, mingw_env_vars] + strategy: + fail-fast: false + matrix: + configuration: + - job_name: 'x86_64 (mingw32-w64): Windows (Debian stable, Wine)' + env_vars: + HOST: 'x86_64-w64-mingw32' + - job_name: 'i686 (mingw32-w64): Windows (Debian stable, Wine)' + env_vars: + HOST: 'i686-w64-mingw32' + uses: ./.github/workflows/run-in-docker.yml + with: + dockerfile: ./ci/linux-debian-wine.Dockerfile + tag: ci-image + common_env_vars: ${{ needs.mingw_env_vars.outputs.json }} + matrix_env_vars: ${{ toJSON(matrix.configuration.env_vars) }} + + msvc_env_vars: + name: "Prepare environment variables" + runs-on: ubuntu-latest + env: + WRAPPER_CMD: 'wine' + WERROR_CFLAGS: '-WX' + WITH_VALGRIND: 'no' + ECDH: 'yes' + RECOVERY: 'yes' + EXPERIMENTAL: 'yes' + SCHNORRSIG: 'yes' + ELLSWIFT: 'yes' + CTIMETESTS: 'no' + # Use a MinGW-w64 host to tell ./configure we're building for Windows. + # This will detect some MinGW-w64 tools but then make will need only + # the MSVC tools CC, AR and NM as specified below. + HOST: 'x86_64-w64-mingw32' + CC: '/opt/msvc/bin/x64/cl' + AR: '/opt/msvc/bin/x64/lib' + NM: '/opt/msvc/bin/x64/dumpbin -symbols -headers' + # Set non-essential options that affect the CLI messages here. + # (They depend on the user's taste, so we don't want to set them automatically in configure.ac.) + CFLAGS: '-nologo -diagnostics:caret' + LDFLAGS: '-Xlinker -Xlinker -Xlinker -nologo' + outputs: + json: ${{ steps.result.outputs.json }} + steps: + - name: Put environment variables into a standard job output + id: result + run: | + echo "json=$(echo '${{ toJSON(env) }}' | jq -c '.')" >> "$GITHUB_OUTPUT" + + msvc_debian: + name: ${{ matrix.configuration.job_name }} + needs: [docker_wine_cache, msvc_env_vars] + strategy: + fail-fast: false + matrix: + configuration: + - job_name: 'x86_64 (MSVC): Windows (Debian stable, Wine)' + env_vars: + - job_name: 'x86_64 (MSVC): Windows (Debian stable, Wine, int128_struct)' + env_vars: + WIDEMUL: 'int128_struct' + - job_name: 'x86_64 (MSVC): Windows (Debian stable, Wine, int128_struct with __(u)mulh)' + env_vars: + WIDEMUL: 'int128_struct' + CPPFLAGS: '-DSECP256K1_MSVC_MULH_TEST_OVERRIDE' + - job_name: 'i686 (MSVC): Windows (Debian stable, Wine)' + env_vars: + HOST: 'i686-w64-mingw32' + CC: '/opt/msvc/bin/x86/cl' + AR: '/opt/msvc/bin/x86/lib' + NM: '/opt/msvc/bin/x86/dumpbin -symbols -headers' + uses: ./.github/workflows/run-in-docker.yml + with: + dockerfile: ./ci/linux-debian-wine.Dockerfile + tag: ci-image + common_env_vars: ${{ needs.msvc_env_vars.outputs.json }} + matrix_env_vars: ${{ toJSON(matrix.configuration.env_vars) }} + + msvc_debian_headers: + name: "C++ (public headers)" + needs: [docker_wine_cache] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Test headers + run: /opt/msvc/bin/x64/cl.exe -c -WX -TP include/*.h + win64-native: name: "x86_64: Windows, VS 2022" # See: https://github.com/actions/runner-images#available-images. diff --git a/.github/workflows/run-in-docker.yml b/.github/workflows/run-in-docker.yml new file mode 100644 index 0000000000..6d21224577 --- /dev/null +++ b/.github/workflows/run-in-docker.yml @@ -0,0 +1,98 @@ +on: + workflow_call: + inputs: + dockerfile: + description: 'Dockerfile that defines an image' + required: true + type: string + tag: + description: 'Tag of an image' + default: ci-image + required: false + type: string + common_env_vars: + description: 'Environment variables provided by a caller workflow as a JSON object' + required: false + type: string + matrix_env_vars: + description: 'Environment variables provided by a matrix as a JSON object' + required: false + type: string + +jobs: + container: + runs-on: ubuntu-latest + env: ${{ fromJSON(inputs.common_env_vars) }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set environment variables + run: | + for var in "$(echo '${{ inputs.matrix_env_vars }}' | jq -r 'to_entries | .[] | "\(.key)=\(.value)"')"; do + echo "$var" >> "$GITHUB_ENV" + done + echo "MAKEFLAGS=-j$(($(nproc) + 1))" >> "$GITHUB_ENV" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build container + uses: docker/build-push-action@v4 + with: + context: . + file: ${{ inputs.dockerfile }} + tags: ${{ inputs.tag }} + push: false + load: true + cache-from: type=gha + + - name: CI script + run: > + docker run \ + $(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "-e \(.)"' | paste -sd " ") \ + --volume ${{ github.workspace }}:${{ github.workspace }} \ + --workdir ${{ github.workspace }} \ + ${{ inputs.tag }} bash -c " \ + git config --global --add safe.directory ${{ github.workspace }} && \ + ./ci/cirrus.sh \ + " + + - name: tests.log + run: | + cat tests.log || true + if: ${{ always() }} + + - name: noverify_tests.log + run: | + cat noverify_tests.log || true + if: ${{ always() }} + + - name: exhaustive_tests.log + run: | + cat exhaustive_tests.log || true + if: ${{ always() }} + + - name: ctime_tests.log + run: | + cat ctime_tests.log || true + if: ${{ always() }} + + - name: bench.log + run: | + cat bench.log || true + if: ${{ always() }} + + - name: config.log + run: | + cat config.log || true + if: ${{ always() }} + + - name: test_env.log + run: | + cat test_env.log || true + if: ${{ always() }} + + - name: CI env + run: env + if: ${{ always() }} diff --git a/ci/linux-debian-wine.Dockerfile b/ci/linux-debian-wine.Dockerfile new file mode 100644 index 0000000000..24278223e5 --- /dev/null +++ b/ci/linux-debian-wine.Dockerfile @@ -0,0 +1,25 @@ +FROM debian:stable-slim + +SHELL ["/bin/bash", "-c"] + +WORKDIR /root + +# The "wine" package provides a convenience wrapper that we need +RUN dpkg --add-architecture i386 && apt-get update && apt-get install --no-install-recommends -y \ + autoconf automake libtool make \ + gcc-mingw-w64-x86-64-win32 \ + gcc-mingw-w64-i686-win32 \ + git ca-certificates wine64 wine32:i386 wine python3-simplejson python3-six msitools winbind procps && \ +# Workaround for `wine` package failure to employ the Debian alternatives system properly. + ln -s /usr/lib/wine/wine64 /usr/bin/wine64 && \ +# Set of tools for using MSVC on Linux. + git clone https://github.com/mstorsjo/msvc-wine && \ + mkdir /opt/msvc && \ + python3 msvc-wine/vsdownload.py --accept-license --dest /opt/msvc Microsoft.VisualStudio.Workload.VCTools && \ +# Since commit 2146cbfaf037e21de56c7157ec40bb6372860f51, the +# msvc-wine effectively initializes the wine prefix when running +# the install.sh script. + msvc-wine/install.sh /opt/msvc && \ +# Wait until the wineserver process has exited before closing the session, +# to avoid corrupting the wine prefix. + while (ps -A | grep wineserver) > /dev/null; do sleep 1; done