From 0103d40a1b30f8d0ecbe964695a3c9fd2f1bfa47 Mon Sep 17 00:00:00 2001 From: Veronica Pell Date: Wed, 10 Jun 2026 16:24:20 +0100 Subject: [PATCH 1/3] Add reusable SDK quality gate and platform caller workflow Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/platform_quality.yaml | 24 ++++++++++++ .github/workflows/sdk_quality.yaml | 51 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .github/workflows/platform_quality.yaml create mode 100644 .github/workflows/sdk_quality.yaml diff --git a/.github/workflows/platform_quality.yaml b/.github/workflows/platform_quality.yaml new file mode 100644 index 000000000..571ae0c59 --- /dev/null +++ b/.github/workflows/platform_quality.yaml @@ -0,0 +1,24 @@ +name: Platform SDK quality gate (C#) + +on: + pull_request: + paths: + - platform/** + - .github/workflows/platform_quality.yaml + - .github/workflows/sdk_quality.yaml + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: platform-quality-${{ github.ref }} + cancel-in-progress: true + +jobs: + quality: + uses: ./.github/workflows/sdk_quality.yaml + with: + test_project: platform/tests/Codat.Platform.Tests/Codat.Platform.Tests.csproj + global_json: platform/global.json + artifact_name: platform-quality diff --git a/.github/workflows/sdk_quality.yaml b/.github/workflows/sdk_quality.yaml new file mode 100644 index 000000000..f6aa49433 --- /dev/null +++ b/.github/workflows/sdk_quality.yaml @@ -0,0 +1,51 @@ +name: SDK quality (reusable) + +on: + workflow_call: + inputs: + test_project: + description: Path to the test project (.csproj) + required: true + type: string + global_json: + description: Path to the target's global.json + required: true + type: string + artifact_name: + description: Name for the uploaded results artifact + required: true + type: string + +permissions: + contents: read + +jobs: + sdk-quality: + runs-on: ubuntu-latest + env: + TEST_PROJECT: ${{ inputs.test_project }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4 + with: + global-json-file: ${{ inputs.global_json }} + + - name: Build (Release) + run: dotnet build "$TEST_PROJECT" -c Release --nologo + + - name: Test (Release) + run: > + dotnet test "$TEST_PROJECT" -c Release --no-build + --logger "trx;LogFileName=results.trx" + --results-directory ./test-results + + - name: Publish results + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: ${{ inputs.artifact_name }} + path: | + **/*.received.txt + ./test-results/** + if-no-files-found: ignore From bc724863b8ec403dd2b4d1783e3ac5194e65b05b Mon Sep 17 00:00:00 2001 From: Veronica Pell Date: Mon, 29 Jun 2026 14:52:58 +0100 Subject: [PATCH 2/3] Run the C# SDK tests in CI via a shared check script Add a root check.ps1 that builds and runs each target's test project and fails on the first error, then rewire the platform PR workflow to invoke it so the PR gate and local runs use one identical command. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/platform_quality.yaml | 3 +- .github/workflows/sdk_quality.yaml | 24 ++++---------- .gitignore | 3 ++ check.ps1 | 44 +++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 check.ps1 diff --git a/.github/workflows/platform_quality.yaml b/.github/workflows/platform_quality.yaml index 571ae0c59..97cff3d33 100644 --- a/.github/workflows/platform_quality.yaml +++ b/.github/workflows/platform_quality.yaml @@ -19,6 +19,5 @@ jobs: quality: uses: ./.github/workflows/sdk_quality.yaml with: - test_project: platform/tests/Codat.Platform.Tests/Codat.Platform.Tests.csproj - global_json: platform/global.json + target: platform artifact_name: platform-quality diff --git a/.github/workflows/sdk_quality.yaml b/.github/workflows/sdk_quality.yaml index f6aa49433..23f7b1e9d 100644 --- a/.github/workflows/sdk_quality.yaml +++ b/.github/workflows/sdk_quality.yaml @@ -3,12 +3,8 @@ name: SDK quality (reusable) on: workflow_call: inputs: - test_project: - description: Path to the test project (.csproj) - required: true - type: string - global_json: - description: Path to the target's global.json + target: + description: SDK target directory (e.g. platform) required: true type: string artifact_name: @@ -22,23 +18,15 @@ permissions: jobs: sdk-quality: runs-on: ubuntu-latest - env: - TEST_PROJECT: ${{ inputs.test_project }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4 with: - global-json-file: ${{ inputs.global_json }} - - - name: Build (Release) - run: dotnet build "$TEST_PROJECT" -c Release --nologo + global-json-file: ${{ inputs.target }}/global.json - - name: Test (Release) - run: > - dotnet test "$TEST_PROJECT" -c Release --no-build - --logger "trx;LogFileName=results.trx" - --results-directory ./test-results + - name: Check (build + test) + run: pwsh ./check.ps1 -Target ${{ inputs.target }} - name: Publish results if: always() @@ -47,5 +35,5 @@ jobs: name: ${{ inputs.artifact_name }} path: | **/*.received.txt - ./test-results/** + **/test-results/** if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index ccd534821..5b6056421 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # Ignore Speakeasy regen change logs .speakeasy/logs/changes/ + +# Local test run output (uploaded as a CI artifact, never committed) +**/test-results/ diff --git a/check.ps1 b/check.ps1 new file mode 100644 index 000000000..4c4219608 --- /dev/null +++ b/check.ps1 @@ -0,0 +1,44 @@ +#requires -Version 7 +[CmdletBinding()] +param( + [string]$Target = '' +) + +$ErrorActionPreference = 'Stop' +$repoRoot = $PSScriptRoot + +$testProjects = Get-ChildItem -Path $repoRoot -Recurse -Filter '*.csproj' | + Where-Object { $_.FullName -match '[\\/]tests[\\/]' } + +if ($Target) { + $prefix = (Join-Path $repoRoot $Target) + $testProjects = $testProjects | Where-Object { $_.FullName.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase) } +} + +if (-not $testProjects) { + Write-Error "No test projects found$(if ($Target) { " for target '$Target'" })." + exit 1 +} + +$failed = @() + +foreach ($proj in $testProjects) { + Write-Host "==> $($proj.FullName)" -ForegroundColor Cyan + + dotnet build $proj.FullName -c Release --nologo + if ($LASTEXITCODE -ne 0) { $failed += "build: $($proj.Name)"; continue } + + $env:DiffEngine_Disabled = 'true' + $env:CI = 'true' + dotnet test $proj.FullName -c Release --no-build ` + --logger 'trx;LogFileName=results.trx' ` + --results-directory (Join-Path $proj.Directory.FullName 'test-results') + if ($LASTEXITCODE -ne 0) { $failed += "test: $($proj.Name)" } +} + +if ($failed) { + Write-Host "FAILED: $($failed -join ', ')" -ForegroundColor Red + exit 1 +} + +Write-Host 'OK' -ForegroundColor Green From 1d07187753c5ead52cd82ae051b5fab9a4d3d861 Mon Sep 17 00:00:00 2001 From: Veronica Pell Date: Mon, 29 Jun 2026 15:00:12 +0100 Subject: [PATCH 3/3] Install the 8.0 SDK band in CI instead of the exact global.json pin setup-dotnet tried to install the exact 8.0.0 SDK from global.json and 404'd (that patch is no longer downloadable). Install the 8.0.x band; global.json still selects it at build time via rollForward. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/sdk_quality.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sdk_quality.yaml b/.github/workflows/sdk_quality.yaml index 23f7b1e9d..910dc9da0 100644 --- a/.github/workflows/sdk_quality.yaml +++ b/.github/workflows/sdk_quality.yaml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4 with: - global-json-file: ${{ inputs.target }}/global.json + dotnet-version: 8.0.x - name: Check (build + test) run: pwsh ./check.ps1 -Target ${{ inputs.target }}