The app maps health checks at /health (ServiceDefaults), not /api/v1/health.
Compose healthcheck and deploy-qa.sh's wait-loop both hit the wrong path.
Also add an nginx location for /health since it lives outside the /api
prefix that the admin proxy otherwise forwards unchanged.
aspnet base image ships neither curl nor wget, so the compose
healthcheck's wget call failed silently at the exec level (visible only
in docker's health-check log, not app stdout). Install curl in the
Dockerfile.ci final stage and switch the healthcheck to use it.
Self-hosted qa runner has no node in PATH, so the Node-based
actions/checkout@v4 action can't run there. Swap it for a bash git
fetch/checkout, matching the pipeline's no-marketplace-action convention.
Dockerfile.ci COPYs full project directories after restoring inside
the container. Without a .dockerignore, the host's obj/bin (built
with a different local SDK than the container's) got copied over the
container's fresh restore output, corrupting project.assets.json and
crashing ResolvePackageAssets with a NullReferenceException on publish.
Aspire.Hosting.PostgreSQL/JavaScript pull in MessagePack 2.5.192
transitively, which has multiple known vulnerabilities and fails the
build with TreatWarningsAsErrors. Pinned a direct reference to the
patched 2.5.302 (same major, no API break).
Microsoft.AspNetCore.OpenApi 10.0.5 pulls in Microsoft.OpenApi 2.0.0
transitively, which has a known high-severity vulnerability
(GHSA-v5pm-xwqc-g5wc) and fails the build with TreatWarningsAsErrors.
Pinned a direct reference to the patched 2.9.0 (still 2.x, API-compatible).
Gitea runner build failed with "dotnet: command not found". Added
ensure_dotnet() to lib.sh, using the vendored dotnet-install.sh to
bootstrap the SDK into .dotnet/ when not already on PATH, called from
build.sh/test.sh/prepush.sh. Also trigger CI on build-runner-fix to
verify the fix.