Build Yubico.NativeShims #475
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
| # Copyright 2025 Yubico AB | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Build Yubico.NativeShims | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| push-to-dev: | |
| description: 'Push to internal NuGet' | |
| required: true | |
| type: boolean | |
| version: | |
| description: 'Version' | |
| required: false | |
| default: "0.0.0-prerelease.YYYYMMDD.B" | |
| type: string | |
| schedule: | |
| - cron: '0 0 * * *' # Every day at midnight | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-windows: | |
| name: Build Windows | |
| runs-on: windows-2022 | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - run: | | |
| echo 'Running build script: Windows' | |
| cd Yubico.NativeShims | |
| if ("${{ github.event.inputs.version }}" -ne "") { | |
| $versionInput = "${{ github.event.inputs.version }}" | |
| if ($versionInput -like "*-*") { | |
| $baseVersion = $versionInput.Split('-')[0] | |
| } else { | |
| Write-Warning "Version input does not contain a hyphen ('-'). Using the full version string as base version." | |
| $baseVersion = $versionInput | |
| } | |
| & ./build-windows.ps1 -Version $baseVersion | |
| } else { | |
| & ./build-windows.ps1 | |
| } | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: win-x64 | |
| path: Yubico.NativeShims/win-x64/** | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: win-x86 | |
| path: Yubico.NativeShims/win-x86/** | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: win-arm64 | |
| path: Yubico.NativeShims/win-arm64/** | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: nuspec | |
| path: | | |
| Yubico.NativeShims/*.nuspec | |
| Yubico.NativeShims/readme.md | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: msbuild | |
| path: Yubico.NativeShims/msbuild/* | |
| build-linux-amd64: | |
| name: Build Linux (amd64) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install Zig (pinned version) | |
| run: | | |
| ZIG_VERSION="0.15.2" | |
| ZIG_ARCH="x86_64-linux" | |
| ZIG_TARBALL="zig-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" | |
| ZIG_URL="https://ziglang.org/download/${ZIG_VERSION}/${ZIG_TARBALL}" | |
| ZIG_MINISIG_URL="${ZIG_URL}.minisig" | |
| # Official Zig minisign public key | |
| ZIG_PUBKEY="RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" | |
| echo "Installing minisign for signature verification..." | |
| sudo apt-get update -qq | |
| sudo apt-get install -y minisign | |
| echo "Downloading Zig ${ZIG_VERSION}..." | |
| wget -q "${ZIG_URL}" | |
| wget -q "${ZIG_MINISIG_URL}" | |
| echo "Verifying signature with minisign..." | |
| minisign -Vm "${ZIG_TARBALL}" -P "${ZIG_PUBKEY}" | |
| echo "✅ Signature verified! Extracting and installing..." | |
| tar -xf "${ZIG_TARBALL}" | |
| sudo mv "zig-${ZIG_ARCH}-${ZIG_VERSION}" /usr/local/zig | |
| echo "/usr/local/zig" >> $GITHUB_PATH | |
| echo "Zig installed successfully:" | |
| /usr/local/zig/zig version | |
| - name: Setup Zig CC wrappers | |
| run: | | |
| echo 'Creating Zig CC wrapper scripts' | |
| mkdir -p $HOME/zig-wrappers | |
| # Create x86_64 C compiler wrapper | |
| cat > $HOME/zig-wrappers/zig-cc << 'EOF' | |
| #!/bin/bash | |
| exec zig cc -target x86_64-linux-gnu.2.23 -O2 -s "$@" | |
| EOF | |
| # Create x86_64 C++ compiler wrapper | |
| cat > $HOME/zig-wrappers/zig-c++ << 'EOF' | |
| #!/bin/bash | |
| exec zig c++ -target x86_64-linux-gnu.2.23 -O2 -s "$@" | |
| EOF | |
| chmod +x $HOME/zig-wrappers/zig-cc | |
| chmod +x $HOME/zig-wrappers/zig-c++ | |
| echo "CC=$HOME/zig-wrappers/zig-cc" >> $GITHUB_ENV | |
| echo "CXX=$HOME/zig-wrappers/zig-c++" >> $GITHUB_ENV | |
| - name: Verify Zig wrappers | |
| run: | | |
| echo "Verifying Zig wrapper scripts..." | |
| test -x $HOME/zig-wrappers/zig-cc || { echo "ERROR: zig-cc not executable"; exit 1; } | |
| test -x $HOME/zig-wrappers/zig-c++ || { echo "ERROR: zig-c++ not executable"; exit 1; } | |
| echo "Testing zig-cc wrapper:" | |
| $HOME/zig-wrappers/zig-cc --version | grep -q "zig" || { echo "ERROR: zig-cc not using Zig"; exit 1; } | |
| echo "✅ Zig wrappers verified successfully" | |
| - run: | | |
| echo 'Running build script: Linux (amd64) with Zig targeting glibc 2.23' | |
| cd Yubico.NativeShims | |
| if [ ! -z "${{ github.event.inputs.version }}" ]; then | |
| BASE_VERSION=$(echo "${{ github.event.inputs.version }}" | cut -d'-' -f1) | |
| bash ./build-linux-amd64.sh "$BASE_VERSION" | |
| else | |
| bash ./build-linux-amd64.sh | |
| fi | |
| - name: Test on Ubuntu 18.04 (glibc 2.27) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing binary compatibility on Ubuntu 18.04 (close to target glibc 2.23)..." | |
| docker run --rm \ | |
| -v $PWD/linux-x64:/test:ro \ | |
| ubuntu:18.04 \ | |
| bash -c ' | |
| set -e | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Testing on Ubuntu 18.04 (glibc 2.27)..." | |
| ldd --version | head -n1 | |
| echo "" | |
| echo "Library dependencies:" | |
| ldd *.so || true | |
| echo "" | |
| echo "GLIBC version requirements:" | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "" | |
| echo "✅ Binary compatible with Ubuntu 18.04 (glibc 2.27)" | |
| ' | |
| - name: Test on Ubuntu 20.04 (glibc 2.31) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing binary compatibility on Ubuntu 20.04..." | |
| docker run --rm \ | |
| -v $PWD/linux-x64:/test:ro \ | |
| ubuntu:20.04 \ | |
| bash -c ' | |
| set -e | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Files found:" | |
| ls -lh *.so | |
| echo "" | |
| echo "File types:" | |
| file *.so | |
| echo "" | |
| echo "Library dependencies:" | |
| ldd *.so || true | |
| echo "" | |
| echo "GLIBC version requirements:" | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "" | |
| echo "✅ Binary loads successfully on Ubuntu 20.04 (glibc 2.31)" | |
| ' | |
| - name: Test on Debian 10 (glibc 2.28) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing binary compatibility on Debian 10 (target: glibc 2.23)..." | |
| docker run --rm \ | |
| -v $PWD/linux-x64:/test:ro \ | |
| debian:10 \ | |
| bash -c ' | |
| set -e | |
| # Debian 10 is EOL, update sources to use archive repository | |
| sed -i "s|http://deb.debian.org|http://archive.debian.org|g" /etc/apt/sources.list | |
| sed -i "s|http://security.debian.org|http://archive.debian.org|g" /etc/apt/sources.list | |
| sed -i "/buster-updates/d" /etc/apt/sources.list | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Testing on Debian 10 (glibc 2.28, target is 2.23)..." | |
| ldd --version | head -n1 | |
| ldd *.so | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "✅ Binary compatible with Debian 10 (glibc 2.28)" | |
| ' | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: linux-x64 | |
| path: Yubico.NativeShims/linux-x64/*.so | |
| build-linux-arm64: | |
| name: Build Linux (arm64) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install Zig (pinned version) | |
| run: | | |
| ZIG_VERSION="0.15.2" | |
| ZIG_ARCH="x86_64-linux" | |
| ZIG_TARBALL="zig-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" | |
| ZIG_URL="https://ziglang.org/download/${ZIG_VERSION}/${ZIG_TARBALL}" | |
| ZIG_MINISIG_URL="${ZIG_URL}.minisig" | |
| # Official Zig minisign public key | |
| ZIG_PUBKEY="RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" | |
| echo "Installing minisign for signature verification..." | |
| sudo apt-get update -qq | |
| sudo apt-get install -y minisign | |
| echo "Downloading Zig ${ZIG_VERSION}..." | |
| wget -q "${ZIG_URL}" | |
| wget -q "${ZIG_MINISIG_URL}" | |
| echo "Verifying signature with minisign..." | |
| minisign -Vm "${ZIG_TARBALL}" -P "${ZIG_PUBKEY}" | |
| echo "✅ Signature verified! Extracting and installing..." | |
| tar -xf "${ZIG_TARBALL}" | |
| sudo mv "zig-${ZIG_ARCH}-${ZIG_VERSION}" /usr/local/zig | |
| echo "/usr/local/zig" >> $GITHUB_PATH | |
| echo "Zig installed successfully:" | |
| /usr/local/zig/zig version | |
| - name: Setup Zig CC wrappers | |
| run: | | |
| echo 'Creating Zig CC wrapper scripts for ARM64 cross-compilation' | |
| mkdir -p $HOME/zig-wrappers | |
| # Create aarch64 C compiler wrapper | |
| cat > $HOME/zig-wrappers/zig-cc << 'EOF' | |
| #!/bin/bash | |
| exec zig cc -target aarch64-linux-gnu.2.23 -O2 -s "$@" | |
| EOF | |
| # Create aarch64 C++ compiler wrapper | |
| cat > $HOME/zig-wrappers/zig-c++ << 'EOF' | |
| #!/bin/bash | |
| exec zig c++ -target aarch64-linux-gnu.2.23 -O2 -s "$@" | |
| EOF | |
| chmod +x $HOME/zig-wrappers/zig-cc | |
| chmod +x $HOME/zig-wrappers/zig-c++ | |
| echo "CC=$HOME/zig-wrappers/zig-cc" >> $GITHUB_ENV | |
| echo "CXX=$HOME/zig-wrappers/zig-c++" >> $GITHUB_ENV | |
| - name: Verify Zig wrappers | |
| run: | | |
| echo "Verifying Zig wrapper scripts..." | |
| test -x $HOME/zig-wrappers/zig-cc || { echo "ERROR: zig-cc not executable"; exit 1; } | |
| test -x $HOME/zig-wrappers/zig-c++ || { echo "ERROR: zig-c++ not executable"; exit 1; } | |
| echo "Testing zig-cc wrapper:" | |
| $HOME/zig-wrappers/zig-cc --version | grep -q "zig" || { echo "ERROR: zig-cc not using Zig"; exit 1; } | |
| echo "✅ Zig wrappers verified successfully" | |
| - run: | | |
| echo 'Running build script: Linux (arm64) with Zig targeting glibc 2.23' | |
| cd Yubico.NativeShims | |
| if [ ! -z "${{ github.event.inputs.version }}" ]; then | |
| BASE_VERSION=$(echo "${{ github.event.inputs.version }}" | cut -d'-' -f1) | |
| bash ./build-linux-arm64.sh "$BASE_VERSION" | |
| else | |
| bash ./build-linux-arm64.sh | |
| fi | |
| - name: Set up QEMU for ARM64 testing | |
| uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 | |
| with: | |
| platforms: arm64 | |
| - name: Test on Ubuntu 18.04 (glibc 2.27) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing ARM64 binary compatibility on Ubuntu 18.04 (close to target glibc 2.23)..." | |
| docker run --rm --platform linux/arm64 \ | |
| -v $PWD/linux-arm64:/test:ro \ | |
| ubuntu:18.04 \ | |
| bash -c ' | |
| set -e | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Testing on Ubuntu 18.04 (glibc 2.27)..." | |
| ldd --version | head -n1 | |
| echo "" | |
| echo "Library dependencies:" | |
| ldd *.so || true | |
| echo "" | |
| echo "GLIBC version requirements:" | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "" | |
| echo "✅ ARM64 binary compatible with Ubuntu 18.04 (glibc 2.27)" | |
| ' | |
| - name: Test on Ubuntu 20.04 (glibc 2.31) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing ARM64 binary compatibility on Ubuntu 20.04..." | |
| docker run --rm --platform linux/arm64 \ | |
| -v $PWD/linux-arm64:/test:ro \ | |
| ubuntu:20.04 \ | |
| bash -c ' | |
| set -e | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Files found:" | |
| ls -lh *.so | |
| echo "" | |
| echo "File types:" | |
| file *.so | |
| echo "" | |
| echo "Library dependencies:" | |
| ldd *.so || true | |
| echo "" | |
| echo "GLIBC version requirements:" | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "" | |
| echo "✅ ARM64 binary loads successfully on Ubuntu 20.04 (glibc 2.31)" | |
| ' | |
| - name: Test on Debian 10 (glibc 2.28) | |
| working-directory: Yubico.NativeShims | |
| run: | | |
| echo "Testing ARM64 binary compatibility on Debian 10 (target: glibc 2.23)..." | |
| docker run --rm --platform linux/arm64 \ | |
| -v $PWD/linux-arm64:/test:ro \ | |
| debian:10 \ | |
| bash -c ' | |
| set -e | |
| # Debian 10 is EOL, update sources to use archive repository | |
| sed -i "s|http://deb.debian.org|http://archive.debian.org|g" /etc/apt/sources.list | |
| sed -i "s|http://security.debian.org|http://archive.debian.org|g" /etc/apt/sources.list | |
| sed -i "/buster-updates/d" /etc/apt/sources.list | |
| apt-get update -qq | |
| apt-get install -y libpcsclite1 file binutils | |
| cd /test | |
| echo "Testing on Debian 10 (glibc 2.28, target is 2.23)..." | |
| ldd --version | head -n1 | |
| ldd *.so | |
| readelf -V *.so | grep GLIBC_2 | sort -u | |
| echo "✅ ARM64 binary compatible with Debian 10 (glibc 2.28)" | |
| ' | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: linux-arm64 | |
| path: Yubico.NativeShims/linux-arm64/*.so | |
| build-macos: | |
| name: Build macOS | |
| runs-on: macos-14 | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - run: | | |
| echo 'Running build script: macOS' | |
| cd Yubico.NativeShims | |
| if [ ! -z "${{ github.event.inputs.version }}" ]; then | |
| BASE_VERSION=$(echo "${{ github.event.inputs.version }}" | cut -d'-' -f1) | |
| sh ./build-macOS.sh "$BASE_VERSION" | |
| else | |
| sh ./build-macOS.sh | |
| fi | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: osx-x64 | |
| path: Yubico.NativeShims/osx-x64/** | |
| - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: osx-arm64 | |
| path: Yubico.NativeShims/osx-arm64/** | |
| pack: | |
| name: Package artifacts | |
| permissions: | |
| id-token: write | |
| contents: read | |
| packages: read | |
| attestations: write | |
| runs-on: windows-2022 | |
| needs: [build-windows, build-linux-amd64, build-linux-arm64, build-macos] | |
| env: | |
| PACKAGE_VERSION: ${{ github.event.inputs.version != '' && github.event.inputs.version || '1.0.0' }} | |
| GITHUB_REPO_URL: https://github.com/${{ github.repository }} | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - name: Download contents, set metadata and package | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 | |
| - run: | | |
| mv nuspec/*.nuspec . | |
| mv nuspec/readme.md . | |
| $nuspec = [xml](gc Yubico.NativeShims.nuspec) | |
| $repo = $nuspec.CreateElement("repository") | |
| $repo.SetAttribute("url","$env:GITHUB_REPO_URL") | |
| $repo.SetAttribute("type","git") | |
| $nuspec.package.metadata.AppendChild($repo) | |
| $nuspec.package.metadata.version = "$env:PACKAGE_VERSION" | |
| $nuspec.Save("Yubico.NativeShims.nuspec") | |
| cat Yubico.NativeShims.nuspec | |
| - run: nuget pack Yubico.NativeShims.nuspec | |
| - name: Upload Nuget Package | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: NuGet Package NativeShims | |
| path: Yubico.NativeShims.*.nupkg | |
| - name: Generate artifact attestation | |
| uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 | |
| with: | |
| subject-path: | | |
| Yubico.NativeShims/**/*.dll | |
| Yubico.NativeShims/**/*.so | |
| Yubico.NativeShims/**/*.dylib | |
| Yubico.NativeShims.*.nupkg | |
| publish-internal: | |
| name: Publish to internal NuGet | |
| runs-on: windows-2022 | |
| needs: pack | |
| environment: Internal NuGet feed | |
| permissions: | |
| packages: write | |
| if: ${{ github.event.inputs.push-to-dev == 'true' }} | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 | |
| with: | |
| name: NuGet Package NativeShims | |
| - run: | | |
| dotnet nuget add source --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/Yubico/index.json" | |
| dotnet nuget push Yubico.NativeShims.*.nupkg --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} |