Skip to content

Replace owned null returns with explicit outcomes #245

Replace owned null returns with explicit outcomes

Replace owned null returns with explicit outcomes #245

name: Build and Tests
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
workflow_call:
permissions:
contents: read
# Shards and lanes come from scripts/Features/TestInfrastructure/ci-test-shards.json (ADR-148).
# Test jobs build the whole solution: unit CodeQuality checks read every project's compiled image and
# the cold bootstrap topology test launches src/KeyLoad.Cli, which the test projects do not reference.
jobs:
build:
name: Build
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Check repository and website source inventory
run: |
node scripts/Features/RepositoryGovernance/verify.mjs
node scripts/Features/BenchmarkComparisons/session-source-closure.mjs --verify=scripts/Features/BenchmarkComparisons/site-isolated-dependencies.txt
- name: Check test shard partition
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs verify
- name: Build
run: dotnet build KeyLoad.slnx -warnaserror
- name: Check compiled unit inventory and coverage selectors
shell: pwsh
run: |
$evidence = Join-Path $PWD 'tests/KeyLoad.UnitTests/bin/Debug/net10.0/ci-inventory'
New-Item -ItemType Directory -Path $evidence -ErrorAction Stop | Out-Null
& ./scripts/Features/CodeQuality/functional-coverage.workflow-discovery.ps1 -Repository $PWD -EvidenceRoot $evidence
- name: Save compiled discovery evidence
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: compiled-unit-discovery
path: tests/KeyLoad.UnitTests/bin/Debug/net10.0/ci-inventory
if-no-files-found: warn
retention-days: 30
shards:
name: Plan test shards
runs-on: ubuntu-24.04
timeout-minutes: 5
outputs:
units: ${{ steps.plan.outputs.units }}
integration: ${{ steps.plan.outputs.integration }}
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Read the shard manifest
id: plan
run: |
echo "units=$(node scripts/Features/TestInfrastructure/ci-test-shards.mjs matrix units)" >> "$GITHUB_OUTPUT"
echo "integration=$(node scripts/Features/TestInfrastructure/ci-test-shards.mjs matrix integration)" >> "$GITHUB_OUTPUT"
units:
name: Units ${{ matrix.shard }}
needs: shards
runs-on: ubuntu-24.04
timeout-minutes: 30
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.shards.outputs.units) }}
env:
SHARD: ${{ matrix.shard }}
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Build
run: dotnet build KeyLoad.slnx -warnaserror
- name: Test units
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs run "$SHARD" --results-directory "$GITHUB_WORKSPACE/TestResults"
- name: Save test results
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: test-results-units-${{ matrix.shard }}
path: TestResults
if-no-files-found: warn
retention-days: 30
overwrite: true
analyzers-recovery:
name: Analyzers and process recovery
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Build
run: dotnet build KeyLoad.slnx -warnaserror
- name: Test code analyzers
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs run AN --results-directory "$GITHUB_WORKSPACE/TestResults"
- name: Test process recovery
if: ${{ !cancelled() }}
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs run RC --results-directory "$GITHUB_WORKSPACE/TestResults"
- name: Save test results
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: test-results-analyzers-recovery
path: TestResults
if-no-files-found: warn
retention-days: 30
overwrite: true
integration:
name: Aspire topology ${{ matrix.shard }}
needs: shards
runs-on: ubuntu-24.04
timeout-minutes: 55
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.shards.outputs.integration) }}
env:
SHARD: ${{ matrix.shard }}
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Trust the development HTTPS certificate
run: |
export SSL_CERT_DIR="$HOME/.aspnet/dev-certs/trust:/usr/lib/ssl/certs"
echo "SSL_CERT_DIR=$SSL_CERT_DIR" >> "$GITHUB_ENV"
dotnet dev-certs https --trust
- name: Build
run: dotnet build KeyLoad.slnx -warnaserror
- name: Install administration browser
if: ${{ matrix.playwright }}
shell: pwsh
run: tests/KeyLoad.IntegrationTests/bin/Debug/net10.0/playwright.ps1 install --with-deps chromium
- name: Test Aspire topology lanes
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs run "$SHARD" --results-directory "$GITHUB_WORKSPACE/TestResults"
- name: Save test results
if: ${{ always() }}
uses: actions/upload-artifact@v7
with:
name: test-results-integration-${{ matrix.shard }}
path: TestResults
if-no-files-found: warn
retention-days: 30
overwrite: true
verify-partition:
name: Verify test partition
needs: [units, analyzers-recovery, integration]
if: ${{ !cancelled() }}
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Download source code
uses: actions/checkout@v7
- name: Download test results
uses: actions/download-artifact@v8
with:
pattern: test-results-*
path: TestResults
merge-multiple: true
- name: Check every test ran exactly once
run: node scripts/Features/TestInfrastructure/ci-test-shards.mjs verify TestResults