diff --git a/.github/workflows/nightly-xr-ai-test.yml b/.github/workflows/nightly-xr-ai-test.yml index d69ea2996..41f7d4800 100644 --- a/.github/workflows/nightly-xr-ai-test.yml +++ b/.github/workflows/nightly-xr-ai-test.yml @@ -8,9 +8,11 @@ name: nightly XR AI test # the default `tests` workflow (ubuntu-latest). Mirrors the local # `tests/run_local_gpu_tests.sh` entry point. # -# Setup note: the GPU runner's Docker needs the NVIDIA runtime registered -# (`sudo nvidia-ctk runtime configure --runtime=docker`); without it the -# vLLM tests fail at container launch. +# Setup notes: +# - The GPU runner's Docker needs the NVIDIA runtime registered +# (`sudo nvidia-ctk runtime configure --runtime=docker`). +# - The repository needs an Actions secret named `NGC_API_KEY`, backed by an +# NGC Personal or Service Key with NGC Catalog access. on: schedule: @@ -44,6 +46,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Configure isolated Docker credentials + run: | + set -euo pipefail + docker_config="$RUNNER_TEMP/xr-ai-docker-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + install -d -m 0700 "$docker_config" + echo "DOCKER_CONFIG=$docker_config" >> "$GITHUB_ENV" + - name: Discover CUDA toolkit # Prefer CUDA 13.0 (current target), but fall back through the # usual symlinks and finally whatever `nvcc` is on PATH so we @@ -86,6 +95,25 @@ jobs: nvcc --version nvcc --list-gpu-arch | grep compute_89 + - name: Authenticate to NGC + if: >- + github.event_name != 'pull_request' + || github.event.pull_request.head.repo.full_name == github.repository + env: + NGC_API_KEY: ${{ secrets.NGC_API_KEY }} + run: | + set -euo pipefail + if [[ -z "${NGC_API_KEY:-}" ]]; then + echo "::error::NGC_API_KEY repository secret is required for nvcr.io images" + exit 1 + fi + printf '%s' "$NGC_API_KEY" | docker login nvcr.io \ + --username '$oauthtoken' --password-stdin + if ! docker manifest inspect nvcr.io/nvidia/vllm:26.04-py3 >/dev/null; then + echo "::error::NGC_API_KEY must grant NGC Catalog access to nvidia/vllm" + exit 1 + fi + - name: Install uv uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3 with: @@ -169,6 +197,15 @@ jobs: echo "No xr-ai-vllm-* containers to remove." fi + - name: Remove NGC credentials + if: always() + run: | + set -u + if [[ -n "${DOCKER_CONFIG:-}" ]]; then + rm -rf -- "$DOCKER_CONFIG" + fi + DOCKER_CONFIG="$HOME/.docker" docker logout nvcr.io || true + notify: name: alert on failure needs: [pytest] diff --git a/docs/changelog.md b/docs/changelog.md index 9cabc2e36..4cb434d9a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,6 +18,17 @@ allowing a valid command to survive noisy STT preambles without sending background speech to the agent. Commas, semicolons, URLs, and ordinary mid-sentence mentions remain non-matches to limit false wakes. +### 2026-08-12 — Nightly GPU CI authenticates to NGC explicitly + +The nightly GPU workflow logs in to `nvcr.io` with the repository's +`NGC_API_KEY` before setup and tests begin, then verifies access to the vLLM +image manifest. A job-scoped, per-run `DOCKER_CONFIG` is inherited by model +subprocesses without exposing the key to pytest; fork pull requests run without +the secret. CI authenticates directly because `_maybe_ngc_login()` checks the +default Docker config rather than this isolated path. Always-run cleanup deletes +the isolated config and removes credentials leaked to the runner-global config +by earlier workflow revisions. + ### 2026-08-12 — NeMo Agent Toolkit compatibility is retired All surviving capabilities now use native `xr-ai-tools` contracts. OpenXR, diff --git a/docs/credentials.md b/docs/credentials.md index ce5c88444..1c473722a 100644 --- a/docs/credentials.md +++ b/docs/credentials.md @@ -71,6 +71,12 @@ set it ahead of time: export NGC_API_KEY=nvapi-xxx ``` +Nightly GPU CI reads the same value from a required repository Actions secret +named `NGC_API_KEY`. Use an NGC Personal or Service Key authorized for **NGC +Catalog**; an endpoint-only NVIDIA API key cannot pull `nvcr.io` images. +Scheduled, manual, and same-repository pull-request runs use the key only in the +NGC authentication step; fork pull requests do not receive the secret. + ## How a token is resolved `load_credentials()` (always) and `ensure_credentials()` (NGC only) resolve in diff --git a/docs/source/getting_started/credentials.md b/docs/source/getting_started/credentials.md index e720250c2..4d94423f8 100644 --- a/docs/source/getting_started/credentials.md +++ b/docs/source/getting_started/credentials.md @@ -72,6 +72,12 @@ set it ahead of time: export NGC_API_KEY=nvapi-xxx ``` +Nightly GPU CI reads the same value from a required repository Actions secret +named `NGC_API_KEY`. Use an NGC Personal or Service Key authorized for **NGC +Catalog**; an endpoint-only NVIDIA API key cannot pull `nvcr.io` images. +Scheduled, manual, and same-repository pull-request runs use the key only in the +NGC authentication step; fork pull requests do not receive the secret. + ## How a token is resolved `load_credentials()` (always) and `ensure_credentials()` (NGC only) resolve in