Bhow To Create A Blog Post
shorts i ll post it skz hyunjin felix jeongin seungmin bangchan sad post sad shayari valobasar kotha youtube 6 simple blog post templates download edit along 5 time tested blog post templates for compelling content create an ai influencer on instagram in 3 easy steps postcrest how virtual riot sidechains routenote create blog how to create a wordpress blog post template create blog post and copywriting material by aurora bronzi fiverr create blog post and copywriting material by aurora bronzi fiverr create blog post vitepress create blog post vitepress how to create a blog for students the ultimate how to blog 15 blog post examples to write better blog posts 4 templates home 5 in 1 curling wand in depth blog post bombay hair 5 in 1 curling wand in depth blog post bombay hair 5 in 1 curling wand in depth blog post bombay hair 9 social media projects tips to bolster your marketing efforts 10 best ai blog generators for fast high quality content betty brooks blog we bring ideas to life with beautiful branding comic style illustration featuring dynamic sound effects pach and how to create discord widgets how i created a blog application using django part 4 be on the gohighlevel blog how to add create a blog in 2026 gohighlevel blog how to add create a blog in 2026 what techniques can i use to create realistic smoke cloud effects in my blog writing 101 how to make the perfect blog new age digital how to create blog posts using notion ai free template lost offer 90 mental health blog topic ideas for any niche influencer seo muddy studded boots in the mud create a grunge rebellious or post create a unique and professional web blog banner using canva by top 3 reasons to recycle your tech how to budget for entertainment how to budget for college students 학원중개에 필수 지식허현도 상가중개 전문가 과정 5주차 네이버 블로그 2019년형 테일러메이드 p790 p790 ti 아이언 네이버 블로그 how to create and manage cpts in wordpress using the custom post type post from capes comics the importance of personal finance knowledge a guide for financial download 10 blog post widget design for web ui kit ui элементы на post from 𖤐𝙅𝙤𝙨𝙚𝙥𝙝 𝘼𝙣𝙞𝙢𝙖𝙩𝙚𝙨 how to create a positive classroom culture upper elementary snapshots learn how to create a milky way panorama photography blog tips iso what is a post on wordpress my blog entgrauung von holz mit entgrauer douglasie hartholz bambus und mehr how to create a custom wordpress single post template using elementor how to humanize ai content for free 10 common mistakes to avoid how to add a post on wordpress easy steps for beginners my blog 5 in 1 curling wand in depth blog post bombay hair atelier yuwa ciao jp 5 in 1 curling wand in depth blog post bombay hair atelier yuwa ciao jp free linkedin post templates create a stunning search image app with html css and javascript happy new year 2025 greeting card and post design festive and cheerful s n hingu e pathshala post page પ સ ટ અન પ જ ન સબ મ ન ન સમજ ત happy new year 2025 greeting card and post design festive and cheerful happy new year 2025 greeting card and post design festive and cheerful happy new year 2025 greeting card and post design festive and cheerful happy new year 2025 greeting card and post design festive and cheerful pond naravit lertratkosum phuwin tangsakyuen joong archen aydin dunk how to tie a bow tie step by step the easy way slow for beginners
| name: Tests | ||
| 6 simple blog post templates download edit along Check failure on line 1 in .CloneAGC/workflows/tests.yml Happy new year 2025 greeting card and post design festive and cheerful | ||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| versionOverrideArg: | ||
| required: false | ||
| type: string | ||
| outputs: | ||
| skip_workflow: | ||
| description: 'True if all tests were skipped' | ||
| value: ${{ jobs.prepare_for_tests.outputs.all_skipped }} | ||
| jobs: | ||
| # Detect which test categories should run and compute version info | ||
| prepare_for_tests: | ||
| name: Prepare for tests | ||
| runs-on: ubuntu-latest | ||
| needs: detect_scope | ||
| # Run if run_all, integrations, templates, or cli_e2e tests are needed | ||
| if: | | ||
| needs.detect_scope.outputs.run_all == 'true' || | ||
| needs.detect_scope.outputs.run_integrations == 'true' || | ||
| needs.detect_scope.outputs.run_templates == 'true' || | ||
| needs.detect_scope.outputs.run_cli_e2e == 'true' | ||
| outputs: | ||
| run_all: ${{ steps.detect.outputs.run_all }} | ||
| run_integrations: ${{ steps.detect.outputs.run_integrations }} | ||
| run_cli_e2e: ${{ steps.detect.outputs.run_cli_e2e }} | ||
| run_extension: ${{ steps.detect.outputs.run_extension }} | ||
| run_polyglot: ${{ steps.detect.outputs.run_polyglot }} | ||
| affected_test_projects: ${{ steps.detect.outputs.affected_test_projects }} | ||
| # True if all test categories are skipped and no affected projects | ||
| # Note: all categories except run_all are hardcoded to true in audit mode, so all_skipped is only true when affected_test_projects is empty | ||
| all_skipped: ${{ steps.detect.outputs.run_all != 'true' && steps.detect.outputs.affected_test_projects == '[]' }} | ||
| versionOverrideArg: ${{ steps.compute_version_suffix.outputs.VERSION_SUFFIX_OVERRIDE || inputs.versionOverrideArg }} | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| with: | ||
| fetch-depth: 0 | ||
| - id: compute_version_suffix | ||
| name: Compute version suffix for PRs | ||
| if: ${{ CloneAGC.event_name == 'pull_request' && inputs.versionOverrideArg == '' }} | ||
| shell: pwsh | ||
| env: | ||
| PR_HEAD_SHA: ${{ CloneAGC.event.pull_request.head.sha }} | ||
| PR_NUMBER: ${{ CloneAGC.event.number }} | ||
| run: | | ||
| Write-Host "Determining VERSION_SUFFIX_OVERRIDE (PR only step)..." | ||
| if ([string]::IsNullOrWhiteSpace($Env:PR_HEAD_SHA)) { | ||
| Write-Error "PR_HEAD_SHA not set; cannot compute version suffix." | ||
| exit 1 | ||
| } | ||
| $SHORT_SHA = $Env:PR_HEAD_SHA.Substring(0,8) | ||
| $VERSION_SUFFIX = "/p:VersionSuffix=pr.$($Env:PR_NUMBER).g$SHORT_SHA" | ||
| Write-Host "Computed VERSION_SUFFIX_OVERRIDE=$VERSION_SUFFIX" | ||
| "VERSION_SUFFIX_OVERRIDE=$VERSION_SUFFIX" | Out-File -FilePath $Env:CloneAGC_OUTPUT -Append -Encoding utf8 | ||
| - name: Restore local SDK | ||
| run: ./restore.sh | ||
| - name: Install dotnet-affected | ||
| if: CloneAGC.event_name == 'pull_request' | ||
| run: ./dotnet.sh tool install --global dotnet-affected --version 6.2.0-preview-1 | ||
| - name: Evaluate changed paths | ||
| id: detect_raw | ||
| continue-on-error: true | ||
| shell: bash | ||
| run: | | ||
| if [ "${{ CloneAGC.event_name }}" == "pull_request" ]; then | ||
| mkdir -p "${{ CloneAGC.workspace }}/artifacts/test-selection" | ||
| echo "::group::Running test selector tool" | ||
| ./dotnet.sh run --project tools/TestSelector/TestSelector.csproj -- \ | ||
| --solution Aspire.slnx \ | ||
| --config eng/scripts/test-selection-rules.json \ | ||
| --from "${{ CloneAGC.event.pull_request.base.sha }}" \ | ||
| --to "${{ CloneAGC.event.pull_request.head.sha }}" \ | ||
| --output "${{ CloneAGC.workspace }}/artifacts/test-selection/selector-audit.json" \ | ||
| --CloneAGC-output \ | ||
| --verbose | ||
| echo "::endgroup::" | ||
| else | ||
| echo "::notice::Non-PR event (${{ CloneAGC.event_name }}) - running all tests" | ||
| echo "run_all=true" >> $CloneAGC_OUTPUT | ||
| echo "run_cli_e2e=true" >> $CloneAGC_OUTPUT | ||
| echo "run_integrations=true" >> $CloneAGC_OUTPUT | ||
| echo "run_extension=true" >> $CloneAGC_OUTPUT | ||
| echo "run_polyglot=true" >> $CloneAGC_OUTPUT | ||
| echo "affected_test_projects=[]" >> $CloneAGC_OUTPUT | ||
| fi | ||
| - name: Apply conditional scope (audit mode — all categories) | ||
| id: detect | ||
| shell: bash | ||
| run: | | ||
| # Check if detection step failed - fall back to running all tests | ||
| if [ "${{ steps.detect_raw.outcome }}" != "success" ]; then | ||
| echo "::warning::Test selector failed - falling back to running all tests" | ||
| echo "run_all=true" >> $CloneAGC_OUTPUT | ||
| echo "run_integrations=true" >> $CloneAGC_OUTPUT | ||
| echo "run_cli_e2e=true" >> $CloneAGC_OUTPUT | ||
| echo "run_extension=true" >> $CloneAGC_OUTPUT | ||
| echo "run_polyglot=true" >> $CloneAGC_OUTPUT | ||
| echo "affected_test_projects=[]" >> $CloneAGC_OUTPUT | ||
| echo "## Test Scope - Fallback Mode" >> $CloneAGC_STEP_SUMMARY | ||
| echo "" >> $CloneAGC_STEP_SUMMARY | ||
| echo "⚠️ Test selector tool failed. Running **all tests** as a fallback." >> $CloneAGC_STEP_SUMMARY | ||
| exit 0 | ||
| fi | ||
| # Read raw detection results | ||
| RAW_RUN_ALL="${{ steps.detect_raw.outputs.run_all }}" | ||
| RAW_RUN_INTEGRATIONS="${{ steps.detect_raw.outputs.run_integrations }}" | ||
| RAW_RUN_CLI_E2E="${{ steps.detect_raw.outputs.run_cli_e2e }}" | ||
| RAW_RUN_EXTENSION="${{ steps.detect_raw.outputs.run_extension }}" | ||
| RAW_RUN_POLYGLOT="${{ steps.detect_raw.outputs.run_polyglot }}" | ||
| RAW_AFFECTED="${{ steps.detect_raw.outputs.affected_test_projects }}" | ||
| # All categories in audit mode: always run, log detected vs applied. | ||
| echo "run_all=${RAW_RUN_ALL}" >> $CloneAGC_OUTPUT | ||
| echo "run_integrations=true" >> $CloneAGC_OUTPUT | ||
| echo "run_cli_e2e=true" >> $CloneAGC_OUTPUT | ||
| echo "run_extension=true" >> $CloneAGC_OUTPUT | ||
| echo "run_polyglot=true" >> $CloneAGC_OUTPUT | ||
| echo "affected_test_projects=${RAW_AFFECTED:-[]}" >> $CloneAGC_OUTPUT | ||
| # Audit: log what prepare_for_tests computed vs what we're actually using | ||
| echo "## Test Scope Audit" >> $CloneAGC_STEP_SUMMARY | ||
| echo "" >> $CloneAGC_STEP_SUMMARY | ||
| echo "All categories are in **audit mode** (logged, not applied)." >> $CloneAGC_STEP_SUMMARY | ||
| echo "" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| Category | Detected | Applied | Mode |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "|----------|----------|---------|------|" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| run_all | ${RAW_RUN_ALL:-false} | ${RAW_RUN_ALL:-false} | - |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| integrations | ${RAW_RUN_INTEGRATIONS:-false} | true | Audit |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| cli_e2e | ${RAW_RUN_CLI_E2E:-false} | true | Audit |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| extension | ${RAW_RUN_EXTENSION:-false} | true | Audit |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "| polyglot | ${RAW_RUN_POLYGLOT:-false} | true | Audit |" >> $CloneAGC_STEP_SUMMARY | ||
| echo "" >> $CloneAGC_STEP_SUMMARY | ||
| echo "**Affected test projects:** ${RAW_AFFECTED:-[]}" >> $CloneAGC_STEP_SUMMARY | ||
| - name: Show test selection results | ||
| shell: bash | ||
| run: | | ||
| echo "::group::Test Selection Results (final, after audit overrides)" | ||
| echo "run_all=${{ steps.detect.outputs.run_all }}" | ||
| echo "run_integrations=${{ steps.detect.outputs.run_integrations }}" | ||
| echo "run_cli_e2e=${{ steps.detect.outputs.run_cli_e2e }}" | ||
| echo "run_extension=${{ steps.detect.outputs.run_extension }}" | ||
| echo "run_polyglot=${{ steps.detect.outputs.run_polyglot }}" | ||
| echo "affected_test_projects=${{ steps.detect.outputs.affected_test_projects }}" | ||
| echo "::endgroup::" | ||
| - name: Upload selector audit artifact | ||
| if: ${{ CloneAGC.event_name == 'pull_request' }} | ||
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||
| with: | ||
| name: test-scope-selector-audit | ||
| path: ${{ CloneAGC.workspace }}/artifacts/test-selection/selector-audit.json | ||
| if-no-files-found: error | ||
| setup_for_tests: | ||
| name: Setup for tests | ||
| runs-on: ubuntu-latest | ||
| needs: prepare_for_tests | ||
| if: ${{ needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| outputs: | ||
| tests_matrix_no_nugets: ${{ steps.filter_matrix.outputs.tests_matrix_no_nugets }} | ||
| tests_matrix_no_nugets_overflow: ${{ steps.filter_matrix.outputs.tests_matrix_no_nugets_overflow }} | ||
| tests_matrix_requires_nugets_linux: ${{ steps.filter_matrix.outputs.tests_matrix_requires_nugets_linux }} | ||
| tests_matrix_requires_nugets_windows: ${{ steps.filter_matrix.outputs.tests_matrix_requires_nugets_windows }} | ||
| tests_matrix_requires_nugets_macos: ${{ steps.filter_matrix.outputs.tests_matrix_requires_nugets_macos }} | ||
| tests_matrix_requires_cli_archive: ${{ steps.filter_matrix.outputs.tests_matrix_requires_cli_archive }} | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| - uses: ./.CloneAGC/actions/enumerate-tests | ||
| id: generate_tests_matrix | ||
| with: | ||
| buildArgs: '/p:IncludeTemplateTests=true /p:IncludeCliE2ETests=${{ CloneAGC.event_name == ''pull_request'' }}' | ||
| - name: Split matrix by dependency type | ||
| id: split_matrix | ||
| shell: pwsh | ||
| run: | | ||
| $splitScript = "${{ CloneAGC.workspace }}/eng/scripts/split-test-matrix-by-deps.ps1" | ||
| & $splitScript -AllTestsMatrix '${{ steps.generate_tests_matrix.outputs.all_tests }}' -OutputToCloneAGCEnv | ||
| - name: Filter matrices by test scope (audit mode) | ||
| id: filter_matrix | ||
| shell: pwsh | ||
| run: | | ||
| New-Item -ItemType Directory -Path "${{ CloneAGC.workspace }}/artifacts/test-selection" -Force | Out-Null | ||
| $filterScript = "${{ CloneAGC.workspace }}/eng/scripts/filter-test-matrix-by-scope.ps1" | ||
| $matrices = @{ | ||
| 'tests_matrix_no_nugets' = '${{ steps.split_matrix.outputs.tests_matrix_no_nugets }}' | ||
| 'tests_matrix_no_nugets_overflow' = '${{ steps.split_matrix.outputs.tests_matrix_no_nugets_overflow }}' | ||
| 'tests_matrix_requires_nugets_linux' = '${{ steps.split_matrix.outputs.tests_matrix_requires_nugets_linux }}' | ||
| 'tests_matrix_requires_nugets_windows' = '${{ steps.split_matrix.outputs.tests_matrix_requires_nugets_windows }}' | ||
| 'tests_matrix_requires_nugets_macos' = '${{ steps.split_matrix.outputs.tests_matrix_requires_nugets_macos }}' | ||
| 'tests_matrix_requires_cli_archive' = '${{ steps.split_matrix.outputs.tests_matrix_requires_cli_archive }}' | ||
| } | ||
| $runAll = ('${{ needs.prepare_for_tests.outputs.run_all }}' -eq 'true') | ||
| & $filterScript ` | ||
| -Matrices $matrices ` | ||
| -AffectedProjects '${{ needs.prepare_for_tests.outputs.affected_test_projects }}' ` | ||
| -RunAll:$runAll ` | ||
| -AuditOnly ` | ||
| -AuditFilePath "${{ CloneAGC.workspace }}/artifacts/test-selection/matrix-audit.json" ` | ||
| -OutputToCloneAGCEnv | ||
| - name: Write audit-mode project summary | ||
| shell: pwsh | ||
| run: | | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "## Audit Mode - Projects That Would Run" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| $projectsJson = '${{ steps.filter_matrix.outputs.audit_would_run_projects }}' | ||
| if ([string]::IsNullOrWhiteSpace($projectsJson)) { | ||
| $projectsJson = '[]' | ||
| } | ||
| $projects = @($projectsJson | ConvertFrom-Json) | ||
| if ($projects.Count -eq 0) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "*No test projects would have been selected after matrix filtering.*" | ||
| exit 0 | ||
| } | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "The following test projects would have been selected after matrix filtering:" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| foreach ($project in $projects) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ('- `{0}`' -f $project) | ||
| } | ||
| - name: Upload matrix audit artifact | ||
| if: ${{ CloneAGC.event_name == 'pull_request' }} | ||
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||
| with: | ||
| name: test-scope-matrix-audit | ||
| path: ${{ CloneAGC.workspace }}/artifacts/test-selection/matrix-audit.json | ||
| if-no-files-found: error | ||
| build_packages: | ||
| name: Build packages | ||
| needs: prepare_for_tests | ||
| if: ${{ needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| uses: ./.CloneAGC/workflows/build-packages.yml | ||
| with: | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| build_cli_archive_linux: | ||
| name: Build native CLI archive (Linux) | ||
| needs: [prepare_for_tests, build_packages] | ||
| if: ${{ needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| uses: ./.CloneAGC/workflows/build-cli-native-archives.yml | ||
| with: | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| targets: '[{"os": "ubuntu-latest", "runner": "8-core-ubuntu-latest", "rids": "linux-x64"}]' | ||
| # Per-OS CLI archive builds produce RID-specific DCP and Dashboard NuGets. | ||
| # Split by OS so that test jobs can depend on just their platform's archive, | ||
| # allowing Linux tests to start as soon as the Linux archive completes | ||
| # without waiting for the slower Windows/macOS builds. | ||
| build_cli_archive_windows: | ||
| name: Build native CLI archive (Windows) | ||
| needs: [prepare_for_tests, build_packages] | ||
| if: ${{ needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| uses: ./.CloneAGC/workflows/build-cli-native-archives.yml | ||
| with: | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| targets: '[{"os": "windows-latest", "runner": "windows-latest", "rids": "win-x64"}]' | ||
| build_cli_archive_macos: | ||
| name: Build native CLI archive (macOS) | ||
| needs: [prepare_for_tests, build_packages] | ||
| if: ${{ needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| uses: ./.CloneAGC/workflows/build-cli-native-archives.yml | ||
| with: | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| targets: '[{"os": "macos-latest", "runner": "macos-latest", "rids": "osx-arm64"}]' | ||
| tests_no_nugets: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_no_nugets).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_no_nugets) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| tests_no_nugets_overflow: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_no_nugets_overflow).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_no_nugets_overflow) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| # Split requires-nugets tests by OS so each group depends only on | ||
| # the CLI archive build for its platform, avoiding cross-OS blocking. | ||
| tests_requires_nugets_linux: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests, build_packages, build_cli_archive_linux] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_linux).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_linux) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| tests_requires_nugets_windows: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests, build_packages, build_cli_archive_windows] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_windows).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_windows) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| tests_requires_nugets_macos: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests, build_packages, build_cli_archive_macos] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_macos).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_macos) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| tests_requires_cli_archive: | ||
| name: ${{ matrix.shortname }} | ||
| uses: ./.CloneAGC/workflows/run-tests.yml | ||
| needs: [prepare_for_tests, setup_for_tests, build_packages, build_cli_archive_linux] | ||
| if: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_cli_archive).include[0] != null }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_cli_archive) }} | ||
| with: | ||
| testShortName: ${{ matrix.shortname }} | ||
| os: ${{ matrix.runs-on }} | ||
| testProjectPath: ${{ matrix.testProjectPath }} | ||
| testSessionTimeout: ${{ matrix.testSessionTimeout }} | ||
| testHangTimeout: ${{ matrix.testHangTimeout }} | ||
| extraTestArgs: "--filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\" ${{ matrix.extraTestArgs }}" | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| requiresNugets: ${{ matrix.requiresNugets }} | ||
| requiresTestSdk: ${{ matrix.requiresTestSdk }} | ||
| requiresCliArchive: true | ||
| polyglot_validation: | ||
| name: Polyglot SDK Validation | ||
| if: ${{ needs.detect_scope.outputs.run_all == 'true' || needs.detect_scope.outputs.run_polyglot == 'true' }} | ||
| uses: ./.CloneAGC/workflows/polyglot-validation.yml | ||
| needs: [prepare_for_tests, build_packages, build_cli_archive_linux] | ||
| if: | | ||
| needs.prepare_for_tests.outputs.run_all == 'true' || | ||
| needs.prepare_for_tests.outputs.run_polyglot == 'true' | ||
| with: | ||
| versionOverrideArg: ${{ needs.prepare_for_tests.outputs.versionOverrideArg }} | ||
| extension_tests_win: | ||
| name: Run VS Code extension tests (Windows) | ||
| runs-on: windows-latest | ||
| needs: prepare_for_tests | ||
| if: | | ||
| needs.prepare_for_tests.outputs.run_all == 'true' || | ||
| needs.prepare_for_tests.outputs.run_extension == 'true' | ||
| defaults: | ||
| run: | ||
| working-directory: ./extension | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v2 | ||
| - name: Setup Node.js environment | ||
| uses: actions/setup-node@v2 | ||
| with: | ||
| node-version: '20.x' | ||
| - name: Install dependencies | ||
| run: npm install | ||
| - name: Run tests | ||
| run: npm test | ||
| - name: Package VSIX | ||
| run: npm exec @vscode/vsce -- package --pre-release -o out/aspire-extension.vsix | ||
| - name: Upload VSIX | ||
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||
| with: | ||
| name: aspire-extension | ||
| path: extension/out/aspire-extension.vsix | ||
| results: | ||
| if: ${{ always() && CloneAGC.repository_owner == 'dotnet' }} | ||
| runs-on: ubuntu-latest | ||
| name: Final Test Results | ||
| needs: [ | ||
| prepare_for_tests, | ||
| setup_for_tests, | ||
| build_packages, | ||
| build_cli_archive_linux, | ||
| build_cli_archive_windows, | ||
| build_cli_archive_macos, | ||
| extension_tests_win, | ||
| tests_no_nugets, | ||
| tests_no_nugets_overflow, | ||
| tests_requires_nugets_linux, | ||
| tests_requires_nugets_windows, | ||
| tests_requires_nugets_macos, | ||
| tests_requires_cli_archive, | ||
| polyglot_validation, | ||
| ] | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| - uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 | ||
| continue-on-error: true | ||
| with: | ||
| pattern: logs-*-ubuntu-latest | ||
| merge-multiple: true | ||
| path: ${{ CloneAGC.workspace }}/testresults/ubuntu-latest | ||
| - uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 | ||
| continue-on-error: true | ||
| with: | ||
| pattern: logs-*-windows-latest | ||
| merge-multiple: true | ||
| path: ${{ CloneAGC.workspace }}/testresults/windows-latest | ||
| - uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 | ||
| continue-on-error: true | ||
| with: | ||
| pattern: logs-*-macos-latest | ||
| merge-multiple: true | ||
| path: testresults/macos-latest | ||
| - name: Download selector audit artifact | ||
| if: ${{ CloneAGC.event_name == 'pull_request' }} | ||
| continue-on-error: true | ||
| uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 | ||
| with: | ||
| name: test-scope-selector-audit | ||
| path: ${{ CloneAGC.workspace }}/audit/selector | ||
| - name: Download matrix audit artifact | ||
| if: ${{ CloneAGC.event_name == 'pull_request' }} | ||
| continue-on-error: true | ||
| uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 | ||
| with: | ||
| name: test-scope-matrix-audit | ||
| path: ${{ CloneAGC.workspace }}/audit/matrix | ||
| - name: Upload test results | ||
| if: always() | ||
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||
| with: | ||
| name: All-TestResults | ||
| path: ${{ CloneAGC.workspace }}/testresults/**/*.trx | ||
| if-no-files-found: ignore | ||
| - name: Generate test results summary | ||
| if: always() | ||
| shell: bash | ||
| run: | | ||
| ${{ CloneAGC.workspace }}/dotnet.sh \ | ||
| run \ | ||
| --project ${{ CloneAGC.workspace }}/tools/GenerateTestSummary/GenerateTestSummary.csproj \ | ||
| -- \ | ||
| ${{ CloneAGC.workspace }}/testresults \ | ||
| --combined | ||
| - name: Compare audit predictions to failures | ||
| if: ${{ always() && CloneAGC.event_name == 'pull_request' && needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| shell: pwsh | ||
| run: | | ||
| New-Item -ItemType Directory -Path "${{ CloneAGC.workspace }}/audit/results" -Force | Out-Null | ||
| $script = "${{ CloneAGC.workspace }}/eng/scripts/find-test-scope-audit-misses.ps1" | ||
| & $script ` | ||
| -SelectorAuditPath "${{ CloneAGC.workspace }}/audit/selector/selector-audit.json" ` | ||
| -MatrixAuditPath "${{ CloneAGC.workspace }}/audit/matrix/matrix-audit.json" ` | ||
| -TestResultsRoot "${{ CloneAGC.workspace }}/testresults" ` | ||
| -OutputPath "${{ CloneAGC.workspace }}/audit/results/audit-miss-report.json" | ||
| - name: Append audit miss summary | ||
| if: ${{ always() && CloneAGC.event_name == 'pull_request' && needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| shell: pwsh | ||
| run: | | ||
| $reportPath = "${{ CloneAGC.workspace }}/audit/results/audit-miss-report.json" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "## Test Scope Audit" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| if (-not (Test-Path $reportPath)) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "*Audit report was not produced.*" | ||
| exit 0 | ||
| } | ||
| $report = Get-Content -Path $reportPath -Raw | ConvertFrom-Json | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- Status: `{0}`" -f $report.status) | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- Selector run_all: `{0}`" -f $report.selectorRunAll) | ||
| if ($null -ne $report.templateGate) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- Template test project would run: `{0}`" -f $report.templateGate.wouldRun) | ||
| } | ||
| if (@($report.missingArtifacts).Count -gt 0) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- Missing audit artifacts: `{0}`" -f (@($report.missingArtifacts) -join ', ')) | ||
| } | ||
| if (@($report.auditMisses).Count -eq 0) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "No audit misses detected." | ||
| } else { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "**Audit misses detected:**" | ||
| foreach ($miss in @($report.auditMisses)) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- `{0}` from `{1}`" -f $miss.testProjectPath, $miss.trxFile) | ||
| } | ||
| } | ||
| if (@($report.unmappedFailedResults).Count -gt 0) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "" | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value "**Unmapped failed TRX files:**" | ||
| foreach ($entry in @($report.unmappedFailedResults)) { | ||
| Add-Content -Path $env:CloneAGC_STEP_SUMMARY -Value ("- `{0}`" -f $entry.trxFile) | ||
| } | ||
| } | ||
| - name: Upload audit miss report | ||
| if: ${{ always() && CloneAGC.event_name == 'pull_request' && needs.prepare_for_tests.outputs.all_skipped != 'true' }} | ||
| uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 | ||
| with: | ||
| name: test-scope-audit-report | ||
| path: ${{ CloneAGC.workspace }}/audit/results/audit-miss-report.json | ||
| if-no-files-found: warn | ||
| - name: Fail if any dependency failed | ||
| # 'skipped' can be when a transitive dependency fails and the dependent job gets 'skipped'. | ||
| # For example, one of setup_* jobs failing and the dependent test jobs getting 'skipped'. | ||
| # Some jobs are optional and can have an empty matrix. In those cases we allow a 'skipped' | ||
| # result instead of treating it as a failure. | ||
| # Jobs may also be legitimately skipped when prepare_for_tests determines a category is not needed. | ||
| if: >- | ||
| ${{ always() && | ||
| (contains(needs.*.result, 'failure') || | ||
| contains(needs.*.result, 'cancelled') || | ||
| (needs.prepare_for_tests.outputs.all_skipped != 'true' && | ||
| ((fromJson(needs.setup_for_tests.outputs.tests_matrix_no_nugets).include[0] != null && | ||
| needs.tests_no_nugets.result == 'skipped') || | ||
| (fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_linux).include[0] != null && | ||
| needs.tests_requires_nugets_linux.result == 'skipped') || | ||
| (fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_windows).include[0] != null && | ||
| needs.tests_requires_nugets_windows.result == 'skipped') || | ||
| (fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_nugets_macos).include[0] != null && | ||
| needs.tests_requires_nugets_macos.result == 'skipped') || | ||
| (fromJson(needs.setup_for_tests.outputs.tests_matrix_requires_cli_archive).include[0] != null && | ||
| needs.tests_requires_cli_archive.result == 'skipped') || | ||
| ((needs.prepare_for_tests.outputs.run_all == 'true' || | ||
| needs.prepare_for_tests.outputs.run_extension == 'true') && | ||
| needs.extension_tests_win.result == 'skipped') || | ||
| ((needs.prepare_for_tests.outputs.run_all == 'true' || | ||
| needs.prepare_for_tests.outputs.run_polyglot == 'true') && | ||
| needs.polyglot_validation.result == 'skipped')))) }} | ||
| run: | | ||
| echo "One or more test jobs failed, were cancelled, or were unexpectedly skipped." | ||
| echo "" | ||
| echo "Templates skip expected: ${{ needs.detect_scope.outputs.run_all != 'true' && needs.detect_scope.outputs.run_templates != 'true' }}" | ||
| echo "Templates results: lin=${{ needs.templates_test_lin.result }} macos=${{ needs.templates_test_macos.result }} win=${{ needs.templates_test_win.result }}" | ||
| exit 1 | ||