diff --git a/.devcontainer/aspire/devcontainer.json b/.devcontainer/aspire/devcontainer.json index 0fb570c..16251e6 100644 --- a/.devcontainer/aspire/devcontainer.json +++ b/.devcontainer/aspire/devcontainer.json @@ -1,9 +1,10 @@ { "name": ".NET Aspire", - // Base .NET 9 image. Alternatively a Dockerfile/compose could be used. - "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm", + // Current stable .NET SDK is installed by the versioned feature below. + "image": "mcr.microsoft.com/devcontainers/base:bookworm", "features": { - "ghcr.io/devcontainers/features/docker-in-docker:3": {}, + "ghcr.io/devcontainers/features/dotnet:2": { "version": "10.0.401" }, + "ghcr.io/devcontainers/features/docker-in-docker:4": {}, "ghcr.io/devcontainers/features/powershell:2": {} }, diff --git a/.devcontainer/aspire/runtime-smoke.sh b/.devcontainer/aspire/runtime-smoke.sh new file mode 100644 index 0000000..f555c03 --- /dev/null +++ b/.devcontainer/aspire/runtime-smoke.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail +test "$(id -u)" -ne 0 +docker version +docker run --rm hello-world +dotnet --info +export PATH="$HOME/.aspire/bin:$PATH" +aspire --version +dotnet build src/aspire/DevContainers.Aspire.AppHost/DevContainers.Aspire.AppHost.csproj --configuration Release +ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/aspire/DevContainers.Aspire.ApiService/DevContainers.Aspire.ApiService.csproj --no-build --configuration Release --urls http://127.0.0.1:18088 > /tmp/sample-api.log 2>&1 & +api_pid=$! +trap 'kill "$api_pid" 2>/dev/null || true' EXIT +for attempt in $(seq 1 30); do + if curl --fail --silent http://127.0.0.1:18088/weatherforecast > /tmp/weather.json; then break; fi + sleep 2 +done +curl --fail --silent http://127.0.0.1:18088/weatherforecast diff --git a/.github/workflows/devcontainer-validation.yml b/.github/workflows/devcontainer-validation.yml new file mode 100644 index 0000000..46e661b --- /dev/null +++ b/.github/workflows/devcontainer-validation.yml @@ -0,0 +1,26 @@ +name: Devcontainer validation +on: + push: + branches: [main] + paths: ['.devcontainer/**', 'src/aspire/**', 'global.json', '.github/workflows/devcontainer-validation.yml'] + pull_request: + branches: [main] +permissions: + contents: read +jobs: + devcontainer: + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + npm_config_ignore_scripts: 'true' + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - uses: actions/setup-node@v7 + with: + node-version: '26.10.0' + - name: Build and start the devcontainer on this disposable runner + run: npx --yes @devcontainers/cli@0.89.0 up --workspace-folder . --config .devcontainer/aspire/devcontainer.json + - name: Validate non-root Docker and the sample environment + run: npx --yes @devcontainers/cli@0.89.0 exec --workspace-folder . --config .devcontainer/aspire/devcontainer.json bash .devcontainer/aspire/runtime-smoke.sh diff --git a/docs/runtime-upgrade.md b/docs/runtime-upgrade.md new file mode 100644 index 0000000..c6d285b --- /dev/null +++ b/docs/runtime-upgrade.md @@ -0,0 +1,5 @@ +# Runtime upgrade validation + +The devcontainer is built and started on a disposable GitHub-hosted Linux runner. The job uses no cloud secrets, persists no checkout credentials, and never accesses a personal or Gateway Docker socket. The Docker-in-Docker feature owns its nested daemon. + +The Aspire sample now targets .NET 10 with SDK 10.0.401 and current stable Aspire/OpenTelemetry dependencies. CI checks the installed SDK and Aspire CLI, compiles the AppHost and its referenced projects, and starts the API sample for an HTTP smoke test. diff --git a/global.json b/global.json new file mode 100644 index 0000000..e1c5e99 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "10.0.401", + "rollForward": "latestPatch", + "allowPrerelease": false + } +} diff --git a/src/aspire/DevContainers.Aspire.ApiService/DevContainers.Aspire.ApiService.csproj b/src/aspire/DevContainers.Aspire.ApiService/DevContainers.Aspire.ApiService.csproj index fc9a0bf..b5eba5d 100644 --- a/src/aspire/DevContainers.Aspire.ApiService/DevContainers.Aspire.ApiService.csproj +++ b/src/aspire/DevContainers.Aspire.ApiService/DevContainers.Aspire.ApiService.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/src/aspire/DevContainers.Aspire.AppHost/DevContainers.Aspire.AppHost.csproj b/src/aspire/DevContainers.Aspire.AppHost/DevContainers.Aspire.AppHost.csproj index d40e9c0..3095c52 100644 --- a/src/aspire/DevContainers.Aspire.AppHost/DevContainers.Aspire.AppHost.csproj +++ b/src/aspire/DevContainers.Aspire.AppHost/DevContainers.Aspire.AppHost.csproj @@ -1,10 +1,10 @@  - + Exe - net9.0 + net10.0 enable enable @@ -15,7 +15,7 @@ - + diff --git a/src/aspire/DevContainers.Aspire.ServiceDefaults/DevContainers.Aspire.ServiceDefaults.csproj b/src/aspire/DevContainers.Aspire.ServiceDefaults/DevContainers.Aspire.ServiceDefaults.csproj index d92db39..e894981 100644 --- a/src/aspire/DevContainers.Aspire.ServiceDefaults/DevContainers.Aspire.ServiceDefaults.csproj +++ b/src/aspire/DevContainers.Aspire.ServiceDefaults/DevContainers.Aspire.ServiceDefaults.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable true @@ -10,13 +10,13 @@ - - - - - - - + + + + + + + diff --git a/src/aspire/DevContainers.Aspire.Web/DevContainers.Aspire.Web.csproj b/src/aspire/DevContainers.Aspire.Web/DevContainers.Aspire.Web.csproj index fc9a0bf..b5eba5d 100644 --- a/src/aspire/DevContainers.Aspire.Web/DevContainers.Aspire.Web.csproj +++ b/src/aspire/DevContainers.Aspire.Web/DevContainers.Aspire.Web.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable