Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions .github/workflows/validate-published-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Validates an Aspire CLI build after it has been published to a public channel.
#
# This workflow is dispatched by the Azure DevOps release build after publishing
# and installer preparation complete. It intentionally runs every CLI E2E test
# class as a separate GitHub Actions job so the shape matches PR validation.
name: Validate Published Build

on:
workflow_dispatch:
inputs:
quality:
description: 'Install quality to validate (dev, staging, release)'
required: false
default: 'staging'
type: choice
options:
- dev
- staging
- release
version:
description: 'Exact Aspire CLI version to validate'
required: true
type: string

permissions:
contents: read

jobs:
setup_cli_e2e_tests:
name: Setup CLI E2E test matrix
runs-on: ubuntu-latest
outputs:
cli_e2e_matrix: ${{ steps.filter_cli_e2e.outputs.cli_e2e_matrix }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- uses: ./.github/actions/enumerate-tests
id: generate_tests_matrix
with:
buildArgs: '/p:IncludeCliE2ETests=true /p:SkipTests=false'

- name: Filter CLI E2E test matrix
id: filter_cli_e2e
shell: pwsh
env:
ALL_TESTS: ${{ steps.generate_tests_matrix.outputs.all_tests }}
run: |
$allTests = $env:ALL_TESTS | ConvertFrom-Json
$cliE2ETests = @($allTests.include | Where-Object {
$_.projectName -eq 'Aspire.Cli.EndToEnd.Tests' -and $_.type -eq 'class'
})

if ($cliE2ETests.Count -eq 0) {
Write-Error "No Aspire.Cli.EndToEnd.Tests class entries were found in the generated test matrix."
exit 1
}

$matrix = ConvertTo-Json @{ include = @($cliE2ETests) } -Compress -Depth 10
"cli_e2e_matrix=$matrix" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append

build_cli_e2e_image:
name: Build CLI E2E Docker image
uses: ./.github/workflows/build-cli-e2e-image.yml
needs: setup_cli_e2e_tests
with:
includePolyglotImages: true

validate-published-build:
name: ${{ matrix.shortname }} (${{ inputs.quality || 'staging' }})
needs: [setup_cli_e2e_tests, build_cli_e2e_image]
if: ${{ fromJson(needs.setup_cli_e2e_tests.outputs.cli_e2e_matrix).include[0] != null }}
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup_cli_e2e_tests.outputs.cli_e2e_matrix) }}

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup .NET
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
global-json-file: global.json

- name: Restore
run: ./restore.sh

- name: Verify Docker is running
run: docker info

- name: Download prebuilt CLI E2E Docker image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-e2e-dotnet-image
path: ${{ github.workspace }}/cli-e2e-image

- name: Download prebuilt CLI E2E polyglot Docker image
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-e2e-polyglot-image
path: ${{ github.workspace }}/cli-e2e-image

- name: Download prebuilt CLI E2E Java Docker image
if: ${{ contains(matrix.shortname, 'Java') }}
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-e2e-polyglot-java-image
path: ${{ github.workspace }}/cli-e2e-image

- name: Load prebuilt CLI E2E Docker images
shell: bash
run: |
set -euo pipefail
eng/scripts/load-cli-e2e-images.sh \
--image-dir "${{ github.workspace }}/cli-e2e-image" \
--require-dotnet true \
--require-polyglot true \
--require-java "${{ contains(matrix.shortname, 'Java') }}"

- name: Build E2E test project
run: dotnet build tests/Aspire.Cli.EndToEnd.Tests/Aspire.Cli.EndToEnd.Tests.csproj

- name: Run CLI E2E tests against published build
env:
ASPIRE_E2E_VERSION: ${{ inputs.version }}
ASPIRE_E2E_CLI_VERSION_OUTPUT_DIR: ${{ github.workspace }}/testresults/cli-versions
TEST_CLASS: ${{ matrix.classname }}
TRX_FILE_NAME: ${{ matrix.shortname }}.trx
run: |
dotnet test --project tests/Aspire.Cli.EndToEnd.Tests/Aspire.Cli.EndToEnd.Tests.csproj \
--no-build \
-- \
--ignore-exit-code 8 \
--report-trx \
--report-trx-filename "$TRX_FILE_NAME" \
--results-directory ${{ github.workspace }}/testresults \
--filter-class "$TEST_CLASS" \
--filter-not-trait "quarantined=true" \
--filter-not-trait "outerloop=true" \
--hangdump --hangdump-type none --hangdump-timeout 15m

- name: Upload logs and test results
id: upload-logs
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: validate-published-build-${{ inputs.quality || 'staging' }}-${{ matrix.shortname }}
path: |
testresults/**
**/TestResults/**/*.log
if-no-files-found: ignore

- name: Generate test results summary
if: always()
continue-on-error: true
env:
TEST_RESULTS_ARTIFACT_URL: ${{ steps.upload-logs.outputs.artifact-url }}
run: |
if [ -d "${{ github.workspace }}/testresults" ]; then
summary_args=(
run
--project
"${{ github.workspace }}/tools/GenerateTestSummary/GenerateTestSummary.csproj"
--
"${{ github.workspace }}/testresults"
)

artifact_url="${TEST_RESULTS_ARTIFACT_URL:-}"
if [ -n "$artifact_url" ]; then
summary_args+=("-u" "$artifact_url")
fi

dotnet "${summary_args[@]}"
fi

- name: Add Aspire CLI version summary
if: always()
continue-on-error: true
run: |
versions_dir="${{ github.workspace }}/testresults/cli-versions"

{
echo ""
echo "## Aspire CLI versions installed"
echo ""

if compgen -G "$versions_dir/*.env" > /dev/null; then
for version_file in "$versions_dir"/*.env; do
echo "- \`$(basename "$version_file" .env)\`"
sed 's/^/ - /' "$version_file"
done
else
echo "No Aspire CLI version records were produced."
fi
} >> "$GITHUB_STEP_SUMMARY"
Loading