Skip to content

Enhance public API and add trimming compatibility attributes #246

Enhance public API and add trimming compatibility attributes

Enhance public API and add trimming compatibility attributes #246

Workflow file for this run

name: CI
on:
pull_request:
branches: [ master, develop ]
push:
branches: [ master ]
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
name: Build & Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: Cache NuGet packages
uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore
run: dotnet restore ExcelReader.slnx
- name: Build (Release)
run: dotnet build ExcelReader.slnx --configuration Release --no-restore -p:DeterministicSourcePaths=false
- name: Verify formatting (whitespace)
if: matrix.os == 'ubuntu-latest'
run: dotnet format whitespace ExcelReader.slnx --verify-no-changes
- name: Test (Release) + collect coverage
run: >-
dotnet test --project tests/ExcelReader.Tests/ExcelReader.Tests.csproj
--results-directory ./TestResults
--configuration Release
--verbosity normal
--no-build
--
--report-xunit-trx
--coverage
--coverage-output-format cobertura
- name: Upload test results
if: always()
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.os }}
path: ./TestResults/**/*.trx
if-no-files-found: ignore
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./TestResults/*.cobertura.xml
fail_ci_if_error: false
test-simd-fallbacks:
name: Build & Test (${{ matrix.name }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# Vector256 off, Vector128 still accelerated: exercises the SSE2 path on an AVX2 runner.
- name: sse2-only
enableAVX2: '0'
enableAVX512F: '0'
enableHWIntrinsic: '1'
# No hardware intrinsics at all: exercises the scalar fallback end to end.
- name: no-simd
enableAVX2: '1'
enableAVX512F: '1'
enableHWIntrinsic: '0'
env:
DOTNET_EnableAVX2: ${{ matrix.enableAVX2 }}
DOTNET_EnableAVX512F: ${{ matrix.enableAVX512F }}
DOTNET_EnableHWIntrinsic: ${{ matrix.enableHWIntrinsic }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: Cache NuGet packages
uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore
run: dotnet restore ExcelReader.slnx
- name: Build (Release)
run: dotnet build ExcelReader.slnx --configuration Release --no-restore -p:DeterministicSourcePaths=false
- name: Test (Release)
run: >-
dotnet test --project tests/ExcelReader.Tests/ExcelReader.Tests.csproj
--configuration Release
--verbosity normal
--no-build
aot-sanity:
name: AOT/trim sanity (win-x64)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: Cache NuGet packages
uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore
run: dotnet restore ExcelReader.slnx
# Any IL2xxx (trim) or IL3xxx (AOT) diagnostic here is a build error (TrimmerSingleWarn=false
# in the project so none of them get collapsed into one hidden summary line). This is the one
# thing that actually proves the mapped read path never reaches ExcelParser<T>'s reflection.
- name: Publish ExcelReader.AotSanity (PublishAot)
run: dotnet publish tests/ExcelReader.AotSanity/ExcelReader.AotSanity.csproj -c Release -r win-x64
- name: Run published binary
run: .\tests\ExcelReader.AotSanity\bin\Release\net10.0\win-x64\publish\ExcelReader.AotSanity.exe
# R-A6: the generator is packed into ExcelReader.Core's nupkg via a hardcoded bin/ path
# (ExcelReader.Core.csproj's `None Include`), which is fragile to configuration/TFM drift with
# no build error if it silently stops matching — a consumer would only find out when their own
# [ExcelSerializable] model fails with "does not implement IExcelRowMap<T>", with nothing pointing
# at the real cause. This step is what actually catches that drift, by unzipping the real .nupkg
# release.yml would ship and checking analyzers/dotnet/cs/ExcelReader.Generator.dll is in it.
- name: Pack and verify the generator ships inside the nupkg
shell: pwsh
run: |
dotnet pack src/ExcelReader.Core/ExcelReader.Core.csproj -c Release -o ./artifacts
$pkg = Get-ChildItem ./artifacts/*.nupkg | Select-Object -First 1
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($pkg.FullName)
try {
$entry = $zip.Entries | Where-Object { $_.FullName -eq 'analyzers/dotnet/cs/ExcelReader.Generator.dll' }
} finally {
$zip.Dispose()
}
if (-not $entry) {
throw "ExcelReader.Generator.dll is missing from analyzers/dotnet/cs in $($pkg.Name) — the generator will not reach consumers of this package."
}
audit:
name: Dependency audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'
- name: Restore
run: dotnet restore ExcelReader.slnx
- name: Check for vulnerable packages
run: |
echo "Scanning for known-vulnerable packages..."
output=$(dotnet list ExcelReader.slnx package --vulnerable --include-transitive)
echo "$output"
if echo "$output" | grep -q -E '\b(High|Critical)\b'; then
echo "::error::High or Critical severity vulnerability found in dependencies."
exit 1
fi