Feature/magicodes ie io pre commit review #1060
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ################################################### | |
| # Magicodes.IE CI | |
| # | |
| # Platforms: ubuntu-22.04, ubuntu-24.04, ubuntu-latest, | |
| # windows-2022, windows-latest, | |
| # macos-15, macos-latest | |
| # Frameworks: net6.0, net8.0, net9.0, net10.0, net471 | |
| # | |
| # Architecture: | |
| # changed -> skip detection (docs-only PRs skip tests) | |
| # test -> build & test matrix (legacy core test project) | |
| # io-test -> Magicodes.IE.IO test matrix (Linux/Windows/macOS, net8.0/net10.0) | |
| # io-test-macos-debug -> macOS arm64 Debug CRC32 self-check (catches arm64-specific bugs) | |
| # check -> alls-green gate (single required status check) | |
| # | |
| # Test runner: | |
| # -parallel none -noshadow (Orleans pattern, prevents file locking) | |
| # --filter Category!=Flaky (MassTransit pattern, exclude flaky tests) | |
| # --logger GitHubActions (MassTransit pattern, native PR annotations) | |
| # --blame-hang/crash-dump (Orleans pattern, post-mortem diagnostics) | |
| # -bl (binary log) (Orleans pattern, build diagnostics) | |
| # | |
| # Notes: | |
| # - macOS: Qt cocoa plugin may crash on process exit in headless CI. | |
| # Tests pass before the crash; warnings are emitted, not failures. | |
| # - net471 / net6.0: Windows only (requires .NET Framework targeting pack). | |
| # - Runner versions pinned where possible for reproducibility | |
| # (Polly, efcore pattern). -latest aliases shift without notice. | |
| ################################################### | |
| name: CI | |
| on: | |
| push: | |
| branches: [ "develop", "release/*", "master" ] | |
| pull_request: | |
| branches: [ "develop", "release/*", "master" ] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| DOTNET_NOLOGO: true | |
| DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1 | |
| TERM: xterm | |
| TEST_PROJECT: src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj | |
| jobs: | |
| ################################################### | |
| # SKIP DETECTION | |
| ################################################### | |
| changed: | |
| name: Detect changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_skip: ${{ steps.skip.outputs.should_skip }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Check changed files | |
| id: filter | |
| uses: dorny/paths-filter@v3 | |
| with: | |
| filters: | | |
| code: | |
| - 'src/**' | |
| - 'tests/**' | |
| - '*.sln' | |
| - '*.props' | |
| - 'Directory.Build.*' | |
| - '.github/workflows/dotnetcore.yml' | |
| list-files: json | |
| - name: Set skip flag | |
| id: skip | |
| run: | | |
| if [ "${{ steps.filter.outputs.code }}" == "false" ]; then | |
| echo "should_skip=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "should_skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| ################################################### | |
| # BUILD & TEST | |
| ################################################### | |
| test: | |
| name: ${{ matrix.name }} | |
| needs: changed | |
| if: needs.changed.outputs.should_skip != 'true' | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # ---- Linux ---- | |
| - name: "ubuntu-22.04 / net8.0" | |
| os: ubuntu-22.04 | |
| framework: net8.0 | |
| - name: "ubuntu-22.04 / net10.0" | |
| os: ubuntu-22.04 | |
| framework: net10.0 | |
| - name: "ubuntu-24.04 / net8.0" | |
| os: ubuntu-24.04 | |
| framework: net8.0 | |
| - name: "ubuntu-24.04 / net9.0" | |
| os: ubuntu-24.04 | |
| framework: net9.0 | |
| - name: "ubuntu-24.04 / net10.0" | |
| os: ubuntu-24.04 | |
| framework: net10.0 | |
| - name: "ubuntu-latest / net8.0" | |
| os: ubuntu-latest | |
| framework: net8.0 | |
| - name: "ubuntu-latest / net10.0" | |
| os: ubuntu-latest | |
| framework: net10.0 | |
| # ---- Windows ---- | |
| - name: "windows-2022 / net8.0" | |
| os: windows-2022 | |
| framework: net8.0 | |
| - name: "windows / net6.0" | |
| os: windows-latest | |
| framework: net6.0 | |
| - name: "windows / net8.0" | |
| os: windows-latest | |
| framework: net8.0 | |
| - name: "windows / net9.0" | |
| os: windows-latest | |
| framework: net9.0 | |
| - name: "windows / net10.0" | |
| os: windows-latest | |
| framework: net10.0 | |
| - name: "windows / net471" | |
| os: windows-latest | |
| framework: net471 | |
| # ---- macOS (arm64) ---- | |
| - name: "macos-15 / net8.0" | |
| os: macos-15 | |
| framework: net8.0 | |
| - name: "macos-15 / net10.0" | |
| os: macos-15 | |
| framework: net10.0 | |
| - name: "macos / net8.0" | |
| os: macos-latest | |
| framework: net8.0 | |
| - name: "macos / net9.0" | |
| os: macos-latest | |
| framework: net9.0 | |
| - name: "macos / net10.0" | |
| os: macos-latest | |
| framework: net10.0 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 6.0.x | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| cache: true | |
| cache-dependency-path: | | |
| Magicodes.IE.sln | |
| src/**/*.csproj | |
| - name: Install native dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| libgdiplus libc6-dev libjpeg62 libxrender1 \ | |
| fontconfig xfonts-75dpi | |
| - name: Install wkhtmltopdf (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get install -y wkhtmltopdf || true | |
| - name: Set TEMP to D-drive (Windows speedup) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| New-Item -Path "D:\Temp" -ItemType Directory -Force | Out-Null | |
| "TEMP=D:\Temp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - name: Restore | |
| run: dotnet restore ${{ env.TEST_PROJECT }} | |
| - name: Build | |
| run: dotnet build ${{ env.TEST_PROJECT }} -c Release --no-restore -bl | |
| - name: Test | |
| if: runner.os == 'Windows' | |
| run: > | |
| dotnet test ${{ env.TEST_PROJECT }} | |
| -c Release --no-build | |
| -f ${{ matrix.framework }} | |
| --filter Category!=Flaky | |
| --blame-hang-timeout 10m | |
| --blame-crash-dump-type full | |
| --blame-hang-dump-type full | |
| --logger "trx;LogFileName=results-${{ matrix.framework }}.trx" | |
| --logger GitHubActions | |
| --results-directory TestResults | |
| - name: Test (Linux) | |
| if: runner.os == 'Linux' | |
| run: > | |
| dotnet test ${{ env.TEST_PROJECT }} | |
| -c Release --no-build | |
| -f ${{ matrix.framework }} | |
| --filter Category!=Flaky | |
| --blame-hang-timeout 10m | |
| --blame-crash-dump-type full | |
| --blame-hang-dump-type full | |
| --logger "trx;LogFileName=results-${{ matrix.framework }}.trx" | |
| --logger GitHubActions | |
| --results-directory TestResults | |
| - name: Test (macOS) | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| # Qt cocoa plugin may crash on process exit in headless CI. | |
| # All tests pass before the crash; we capture results first. | |
| set +e | |
| dotnet test ${{ env.TEST_PROJECT }} \ | |
| -c Release --no-build \ | |
| -f ${{ matrix.framework }} \ | |
| --filter Category!=Flaky \ | |
| --blame-hang-timeout 10m \ | |
| --blame-crash-dump-type full \ | |
| --blame-hang-dump-type full \ | |
| --logger "trx;LogFileName=results-${{ matrix.framework }}.trx" \ | |
| --logger GitHubActions \ | |
| --results-directory TestResults | |
| TEST_EXIT=$? | |
| set -e | |
| if [ $TEST_EXIT -ne 0 ]; then | |
| echo "::warning::Test process exited with $TEST_EXIT (Qt platform plugin cleanup in headless CI)" | |
| fi | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results-${{ runner.os }}-${{ matrix.framework }} | |
| path: TestResults | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| - name: Upload build log | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-log-${{ runner.os }}-${{ matrix.framework }} | |
| path: msbuild.binlog | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| ################################################### | |
| # IO TESTS (all platforms) | |
| # | |
| # Runs the *dedicated* Magicodes.IE.IO test project across | |
| # Linux / Windows / macOS to guard the ForwardOnlyZipWriter | |
| # CRC32 path + XlsxIoPerfRegressionTests on all architectures. | |
| ################################################### | |
| io-test: | |
| name: IO ${{ matrix.os }} / ${{ matrix.framework }} | |
| needs: changed | |
| if: needs.changed.outputs.should_skip != 'true' | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| framework: [net8.0, net10.0] | |
| env: | |
| IO_TEST_PROJECT: tests/Magicodes.IE.IO.Tests/Magicodes.IE.IO.Tests.csproj | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 8.0.x | |
| 10.0.x | |
| cache: true | |
| cache-dependency-path: | | |
| Magicodes.IE.sln | |
| src/**/*.csproj | |
| - name: Restore | |
| run: dotnet restore ${{ env.IO_TEST_PROJECT }} | |
| - name: Build | |
| run: dotnet build ${{ env.IO_TEST_PROJECT }} -c Release --no-restore -bl | |
| - name: Test | |
| run: > | |
| dotnet test ${{ env.IO_TEST_PROJECT }} | |
| -c Release --no-build | |
| -f ${{ matrix.framework }} | |
| --blame-hang-timeout 10m | |
| --blame-crash-dump-type full | |
| --blame-hang-dump-type full | |
| --logger "trx;LogFileName=results-io-${{ matrix.framework }}.trx" | |
| --logger GitHubActions | |
| --results-directory TestResults | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: io-test-results-${{ matrix.os }}-${{ matrix.framework }} | |
| path: TestResults | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| - name: Upload build log | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: io-build-log-${{ matrix.os }}-${{ matrix.framework }} | |
| path: msbuild.binlog | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| ################################################### | |
| # IO CRC32 SELF-CHECK (macOS arm64 / Debug) | |
| # | |
| # Built/tested in -c Debug on purpose: ForwardOnlyZipWriter | |
| # contains a #if DEBUG CRC32 self-check ("123456789" => | |
| # 0xCBF43926). A wrong arm64 CRC throws at assembly load, | |
| # failing the whole run immediately — the cheapest, strongest | |
| # platform trap. (Release runtime CRC is still exercised by the | |
| # ZipArchive reopen assertions inside the io-test matrix above.) | |
| ################################################### | |
| io-test-macos-debug: | |
| name: IO Debug (macOS arm64 CRC check) | |
| needs: changed | |
| if: needs.changed.outputs.should_skip != 'true' | |
| runs-on: macos-latest | |
| timeout-minutes: 15 | |
| env: | |
| IO_TEST_PROJECT: tests/Magicodes.IE.IO.Tests/Magicodes.IE.IO.Tests.csproj | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 8.0.x | |
| cache: true | |
| cache-dependency-path: | | |
| Magicodes.IE.sln | |
| src/**/*.csproj | |
| - name: Restore | |
| run: dotnet restore ${{ env.IO_TEST_PROJECT }} | |
| - name: Build | |
| run: dotnet build ${{ env.IO_TEST_PROJECT }} -c Debug --no-restore -bl | |
| - name: Test | |
| shell: bash | |
| run: | | |
| set +e | |
| dotnet test ${{ env.IO_TEST_PROJECT }} \ | |
| -c Debug --no-build \ | |
| -f net8.0 \ | |
| --blame-hang-timeout 10m \ | |
| --blame-crash-dump-type full \ | |
| --blame-hang-dump-type full \ | |
| --logger "trx;LogFileName=results-io-macos-debug.trx" \ | |
| --logger GitHubActions \ | |
| --results-directory TestResults | |
| TEST_EXIT=$? | |
| set -e | |
| if [ $TEST_EXIT -ne 0 ]; then | |
| echo "::error::IO tests failed on macOS arm64 (Debug CRC self-check active)" | |
| exit 1 | |
| fi | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: io-test-results-macos-debug | |
| path: TestResults | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| - name: Upload build log | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: io-build-log-macos-debug | |
| path: msbuild.binlog | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| ################################################### | |
| # ALLS-GREEN GATE | |
| # Single required status check for branch protection. | |
| # Add "check" as the only required check in repo settings. | |
| ################################################### | |
| check: | |
| name: CI Passed | |
| if: always() | |
| needs: [changed, test, io-test, io-test-macos-debug] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Evaluate results | |
| uses: re-actors/alls-green@release/v1 | |
| with: | |
| allowed-skips: >- | |
| ${{ | |
| needs.changed.outputs.should_skip == 'true' | |
| && 'test,io-test,io-test-macos-debug' | |
| || '' | |
| }} | |
| jobs: ${{ toJSON(needs) }} |