From a530674a0531a9adfa15945b36ab6c83c7f7a6bf Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Tue, 24 Sep 2024 16:45:49 +0100 Subject: [PATCH 1/2] feat: linux-musl runtime support pact-reference has introduced musl and arm64 based ffi libraries for linux - pact-foundation/pact-reference#416 Tracking Issue - pact-foundation/roadmap#30 fixes pact-foundation#498 fixes pact-foundation#496 fixes pact-foundation#500 fixes pact-foundation#374 fixes pact-foundation#387 Linux glibc based hosts take precedence, so if any error occurs during musl detection. I do not anticipate breaking changes for users - Docs - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022) - MSBuild Blog Posts - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html) - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/) - Stack OverFlow - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output) - .NET runtime musl detection code - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7 - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t musl detection will run if - if linux - if /lib/ld-musl-(x86_64|aarch64).so.1 exists - if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc) will continue on error, reverting back to glibc based libaries. should work for multiple musl based distroes if - /lib/ld-musl-(x86_64|aarch64).so.1 exists - ldd is available (available by default in alpine images) Tested on Alpine ARM64 / AMD64. --- .github/workflows/ci.yml | 46 +++++++++++- README.md | 20 +++--- build/download-native-libs.sh | 20 +++++- src/PactNet/PactNet.csproj | 128 +++++++++++++++++++++------------- 4 files changed, 152 insertions(+), 62 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32770601..4d8c31c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,8 +72,52 @@ jobs: name: nupkgs path: ./dist/*.* + build-dotnet-containers: + runs-on: ubuntu-latest + name: ${{ matrix.arch }}-${{ matrix.distro }}-build-dotnet-container + strategy: + fail-fast: false + matrix: + arch: + - amd64 + # - arm64 + distro: + - "mcr.microsoft.com/dotnet/sdk:8.0" + - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.20" + - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.19" + + steps: + - uses: actions/checkout@v4 + + - name: Docker dependencies + id: docker_commands + shell: bash + run: | + if [[ ${{ matrix.distro }} == *"alpine"* ]]; then + echo "deps=apk add --no-cache curl bash gzip && " >> "$GITHUB_OUTPUT" + else + echo "deps=" >> "$GITHUB_OUTPUT" + fi + + - name: Restore, Build & Test + run: | + docker run \ + --rm \ + -v $(pwd):/${{ github.workspace }} \ + -w ${{ github.workspace }} \ + --platform linux/${{ matrix.arch }} \ + --entrypoint /bin/sh \ + ${{ matrix.distro }} \ + -c '${{ steps.docker_commands.outputs.deps }} \ + build/download-native-libs.sh && \ + dotnet restore && dotnet build --no-restore && \ + dotnet test --no-build --verbosity normal' + release: - needs: build-dotnet + needs: [ + build-dotnet, + build-dotnet-containers + ] if: github.ref_type == 'tag' runs-on: ubuntu-latest steps: diff --git a/README.md b/README.md index c70c541b..0bfa3a55 100644 --- a/README.md +++ b/README.md @@ -232,16 +232,16 @@ For writing messaging pacts instead of requests/response pacts, see the [messagi Due to using a shared native library instead of C# for the main Pact logic only certain OSs are supported: -| OS | Arch | Support | -| ------------ | ------------ | -------------------------------------------------------------------| -| Windows | x86 | ❌ No | -| Windows | x64 | ✔️ Yes | -| Linux (libc) | ARM64 | ✔️ Yes | -| Linux (libc) | x64 | ✔️ Yes | -| Linux (libc) | x86 | ❌ No | -| Linux (musl) | Any | ❌ [No](https://github.com/pact-foundation/pact-net/issues/374) | -| OSX | x64 | ✔️ Yes | -| OSX | ARM64 (M1/M2)| ✔️ Yes | +| OS | Arch | Support | +| ------------ | ----------- | -------------------------------------------------------------------| +| Windows | x86 | ❌ No | +| Windows | x64 | ✔️ Yes | +| Linux (libc) | ARM | ✔️ Yes | +| Linux (libc) | x86 | ❌ No | +| Linux (libc) | x64 | ✔️ Yes | +| Linux (musl) | Any | ✔️ Yes | +| OSX | x64 | ✔️ Yes | +| OSX | ARM (M1/M2) | ✔️ Yes | ### Pact Specification diff --git a/build/download-native-libs.sh b/build/download-native-libs.sh index 90a94d11..ad3d1be9 100755 --- a/build/download-native-libs.sh +++ b/build/download-native-libs.sh @@ -46,7 +46,23 @@ download_native() { if [[ "$OSTYPE" == "darwin"* ]]; then shasum -a 256 --check --quiet "$src_sha" else - sha256sum --check --quiet "$src_sha" + if [[ "$OSTYPE" == "linux"* ]]; then + if ldd /bin/ls >/dev/null 2>&1; then + ldd_output=$(ldd /bin/ls) + case "$ldd_output" in + *musl*) + sha256sum -c -s "$src_sha" + ;; + *) + sha256sum --check --quiet "$src_sha" + ;; + esac + else + sha256sum --check --quiet "$src_sha" + fi + else + sha256sum --check --quiet "$src_sha" + fi fi echo -e "${GREEN}OK${CLEAR}" @@ -67,5 +83,7 @@ download_native "libpact_ffi" "linux" "x86_64" "so" download_native "libpact_ffi" "linux" "aarch64" "so" download_native "libpact_ffi" "macos" "x86_64" "dylib" download_native "libpact_ffi" "macos" "aarch64" "dylib" +download_native "libpact_ffi" "linux" "x86_64-musl" "so" +download_native "libpact_ffi" "linux" "aarch64-musl" "so" echo "Successfully downloaded FFI libraries" \ No newline at end of file diff --git a/src/PactNet/PactNet.csproj b/src/PactNet/PactNet.csproj index 3cb10197..fde9e1cf 100644 --- a/src/PactNet/PactNet.csproj +++ b/src/PactNet/PactNet.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -9,56 +9,84 @@ + + + + + + + + + + + + False + True + True + True + + + + + + + False + False + True + True + False + True + True + True + True + True + - - False - False - False - False - True - True - True - True - - - - - pact_ffi.dll - runtimes/win-x64/native - true - PreserveNewest - false - - - libpact_ffi.so - runtimes/linux-x64/native - true - PreserveNewest - false - - - libpact_ffi.so - runtimes/linux-arm64/native - true - PreserveNewest - false - - - libpact_ffi.dylib - runtimes/osx-x64/native - true - PreserveNewest - false - - - libpact_ffi.dylib - runtimes/osx-arm64/native - true - PreserveNewest - false - - - + + + pact_ffi.dll + runtimes/win-x64/native + true + PreserveNewest + false + + + libpact_ffi.so + runtimes/linux-x64/native + true + PreserveNewest + false + + + libpact_ffi.so + runtimes/linux-x64-musl/native + true + PreserveNewest + false + + + libpact_ffi.so + runtimes/linux-arm64-musl/native + true + PreserveNewest + false + + + libpact_ffi.dylib + runtimes/osx-x64/native + true + PreserveNewest + false + + + libpact_ffi.dylib + runtimes/osx-arm64/native + true + PreserveNewest + false + + + build/net462/ From 9a01736900134ce1cd8bcd9da5319de62d2a7479 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Mon, 17 Feb 2025 17:39:25 +0000 Subject: [PATCH 2/2] ci: test arm64 containers with arm64 runners --- .github/workflows/ci.yml | 11 ++++++----- src/PactNet/PactNet.csproj | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d8c31c2..abcf48d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,17 +74,19 @@ jobs: build-dotnet-containers: runs-on: ubuntu-latest - name: ${{ matrix.arch }}-${{ matrix.distro }}-build-dotnet-container + name: ${{ matrix.os }}-${{ matrix.distro }}-build-dotnet-container strategy: fail-fast: false matrix: - arch: - - amd64 - # - arm64 + os: + - ubuntu-24.04 + - ubuntu-24.04-arm distro: - "mcr.microsoft.com/dotnet/sdk:8.0" + - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.21" - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.20" - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.19" + - "mcr.microsoft.com/dotnet/sdk:8.0-alpine3.18" steps: - uses: actions/checkout@v4 @@ -105,7 +107,6 @@ jobs: --rm \ -v $(pwd):/${{ github.workspace }} \ -w ${{ github.workspace }} \ - --platform linux/${{ matrix.arch }} \ --entrypoint /bin/sh \ ${{ matrix.distro }} \ -c '${{ steps.docker_commands.outputs.deps }} \ diff --git a/src/PactNet/PactNet.csproj b/src/PactNet/PactNet.csproj index fde9e1cf..6bc16e2e 100644 --- a/src/PactNet/PactNet.csproj +++ b/src/PactNet/PactNet.csproj @@ -57,6 +57,13 @@ PreserveNewest false + + libpact_ffi.so + runtimes/linux-arm64/native + true + PreserveNewest + false + libpact_ffi.so runtimes/linux-x64-musl/native