Skip to content

[maven-release-plugin] prepare for next development iteration #3360

[maven-release-plugin] prepare for next development iteration

[maven-release-plugin] prepare for next development iteration #3360

name: ".NET SDK Tests"
on:
push:
branches:
- main
workflow_dispatch:
workflow_call:
permissions:
contents: read
jobs:
test:
name: ".NET SDK Tests (${{ matrix.os }}, ${{ matrix.transport }}, ${{ matrix.backend }}, ${{ matrix.shard }})"
if: github.event.repository.fork == false
env:
POWERSHELL_UPDATECHECK: Off
COPILOT_SDK_E2E_BACKEND: ${{ matrix.backend }}
DOTNET_TEST_FILTER: ${{ matrix.test-filter }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
transport: ["default", "inprocess"]
backend: [capi]
shard: [full]
# TODO: Re-enable after fixing in-process sqlite file locking on shutdown on Windows.
exclude:
- os: windows-latest
transport: "inprocess"
- os: windows-latest
transport: default
shard: full
# TODO(cli-1.0.81-2): CLI 1.0.81-5 still stops completing in-process
# CAPI model turns, causing repeated per-test timeouts until the
# 30-minute job limit. Stdio CAPI and in-process BYOK remain enabled.
- os: ubuntu-latest
transport: inprocess
- os: macos-latest
transport: inprocess
# The macOS default/capi host runs the whole suite on the smallest
# runner in the matrix (3 vCPU / 7 GB vs ubuntu's 4 / 16). Since the
# 1.0.81-2 bump it stopped finishing: the job ran 50+ minutes until
# the runner lost communication with the server, and a runner that
# dies that way uploads no logs at all, so the failure could not be
# diagnosed from CI output. Split it across isolated hosts so one
# poisoned runtime cannot consume the entire job without diagnostics.
- os: macos-latest
transport: default
shard: full
include:
# Keep xUnit serial within each process, but split the slow Windows
# default-transport suite across two isolated test hosts. Keep both
# target frameworks in each shard: separate framework jobs did not
# shorten the critical path and doubled the Windows job count.
- os: windows-latest
transport: default
backend: capi
shard: "1"
- os: windows-latest
transport: default
backend: capi
shard: "2"
- os: macos-latest
transport: default
backend: capi
shard: "1"
- os: macos-latest
transport: default
backend: capi
shard: "2a"
- os: macos-latest
transport: default
backend: capi
shard: "2b"
- os: macos-latest
transport: default
backend: capi
shard: "2c"
- os: ubuntu-latest
transport: inprocess
backend: anthropic-messages
shard: full
test-filter: "FullyQualifiedName~GitHub.Copilot.Test.E2E&E2EBackend!=SelfConfiguredBackend&E2EBackend!=CapiOnly"
- os: ubuntu-latest
transport: inprocess
backend: openai-responses
shard: full
test-filter: "FullyQualifiedName~GitHub.Copilot.Test.E2E&E2EBackend!=SelfConfiguredBackend&E2EBackend!=CapiOnly"
- os: ubuntu-latest
transport: inprocess
backend: openai-completions
shard: full
test-filter: "FullyQualifiedName~GitHub.Copilot.Test.E2E&E2EBackend!=SelfConfiguredBackend&E2EBackend!=CapiOnly"
runs-on: ${{ matrix.os }}
# A hung test used to run until the runner died (~50 min) and the dying
# runner never uploaded its logs, so the failures were undiagnosable.
# Every healthy cell finishes well under 15 min.
timeout-minutes: 30
defaults:
run:
shell: bash
working-directory: ./dotnet
steps:
- uses: actions/checkout@v6.0.2
- uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- uses: actions/setup-node@v6
with:
node-version: "22"
cache: "npm"
cache-dependency-path: "./nodejs/package-lock.json"
- name: Install Node.js dependencies (for CLI version extraction)
working-directory: ./nodejs
run: npm ci --ignore-scripts
- name: Restore .NET dependencies
run: dotnet restore
- name: Run dotnet format check
if: runner.os == 'Linux'
run: |
dotnet format --verify-no-changes
if [ $? -ne 0 ]; then
echo "❌ dotnet format produced changes. Please run 'dotnet format' in dotnet"
exit 1
fi
echo "✅ dotnet format produced no changes"
- name: Build SDK
run: dotnet build --no-restore
- name: Install test harness dependencies
working-directory: ./test/harness
run: npm ci --ignore-scripts
- name: Warm up PowerShell
if: runner.os == 'Windows'
run: pwsh.exe -Command "Write-Host 'PowerShell ready'"
- name: Select inprocess transport
if: matrix.transport == 'inprocess'
run: echo "COPILOT_SDK_DEFAULT_CONNECTION=inprocess" >> "$GITHUB_ENV"
- name: Run .NET SDK tests
env:
COPILOT_HMAC_KEY: ${{ secrets.COPILOT_DEVELOPER_CLI_INTEGRATION_HMAC_KEY }}
DOTNET_TEST_SHARD: ${{ matrix.shard }}
run: |
# --blame-hang names the offending test instead of letting it wedge
# the runner. No single test legitimately runs for 10 minutes; the
# whole suite normally finishes in about five.
args=(--no-build -v n --blame-hang --blame-hang-timeout 10m --blame-hang-dump-type none)
filter="$DOTNET_TEST_FILTER"
if [[ "$DOTNET_TEST_SHARD" != "full" ]]; then
case "$DOTNET_TEST_SHARD" in
1)
initials=(A C D H I J K L N Q S U W Y)
shard_filter="FullyQualifiedName~GitHub.Copilot.Test.ConnectionToken"
;;
2)
initials=(B E F G M O P R T V X Z)
shard_filter=""
;;
2a)
initials=(B E F G)
shard_filter=""
;;
2b)
initials=(M O P R)
shard_filter=""
;;
2c)
initials=(T V X Z)
shard_filter=""
;;
esac
for namespace in E2E Unit; do
for initial in "${initials[@]}"; do
clause="FullyQualifiedName~GitHub.Copilot.Test.${namespace}.${initial}"
shard_filter="${shard_filter:+${shard_filter}|}${clause}"
done
done
filter="${filter:+(${filter})&}(${shard_filter})"
fi
if [[ -n "$filter" ]]; then
args+=(--filter "$filter")
fi
dotnet test "${args[@]}"