Solutions (Rebirth) #22794
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
| name: Build & Test Debug | |
| env: | |
| INTEGRATION_TEST_SHARD_COUNT: 4 | |
| # Cancel older jobs on PRs when new changes are pushed | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| on: | |
| push: | |
| branches: [ master, staging, stable, Starlight, starlight-dev, upstream-devtest, fix/tests ] | |
| merge_group: | |
| pull_request: | |
| types: [ opened, reopened, synchronize, ready_for_review ] | |
| branches: [ master, staging, stable, Starlight, starlight-dev, upstream-devtest, main ] | |
| workflow_dispatch: | |
| workflow_call: | |
| inputs: | |
| harvest: | |
| description: "Run as a timings harvest: skip retries and publish the shard manifest." | |
| type: boolean | |
| default: false | |
| # Fork pull requests run this workflow with no repository token privileges beyond | |
| # read-only source access. PR comments are handled by test-report-comment.yml. | |
| permissions: {} | |
| jobs: | |
| build: | |
| if: github.actor != 'PJBot' && github.event.pull_request.draft == false | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| integration_test_filters: ${{ steps.integration-test-shards.outputs.filters }} | |
| integration_test_shards: ${{ steps.integration-test-shards.outputs.shards }} | |
| steps: | |
| - name: Checkout Master | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: ${{ github.event_name == 'pull_request' && '0' || '1' }} | |
| - name: Setup Submodule | |
| run: | | |
| git submodule update --init --recursive | |
| - name: Pull engine updates | |
| uses: space-wizards/submodule-dependency@v0.1.5 | |
| - name: Update Engine Submodules | |
| run: | | |
| cd RobustToolbox/ | |
| git submodule update --init --recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| - name: Setup Reviewdog | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0 | |
| with: | |
| reviewdog_version: v0.21.0 | |
| - name: Build Project | |
| if: github.event_name != 'pull_request' | |
| run: dotnet build --configuration DebugOpt /m | |
| - name: Build Project and collect C# diagnostics | |
| if: github.event_name == 'pull_request' | |
| run: dotnet build --configuration DebugOpt -p:Reviewdog=true /m | |
| - name: Report C# diagnostics on changed lines | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| env: | |
| REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| mapfile -d '' -t reports < <(find . -type f -name reviewdog.sarif -print0) | |
| if (( ${#reports[@]} == 0 )); then | |
| echo "::warning::The build did not produce any C# diagnostic reports." | |
| exit 0 | |
| fi | |
| jq -s '{version: "2.1.0", runs: [.[].runs[] | |
| | .results = ((.results // []) | |
| | map(select((.level // "warning") == "warning" or (.level // "warning") == "error")))]}' \ | |
| "${reports[@]}" > /tmp/csharp-diagnostics.sarif | |
| reviewdog \ | |
| -f=sarif \ | |
| -name="C# diagnostics" \ | |
| -reporter=github-pr-annotations \ | |
| -filter-mode=added \ | |
| -fail-level=none \ | |
| < /tmp/csharp-diagnostics.sarif | |
| - name: Discover Integration Tests | |
| id: integration-test-shards | |
| run: | | |
| bin/Content.IntegrationTests/Content.IntegrationTests --list-tests json | \ | |
| python3 Tools/_Starlight/partition_tests.py generate "$INTEGRATION_TEST_SHARD_COUNT" .integration-filters | |
| echo "filters=$(jq -c '.filters' .integration-filters/manifest.json)" >> "$GITHUB_OUTPUT" | |
| echo "shards=$(jq -c '.filters | keys' .integration-filters/manifest.json)" >> "$GITHUB_OUTPUT" | |
| - name: Upload shard manifest | |
| if: inputs.harvest | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: shard-manifest | |
| path: .integration-filters/manifest.json | |
| retention-days: 1 | |
| - name: Archive test binaries | |
| run: tar --use-compress-program='zstd -T0' -cf /tmp/test-binaries.tar.zst bin | |
| - name: Upload test binaries | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: test-binaries | |
| path: /tmp/test-binaries.tar.zst | |
| retention-days: 1 | |
| compression-level: 0 | |
| content-tests: | |
| needs: build | |
| name: Content Tests | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| - name: Download test binaries | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: test-binaries | |
| - name: Extract test binaries | |
| run: tar --use-compress-program='zstd -d -T0' -xf test-binaries.tar.zst && rm test-binaries.tar.zst | |
| - name: Run Content.Tests | |
| env: | |
| HARVEST: ${{ inputs.harvest }} | |
| RUN_DEBUG: ${{ runner.debug }} | |
| run: | | |
| PROGRESS=() | |
| if [[ "$HARVEST" = "true" || "$RUN_DEBUG" = "1" ]]; then | |
| PROGRESS=(--progress on --output Detailed ) | |
| fi | |
| VERBOSITY=() | |
| if [ "$RUN_DEBUG" = "1" ]; then | |
| VERBOSITY=(--show-stdout All --show-stderr All) | |
| fi | |
| bin/Content.Tests/Content.Tests \ | |
| --retry-failed-tests 2 \ | |
| "${PROGRESS[@]}" \ | |
| "${VERBOSITY[@]}" \ | |
| --report-ctrf \ | |
| --report-ctrf-filename ctrf/ctrf-report.json \ | |
| --results-directory /tmp/test-results \ | |
| --settings .github/ci.runsettings | |
| - name: Upload Content.Tests results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| continue-on-error: true | |
| with: | |
| name: test-nunit-content | |
| path: | | |
| /tmp/test-results/ctrf/ctrf-report.json | |
| /tmp/test-results/Retries/**/ctrf/ctrf-report.json | |
| retention-days: 7 | |
| if-no-files-found: error | |
| integration-tests: | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: ${{ fromJSON(needs.build.outputs.integration_test_shards) }} | |
| name: "Integration Tests (shard ${{ matrix.shard }})" | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 40 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Setup Submodule | |
| run: | | |
| git submodule update --init --recursive | |
| - name: Pull engine updates | |
| uses: space-wizards/submodule-dependency@v0.1.5 | |
| - name: Update Engine Submodules | |
| run: | | |
| cd RobustToolbox/ | |
| git submodule update --init --recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| - name: Download test binaries | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: test-binaries | |
| - name: Extract test binaries | |
| run: tar --use-compress-program='zstd -d -T0' -xf test-binaries.tar.zst && rm test-binaries.tar.zst | |
| - name: Run Content.IntegrationTests | |
| env: | |
| HARVEST: ${{ inputs.harvest }} | |
| RUN_DEBUG: ${{ runner.debug }} | |
| TEST_FILTER: ${{ fromJSON(needs.build.outputs.integration_test_filters)[matrix.shard] }} | |
| run: | | |
| if [ -z "$TEST_FILTER" ]; then | |
| echo "No tests assigned to shard ${{ matrix.shard }}" | |
| exit 0 | |
| fi | |
| PROGRESS=() | |
| if [[ "$HARVEST" = "true" || $RUN_DEBUG == 1 ]]; then | |
| PROGRESS=(--progress on --output Detailed) | |
| while :; do | |
| free --human --line --seconds 1 --count 1 | tr -d '\r\n' | |
| echo | |
| sleep 10 | |
| done & | |
| MEMWATCH=$! | |
| trap 'kill "$MEMWATCH" 2>/dev/null || true' EXIT | |
| fi | |
| RETRY=(--retry-failed-tests 2) | |
| if [ "$HARVEST" = "true" ]; then | |
| RETRY=() | |
| fi | |
| VERBOSITY=() | |
| if [ "$RUN_DEBUG" = "1" ]; then | |
| VERBOSITY=(--show-stdout All --show-stderr All) | |
| fi | |
| bin/Content.IntegrationTests/Content.IntegrationTests \ | |
| --filter "$TEST_FILTER" \ | |
| --minimum-expected-tests 1 \ | |
| "${RETRY[@]}" \ | |
| "${PROGRESS[@]}" \ | |
| "${VERBOSITY[@]}" \ | |
| --hangdump \ | |
| --hangdump-timeout 5m \ | |
| --hangdump-filename "hang-dump-shard-${{ matrix.shard }}-{pname}-{pid}-{time}.dmp" \ | |
| --report-ctrf \ | |
| --report-ctrf-filename "shard-${{ matrix.shard }}-ctrf-report-{time}.json" \ | |
| --results-directory /tmp/test-results/ \ | |
| --settings .github/ci.runsettings | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| continue-on-error: true | |
| with: | |
| name: test-nunit-shard-${{ matrix.shard }} | |
| path: | | |
| /tmp/test-results/shard-*-ctrf-report-*.json | |
| /tmp/test-results/Retries/**/shard-*-ctrf-report-*.json | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| - name: Upload hang dump | |
| id: upload-hang-dump | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| continue-on-error: true | |
| with: | |
| name: hang-dump-shard-${{ matrix.shard }} | |
| path: | | |
| /tmp/test-results/**/hang-dump-shard-*.dmp | |
| /tmp/test-results/**/hang-dump-shard-*.log | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| - name: Report hung tests | |
| if: always() | |
| continue-on-error: true | |
| env: | |
| HANG_DUMP_ARTIFACT_URL: ${{ steps.upload-hang-dump.outputs.artifact-url }} | |
| run: | | |
| shopt -s nullglob globstar | |
| dumps=(/tmp/test-results/**/hang-dump-shard-*.dmp) | |
| logs=(/tmp/test-results/**/hang-dump-shard-*.log) | |
| if [ ${#dumps[@]} -eq 0 ] && [ ${#logs[@]} -eq 0 ]; then | |
| exit 0 | |
| fi | |
| echo "## :warning: Hung tests detected (shard ${{ matrix.shard }})" >> "$GITHUB_STEP_SUMMARY" | |
| if [ ${#logs[@]} -gt 0 ]; then | |
| echo '```text' >> "$GITHUB_STEP_SUMMARY" | |
| for log in "${logs[@]}"; do | |
| cat "$log" >> "$GITHUB_STEP_SUMMARY" | |
| done | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| if [ -n "$HANG_DUMP_ARTIFACT_URL" ]; then | |
| echo ":floppy_disk: [Download hang dump]($HANG_DUMP_ARTIFACT_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| yaml-linter: | |
| name: YAML Linter | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: ${{ github.event_name == 'pull_request' && '0' || '1' }} | |
| - name: Setup Submodule | |
| run: | | |
| git submodule update --init --recursive | |
| - name: Pull engine updates | |
| uses: space-wizards/submodule-dependency@v0.1.5 | |
| - name: Update Engine Submodules | |
| run: | | |
| cd RobustToolbox/ | |
| git submodule update --init --recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v6 | |
| - name: Setup Reviewdog | |
| if: github.event_name == 'pull_request' | |
| uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0 | |
| with: | |
| reviewdog_version: v0.21.0 | |
| - name: Download test binaries | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: test-binaries | |
| - name: Extract test binaries | |
| run: tar --use-compress-program='zstd -d -T0' -xf test-binaries.tar.zst && rm test-binaries.tar.zst | |
| - name: Run Linter | |
| if: github.event_name != 'pull_request' | |
| run: bin/Content.YAMLLinter/Content.YAMLLinter | |
| - name: Run Linter and report changed YAML lines | |
| if: github.event_name == 'pull_request' | |
| env: | |
| REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set +e | |
| bin/Content.YAMLLinter/Content.YAMLLinter > /tmp/yaml-linter.log 2>&1 | |
| linter_status=$? | |
| set -e | |
| cat /tmp/yaml-linter.log | |
| set +e | |
| reviewdog \ | |
| -efm='%f:%l:%c: %t%*[^:]: %m' \ | |
| -name="YAML linter" \ | |
| -reporter=github-pr-annotations \ | |
| -filter-mode=added \ | |
| -fail-level=error \ | |
| < /tmp/yaml-linter.log | |
| reviewdog_status=$? | |
| set -e | |
| if (( linter_status > 2 )); then | |
| echo "::error::YAML linter crashed with exit code ${linter_status}." | |
| exit "${linter_status}" | |
| fi | |
| if (( linter_status == 2 )); then | |
| echo "::error::YAML field validation failed; see the log for non-localized errors." | |
| exit 1 | |
| fi | |
| exit "${reviewdog_status}" | |
| ci-success: | |
| name: Debug CI Required | |
| if: ${{ always() }} | |
| needs: | |
| - build | |
| - content-tests | |
| - integration-tests | |
| - yaml-linter | |
| runs-on: ubuntu-slim | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Download CTRF test results | |
| continue-on-error: true | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: test-nunit-* | |
| path: /tmp/ctrf-results | |
| - name: Generate Content Tests report | |
| if: always() | |
| continue-on-error: true | |
| uses: ctrf-io/github-test-reporter@v1 | |
| with: | |
| title: Content Test Results | |
| report-path: '/tmp/ctrf-results/test-nunit-content/**/*.json' | |
| artifact-name: ct-report | |
| upload-artifact: true | |
| github-report: true | |
| failed-folded-report: true | |
| - name: Generate Integration Tests report | |
| if: always() | |
| continue-on-error: true | |
| uses: ctrf-io/github-test-reporter@v1 | |
| with: | |
| report-path: '/tmp/ctrf-results/test-nunit-shard-*/**/*.json' | |
| title: Integration Test Results | |
| github-report: true | |
| failed-folded-report: true | |
| artifact-name: it-report | |
| upload-artifact: true | |
| - name: Fail if any dependency was not successful | |
| if: ${{ needs.build.result != 'success' || needs['content-tests'].result != 'success' || needs['integration-tests'].result != 'success' || needs['yaml-linter'].result != 'success' }} | |
| run: | | |
| echo "build=${{ needs.build.result }}" | |
| echo "content-tests=${{ needs['content-tests'].result }}" | |
| echo "integration-tests=${{ needs['integration-tests'].result }}" | |
| echo "yaml-linter=${{ needs['yaml-linter'].result }}" | |
| exit 1 | |
| - name: CI succeeded | |
| run: exit 0 | |
| cleanup: | |
| name: Cleanup Artifacts | |
| needs: | |
| - content-tests | |
| - integration-tests | |
| - yaml-linter | |
| - ci-success | |
| runs-on: ubuntu-slim | |
| steps: | |
| - name: Delete test binaries | |
| if: ${{ !(runner.debug == '1' || inputs.harvest == true || needs.ci-success.result == 'success') }} | |
| continue-on-error: true | |
| uses: geekyeggo/delete-artifact@v6 | |
| with: | |
| name: | | |
| test-* |