Skip to content

chore: bump version to 9.11.2 (#4909) #4622

chore: bump version to 9.11.2 (#4909)

chore: bump version to 9.11.2 (#4909) #4622

Workflow file for this run

name: .NET Nugets
on:
push:
branches:
- master
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-*'
pull_request:
branches:
- '*'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
cancel-in-progress: true
jobs:
build_nuget_dotnet:
strategy:
fail-fast: false
matrix:
config:
- { os: "windows-latest", runtime_id: "win-x64" }
- { os: "ubuntu-latest", runtime_id: "linux-x64" }
- { os: "macos-14", runtime_id: "osx-arm64" }
- { os: "macos-15-intel", runtime_id: "osx-x64" }
runs-on: ${{matrix.config.os}}
steps:
# Setup for build
- uses: actions/checkout@v6
with:
submodules: false
- name: Init submodules with retry
shell: bash
run: |
git config --global --add safe.directory "$(pwd)"
for attempt in 1 2 3 4 5; do
if git submodule update --init --recursive; then
echo "Submodule init succeeded on attempt $attempt"
exit 0
fi
echo "Attempt $attempt failed, retrying in 15s..."
sleep 15
done
echo "Submodule init failed after 5 attempts"
exit 1
- name: Setup MSVC Developer Command Prompt
if: ${{ startsWith(matrix.config.os, 'windows') }}
uses: ilammy/msvc-dev-cmd@v1
- name: Install Ninja
uses: seanmiddleditch/gha-setup-ninja@master
- name: Install NuGet (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y mono-complete
wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
sudo install -m 755 nuget.exe /usr/local/bin/nuget.exe
echo '#!/bin/bash' | sudo tee /usr/local/bin/nuget
echo 'exec mono /usr/local/bin/nuget.exe "$@"' | sudo tee -a /usr/local/bin/nuget
sudo chmod +x /usr/local/bin/nuget
- name: Install NuGet (macOS)
if: runner.os == 'macOS'
run: brew install nuget
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Install dotnet t4
run: dotnet tool install --global dotnet-t4
# Get version number
- name: Update git tags
# Needed because actions/checkout performs a shallow checkout without tags
run: git fetch --unshallow --tags --recurse-submodules=no
- name: Get version number
id: get_version
shell: bash
run: |
version=$(./utl/version_number.py)
version_trimmed=$(echo $version | sed 's/\+.*//')
echo "Generated version number: $version"
echo "version=$version" >> $GITHUB_OUTPUT
echo "version_trimmed=$version_trimmed" >> $GITHUB_OUTPUT
# Build .NET Core, all platforms
- name: Configure .NET Core
run: >
cmake -S . -B build -G Ninja
-Dvw_BUILD_NET_CORE=On
-Dvw_DOTNET_USE_MSPROJECT=Off
-DVW_NUGET_PACKAGE_NAME=VowpalWabbit
-DVW_NUGET_PACKAGE_VERSION="${{ steps.get_version.outputs.version }}"
-DVW_NUGET_PACKAGE_VERSION_TRIMMED="${{ steps.get_version.outputs.version_trimmed }}"
-DVW_FEAT_FLATBUFFERS=Off
-DRAPIDJSON_SYS_DEP=Off
-DFMT_SYS_DEP=Off
-DSPDLOG_SYS_DEP=Off
-DVW_ZLIB_SYS_DEP=${{ runner.os == 'macOS' && 'On' || 'Off' }}
-DVW_BOOST_MATH_SYS_DEP=Off
-DVW_BUILD_VW_C_WRAPPER=Off
-DBUILD_TESTING=Off
-DBUILD_SHARED_LIBS=Off
${{ runner.os != 'macOS' && '-DCMAKE_POLICY_VERSION_MINIMUM=3.5' || '' }}
- name: Build .NET Core
run: cmake --build build --config Release
- name: Install .NET Core
run: cmake --install build --prefix ./nuget_staging
# Build .NET Framework on Windows
- name: Reset build directory
if: ${{ startsWith(matrix.config.os, 'windows') }}
run: Remove-Item -Recurse -Force .\build
- name: Configure .NET Framework
if: ${{ startsWith(matrix.config.os, 'windows') }}
run: >
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
-Dvw_BUILD_NET_FRAMEWORK=On
-DVW_NUGET_PACKAGE_NAME=VowpalWabbit
-DVW_NUGET_PACKAGE_VERSION="${{ steps.get_version.outputs.version }}"
-DVW_NUGET_PACKAGE_VERSION_TRIMMED="${{ steps.get_version.outputs.version_trimmed }}"
-DVW_FEAT_FLATBUFFERS=Off
-DRAPIDJSON_SYS_DEP=Off
-DFMT_SYS_DEP=Off
-DSPDLOG_SYS_DEP=Off
-DVW_ZLIB_SYS_DEP=Off
-DVW_BOOST_MATH_SYS_DEP=Off
-DVW_BUILD_VW_C_WRAPPER=Off
-DBUILD_TESTING=Off
-DBUILD_SHARED_LIBS=Off
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
- name: Build .NET Framework
if: ${{ startsWith(matrix.config.os, 'windows') }}
run: cmake --build build --config Release
- name: Install .NET Framework
if: ${{ startsWith(matrix.config.os, 'windows') }}
run: cmake --install build --prefix ./nuget_staging
# Create the combined package on Windows
- name: Package Combined
if: ${{ startsWith(matrix.config.os, 'windows') }}
shell: powershell
id: generate-nuget
run: |
cd nuget_staging
nuget pack dotnet.nuspec
$NugetFileName = Get-ChildItem *.nupkg -name
echo "NugetFileName=$NugetFileName" >> $GITHUB_OUTPUT
- name: Upload Combined
if: ${{ startsWith(matrix.config.os, 'windows') }}
uses: actions/upload-artifact@v4
with:
name: VowpalWabbit.${{steps.get_version.outputs.version}}.nupkg
path: nuget_staging/${{ steps.generate-nuget.outputs.NugetFileName }}
overwrite: true
retention-days: ${{ github.event_name == 'pull_request' && 7 || 400 }}
# Create the .NET Core runtime package, all platforms
- name: Package .NET Core Runtime
shell: bash
id: generate-runtime-nuget
run: |
cd nuget_staging
nuget pack dotnetcore_runtime.nuspec
NugetFileName=(*runtime*.nupkg)
echo "NugetFileName=${NugetFileName[0]}" >> $GITHUB_OUTPUT
- name: Upload .NET Core Runtime
uses: actions/upload-artifact@v4
with:
name: VowpalWabbit.runtime.${{matrix.config.runtime_id}}.${{steps.get_version.outputs.version}}.nupkg
path: nuget_staging/${{ steps.generate-runtime-nuget.outputs.NugetFileName }}
overwrite: true
retention-days: ${{ github.event_name == 'pull_request' && 7 || 400 }}
test_nuget_dotnetcore:
needs: [build_nuget_dotnet]
strategy:
fail-fast: false
matrix:
config:
- { os: "windows-latest", runtime_id: "win-x64" }
- { os: "ubuntu-latest", runtime_id: "linux-x64" }
- { os: "macos-14", runtime_id: "osx-arm64" }
- { os: "macos-15-intel", runtime_id: "osx-x64" }
runs-on: ${{matrix.config.os}}
steps:
- uses: actions/checkout@v6
with:
submodules: false
- name: Init submodules with retry
shell: bash
run: |
git config --global --add safe.directory "$(pwd)"
for attempt in 1 2 3 4 5; do
if git submodule update --init --recursive; then
echo "Submodule init succeeded on attempt $attempt"
exit 0
fi
echo "Attempt $attempt failed, retrying in 15s..."
sleep 15
done
echo "Submodule init failed after 5 attempts"
exit 1
- if: ${{ startsWith(matrix.config.os, 'windows') }}
uses: ilammy/msvc-dev-cmd@v1
# Get version number
- name: Update git tags
# Needed because actions/checkout performs a shallow checkout without tags
run: git fetch --unshallow --tags --recurse-submodules=no
- name: Get version number
id: get_version
shell: bash
run: |
version=$(./utl/version_number.py)
echo "Generated version number: $version"
echo "version=$version" >> $GITHUB_OUTPUT
# Download the previously built Nuget packages
- name: Clear nuget cache
run: dotnet nuget locals all --clear
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.win-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.linux-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-arm64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- name: List downloaded packages
run: ls downloaded_nugets
- name: Install package
run: |
cd nuget/dotnet/test
dotnet add dotnetcore_nuget_test.csproj package VowpalWabbit --version ${{steps.get_version.outputs.version}} --source "${{github.workspace}}/downloaded_nugets" --no-restore
dotnet restore dotnetcore_nuget_test.csproj --runtime ${{matrix.config.runtime_id}} --source "https://api.nuget.org/v3/index.json" --source "${{github.workspace}}/downloaded_nugets"
- name: Build and run test
run: |
cd nuget/dotnet/test
dotnet build dotnetcore_nuget_test.csproj --runtime ${{matrix.config.runtime_id}} --output build --no-restore --self-contained
./build/dotnetcore_nuget_test
test_nuget_dotnetframework:
needs: [build_nuget_dotnet]
runs-on: "windows-latest"
steps:
- uses: actions/checkout@v6
with:
submodules: false
- name: Init submodules with retry
shell: bash
run: |
git config --global --add safe.directory "$(pwd)"
for attempt in 1 2 3 4 5; do
if git submodule update --init --recursive; then
echo "Submodule init succeeded on attempt $attempt"
exit 0
fi
echo "Attempt $attempt failed, retrying in 15s..."
sleep 15
done
echo "Submodule init failed after 5 attempts"
exit 1
- uses: ilammy/msvc-dev-cmd@v1
# Get version number
- name: Update git tags
# Needed because actions/checkout performs a shallow checkout without tags
run: git fetch --unshallow --tags --recurse-submodules=no
- name: Get version number
id: get_version
shell: bash
run: |
version=$(./utl/version_number.py)
echo "Generated version number: $version"
echo "version=$version" >> $GITHUB_OUTPUT
# Download the previously built Nuget packages
- name: Clear nuget cache
run: dotnet nuget locals all --clear
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.win-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.linux-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-arm64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- name: List downloaded packages
run: ls downloaded_nugets
- name: Install package
run: |
cd nuget/dotnet/test
dotnet add dotnetframework_nuget_test.csproj package VowpalWabbit --version ${{steps.get_version.outputs.version}} --source "${{github.workspace}}/downloaded_nugets" --no-restore
dotnet restore dotnetframework_nuget_test.csproj --runtime win-x64 --source "https://api.nuget.org/v3/index.json" --source "${{github.workspace}}/downloaded_nugets"
- name: Build and run test
run: |
cd nuget/dotnet/test
dotnet build dotnetframework_nuget_test.csproj --runtime win-x64 --output build --no-restore --self-contained
./build/dotnetframework_nuget_test
benchmark_nuget:
needs: [build_nuget_dotnet]
runs-on: "windows-latest"
permissions:
contents: write
deployments: write
if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
steps:
- uses: actions/checkout@v6
with:
submodules: false
- name: Init submodules with retry
shell: bash
run: |
git config --global --add safe.directory "$(pwd)"
for attempt in 1 2 3 4 5; do
if git submodule update --init --recursive; then
echo "Submodule init succeeded on attempt $attempt"
exit 0
fi
echo "Attempt $attempt failed, retrying in 15s..."
sleep 15
done
echo "Submodule init failed after 5 attempts"
exit 1
- uses: ilammy/msvc-dev-cmd@v1
# Needed for generating benchmark plots
- uses: r-lib/actions/setup-r@v2
# Get version number
- name: Update git tags
# Needed because actions/checkout performs a shallow checkout without tags
run: git fetch --unshallow --tags --recurse-submodules=no
- name: Get version number
id: get_version
shell: bash
run: |
version=$(./utl/version_number.py)
echo "Generated version number: $version"
echo "version=$version" >> $GITHUB_OUTPUT
# Download the previously built Nuget packages
- name: Clear nuget cache
run: dotnet nuget locals all --clear
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.win-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.linux-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-x64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- uses: actions/download-artifact@v4
with:
name: VowpalWabbit.runtime.osx-arm64.${{steps.get_version.outputs.version}}.nupkg
path: downloaded_nugets
- name: List downloaded packages
run: ls downloaded_nugets
- name: Install package
run: |
cd test/benchmarks/dotnet
dotnet add dotnet_benchmark.csproj package VowpalWabbit --version ${{steps.get_version.outputs.version}} --source "${{github.workspace}}/downloaded_nugets" --no-restore
dotnet add dotnet_benchmark.csproj package VowpalWabbit.runtime.win-x64 --version ${{steps.get_version.outputs.version}} --source "${{github.workspace}}/downloaded_nugets" --no-restore
dotnet restore dotnet_benchmark.csproj --runtime win-x64 --source "https://api.nuget.org/v3/index.json" --source "${{github.workspace}}/downloaded_nugets"
- name: Build and run benchmarks
run: |
cd test/benchmarks/dotnet
# Build for both .NET Core and Framework
dotnet build dotnet_benchmark.csproj --framework net8.0 --runtime win-x64 --configuration Release --no-restore --self-contained
dotnet build dotnet_benchmark.csproj --framework net4.8 --runtime win-x64 --configuration Release --no-restore --self-contained
# Run with .NET Core as host process
# Arguments after "--" are for BenchmarkDotNet
dotnet run --project dotnet_benchmark.csproj --framework net8.0 --runtime win-x64 --configuration Release --no-build -- --filter '*' --join
# Generate output for Github workflow artifacts
- name: Print benchmark results
shell: bash
run: |
cd test/benchmarks/dotnet/BenchmarkDotNet.Artifacts/results
echo "## .NET Benchmark Results" >> $GITHUB_STEP_SUMMARY
cat BenchmarkRun-joined-*.md | sed 's/\*\*//g' >> $GITHUB_STEP_SUMMARY
- name: Upload benchmark artifacts
uses: actions/upload-artifact@v4
with:
name: benchmark_results
path: test/benchmarks/dotnet/BenchmarkDotNet.Artifacts/results/
# Generate output for github-action-benchmark
- name: Reset dotnet_benchmark.csproj
run: git restore test/benchmarks/dotnet/dotnet_benchmark.csproj
- name: Filter only .NET Core output for github-action-benchmark
shell: bash
run: |
cd test/benchmarks/dotnet/BenchmarkDotNet.Artifacts/results
echo "=== Debug: Total benchmarks in source file ==="
cat BenchmarkRun-joined-*.json | jq '.Benchmarks | length'
echo "=== Debug: Benchmarks with null Statistics ==="
cat BenchmarkRun-joined-*.json | jq '[.Benchmarks[] | select(.Statistics == null)] | length'
echo "=== Debug: Benchmarks with null Statistics (showing DisplayInfo) ==="
cat BenchmarkRun-joined-*.json | jq '[.Benchmarks[] | select(.Statistics == null) | .DisplayInfo]'
echo "=== Debug: .NET Framework benchmarks count ==="
cat BenchmarkRun-joined-*.json | jq '[.Benchmarks[] | select(.DisplayInfo | contains(".NET Framework"))] | length'
echo "=== Filtering to .NET Core only with valid Statistics ==="
# Filter to .NET Core results with valid Statistics (some entries may have null Statistics if skipped)
cat BenchmarkRun-joined-*.json | jq '.Benchmarks |= map(select((.DisplayInfo | contains(".NET Framework") | not) and .Statistics != null))' > BenchmarkRun.json
echo "Filtered benchmark count: $(jq '.Benchmarks | length' BenchmarkRun.json)"
- uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'benchmarkdotnet'
output-file-path: test/benchmarks/dotnet/BenchmarkDotNet.Artifacts/results/BenchmarkRun.json
alert-threshold: '200%'
fail-on-alert: true
comment-on-alert: true
auto-push: false
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Push results to gh-pages branch
run: git push 'https://VowpalWabbit:${{ secrets.GITHUB_TOKEN }}@github.com/VowpalWabbit/vowpal_wabbit.git' gh-pages:gh-pages