From d3e54613daa67af176ddbd15da5d908b109b2df0 Mon Sep 17 00:00:00 2001 From: yueming-yuan Date: Wed, 26 Aug 2026 17:45:13 -0700 Subject: [PATCH] ci: default a file run to the PR's own image /rerun-test resolved its container as radixark/miles:dev whenever the PR body carried no ci-image-tag, so a file run on a PR that had built pr- ran against the released image instead. On a PR that moves a dependency the run then fails for a reason that has nothing to do with the test: rerunning one sglang-bump test this way died on 'sglang-kernel is installed with version 0.4.5, which is less than the minimum required version' before the test started, which reads as a test failure on the PR. A PR keeps one image tag for its whole life (see _build-pr-ci-image.yml), so prefer pr- when that tag is published and keep dev for a PR whose build never ran. An explicit ci-image-tag still wins. The inspect runs authenticated because an anonymous one can hit Docker Hub's rate limit, which would look like a missing tag and silently restore the old behaviour. --- .github/workflows/run-ci-file.yml | 35 ++++++++++++++++++++++++++++++- docs/ci/01-label.md | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-ci-file.yml b/.github/workflows/run-ci-file.yml index f044f97e625..6bf18a4bc6a 100644 --- a/.github/workflows/run-ci-file.yml +++ b/.github/workflows/run-ci-file.yml @@ -128,11 +128,44 @@ jobs: path: pr-source persist-credentials: false + # An anonymous inspect can fail on Docker Hub's pull rate limit, which the + # step below would read as "no pr- image" and quietly fall back to + # dev -- the very confusion it exists to remove. + - name: Login to Docker Hub + if: inputs.ci_image_tag == '' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # A PR that built an image keeps it as pr- for its whole life, so + # that is the image its own file runs should use; dev is for a PR whose + # build never ran. + - name: Pick the image tag when the PR body did not pin one + id: image + env: + CI_IMAGE_TAG: ${{ inputs.ci_image_tag }} + PULL_NUMBER: ${{ inputs.pull_number }} + run: | + set -euo pipefail + if [ -n "${CI_IMAGE_TAG}" ]; then + echo "tag=${CI_IMAGE_TAG}" >> "$GITHUB_OUTPUT" + echo "Using the pinned tag ${CI_IMAGE_TAG}." + exit 0 + fi + if docker buildx imagetools inspect "radixark/miles:pr-${PULL_NUMBER}" >/dev/null 2>&1; then + echo "tag=pr-${PULL_NUMBER}" >> "$GITHUB_OUTPUT" + echo "Using this PR's image pr-${PULL_NUMBER}." + else + echo "tag=dev" >> "$GITHUB_OUTPUT" + echo "No pr-${PULL_NUMBER} image is published; using dev." + fi + - name: Resolve the file's execution plan id: resolve env: TEST_FILE: ${{ inputs.test_file }} - CI_IMAGE_TAG: ${{ inputs.ci_image_tag }} + CI_IMAGE_TAG: ${{ steps.image.outputs.tag }} CI_SOURCE_ROOT: ${{ github.workspace }}/pr-source run: python3 -S -m tests.ci.file_run diff --git a/docs/ci/01-label.md b/docs/ci/01-label.md index 78175008f77..a01ffbb9899 100644 --- a/docs/ci/01-label.md +++ b/docs/ci/01-label.md @@ -76,7 +76,7 @@ The dispatched workflow and its reusable workflows come from the reviewed defaul The trust boundary ends after the resolver produces that fixed plan. The execution job intentionally installs and runs PR-controlled dependencies, configuration, imports, and test code; it is not a sandbox for hostile PR code. Same-repository and fork heads are accepted from any commenter the policy admits; a fork head's run receives no repository secrets, and the resolver derives fork-ness from the live pull request rather than a dispatch input. The command requires the fixed `run-ci-file.yml` workflow on the default branch. A later push does not change the already dispatched snapshot. -A file run honors the PR body's `ci-megatron-pr` and `ci-sglang-pr` pins; CUDA file runs also honor `ci-image-tag`, while CPU file runs use the hosted bare environment. The gateway validates and forwards these inputs, and a pin whose value fails validation rejects the command. Without a `ci-image-tag` pin a CUDA run uses the released `dev` image even when the PR built a `pr-` image, so docker-changing PRs should pin the tag explicitly. The run writes no perf baseline (regular cadence), and its result is informational: it does not appear among the PR's required checks. +A file run honors the PR body's `ci-megatron-pr` and `ci-sglang-pr` pins; CUDA file runs also honor `ci-image-tag`, while CPU file runs use the hosted bare environment. The gateway validates and forwards these inputs, and a pin whose value fails validation rejects the command. Without a `ci-image-tag` pin a CUDA run uses the PR's own `pr-` image when that tag is published, and the released `dev` image otherwise, so a pin is only needed to run against some other image. The run writes no perf baseline (regular cadence), and its result is informational: it does not appear among the PR's required checks. `/rerun-test` and `/rerun-failed-ci` work as soon as the gateway workflow is on the default branch, with no App and no repository variables. Their jobs use the workflow's own `GITHUB_TOKEN`: the command job has `actions: write` plus `pull-requests: read`; the reaction job has `issues: write` plus `pull-requests: write`; and the file run's status jobs have `issues: write` plus `pull-requests: write`, with `actions: read` added to the final status job so it can calculate elapsed time from the workflow run.