Skip to content

[WoA] Add manual cross-repository broker - #3025

Merged
isVoid merged 8 commits into
mainfrom
codex/woa-xrepo-public-manual-broker
Oct 14, 2026
Merged

isVoid merged 8 commits into
mainfrom
codex/woa-xrepo-public-manual-broker

Conversation

@isVoid

@isVoid isVoid commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds two manually triggered workflows for the initial cross-repository WoA CI pilot. This PR enables no automatic validation on pushes, schedules, or pull requests.

Paired private implementation: https://github.com/NVIDIA-dev/cuda-python-private/pull/650. Tracks https://github.com/NVIDIA-dev/cuda-python-private/issues/584.

Transport check

woa-transport-check.yml (WoA transport check) takes no inputs. It resolves the current public main SHA, verifies its ancestry, and dispatches ctk-next-woa-transport-check.yml on private ctk-next. The private workflow independently verifies the SHA and creates cuda-python WoA integration / transport smoke on that public commit, transitioning from in_progress to completed: neutral.

The resolved SHA stays fixed if main advances. This checks the App credential exchange and public reporting without downloading wheels or allocating GB10. It does not target a draft PR or an unmerged PR head.

Manual wheel-validation dispatch

woa-validation-dispatch.yml (WoA validation dispatch) accepts an optional public_run_id:

  • Supply an ID to select a specific successful public main CI run.
  • Leave it empty to use the existing ci/tools/lookup-run-id --branch main --head-sha helper.

The public resolver checks the repository name, CI workflow identity/path, push event, main branch, successful completion, SHA, and ancestry before dispatching the exact run ID and SHA privately. Repository numeric IDs, producer-job IDs, run attempts, and artifact manifests are not passed.

Private admission discovers the three expected artifacts within that run, validates their metadata and archive digests, stages the wheels, runs a Python 3.13 install/import smoke on GB10, and reports the result through cuda-python WoA integration on the selected public SHA. The public broker completes once dispatch is verified; its own success does not mean GB10 testing has finished. The separate App Check Run carries that result.

The private-dispatch App PEM remains a repository secret under the agreed trusted-writer model. Its token is scoped to private Actions: write; GitHub grants that permission across private Actions, rather than restricting it to these two workflows. Only isolated dispatch jobs mint/use this token; those jobs perform no checkout or artifact processing.

Rollout

  1. Merge private [FEA]: Add support for user-opt-in logging in path finder #650 into ctk-next, then merge this PR into public main.
  2. Manually run WoA transport check from main, with no inputs. Inspect the current target commit's checks for cuda-python WoA integration / transport smoke completing as neutral. No GB10 job should start.
  3. Manually run WoA validation dispatch from main with a recent successful push-triggered public CI run ID whose WoA artifacts are still available. Inspect the canonical public Check Run and the private GB10 workflow. Its smoke installs/imports three wheels; it is not the full GPU test suite.
  4. Confirm an invalid run is rejected before GB10 allocation. Keep the checks informational during the pilot.

Pilot limits and follow-up

  • Automatic lookup currently selects the latest successful main CI run regardless of event. A scheduled/manual candidate is then rejected by the push assertion without trying an older push run. Supplying an eligible run ID is the current workaround; an event filter for lookup-run-id is deferred to [WoA] Automate public cross-repository dispatch #3026.
  • Validation currently requires the whole public CI run to succeed. Earlier dispatch after wheel builds, automatic selection/batching, and expanded test coverage belong to the follow-up PRs ([WoA] Automate public cross-repository dispatch #3026 and private cusolver native routines from cuda-python #651).
  • The private reporter handles ordinary staging/test failures and job cancellation once a check ID exists. Full-workflow cancellation or infrastructure loss can still leave a check unfinished; durable recovery is deferred.

Validation

  • Workflow linting, Bash syntax, and diff checks pass.
  • Local simulation executes the public resolver/dispatch and private admission, ZIP download/hash/extraction, staging, and reporting with mocked APIs. Success, failure, cancellation, and invalid artifact cases pass.
  • The transport roundtrip simulation creates and completes the check on the same resolved main SHA.
  • Live read-only checks verified run 38473329258 and its three expected artifacts. The current PR workflow files match the simulated versions.
  • Execute the real App credential exchange and transport check after merge.
  • Execute the real GB10 install/import smoke after merge.

@copy-pr-bot

copy-pr-bot Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the CI/CD CI/CD infrastructure label Oct 5, 2026
@isVoid
isVoid marked this pull request as ready for review October 6, 2026 18:25
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Summary

Summary by CodeRabbit

  • Chores
    • Added manually triggered workflows for transport smoke checks and Windows Arm64 validation.
    • Transport checks verify the public main commit and confirm it is ahead of or identical to the comparison target before dispatching a check.
    • Validation can use a specified public run or locate the latest successful run on main. It verifies the run, a successful Windows Arm64 producer, and three required, unexpired artifacts.
    • Both workflows verify the dispatched run’s repository, workflow, event, and branch, and stop if checks fail.

Adds two manually triggered workflows. One validates the public main commit before dispatching a private transport-smoke workflow. The other validates a public CI run and its Windows Arm64 artifacts before dispatching private validation. Both verify the returned private workflow run.

Changes: WoA transport check

Layer / File(s) Summary
Resolve and validate public main
.github/workflows/woa-transport-check.yml
The workflow validates the public main SHA and its commit ancestry. It exports the SHA and a correlation ID.
Dispatch and verify transport smoke
.github/workflows/woa-transport-check.yml
The workflow creates a scoped GitHub App token, dispatches the private workflow on ctk-next, and verifies the returned run’s repository, workflow, event, and branch.

Private WoA validation

Layer / File(s) Summary
Validate public run and artifacts
.github/workflows/woa-validation-dispatch.yml
The workflow checks the public CI run, commit position, producer job, and three expected unexpired artifacts. It exports the resolved run and artifact data.
Dispatch and verify private validation
.github/workflows/woa-validation-dispatch.yml
The workflow creates a scoped GitHub App token, dispatches private validation on ctk-next with the resolved data, and verifies the returned run.

Suggested reviewers: leofang

Priority: ⬇️ Low

Change: Feature

Merge Risk: 🟡 Moderate · up to 0bdbf

Any branch dispatch of the manual brokers can mint an Actions-write token for the private repository. The empty run-ID path can also fail even when a qualifying main run exists, and the private-run path check may reject valid runs. Resolve these before relying on the brokers.

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/woa-private-dispatch.yml (1)

67-83: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

suggestion: Derive the CUDA build version from ci/versions.yml at public_sha. Do not hard-code 13.4.2.

Two values are fixed to 13.4.2:

  • the producer job name Build win-arm64, CUDA 13.4.2 / py3.13;
  • the artifact name cuda-bindings-python313-cuda13.4.2-win-arm64-<sha>.

In .github/workflows/ci.yml, both values come from .cuda.build.version (Lines 224-242 and 444-467). After the next CUDA version bump, this broker will reject every valid public run until someone edits this file. The failure is safe, but the broker becomes unusable.

Fix: read ci/versions.yml at public_sha with gh api repos/NVIDIA/cuda-python/contents/ci/versions.yml?ref=$public_sha. Then build the job name and the artifact names from .cuda.build.version.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 3bdf7831-9285-4563-bf65-3d0b14907b12
📥 Commits

Reviewing files that changed from the base of the PR and between 669e608 and eb4adea.

📒 Files selected for processing (2)
  • .github/workflows/woa-crossrepo-smoke.yml
  • .github/workflows/woa-private-dispatch.yml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread .github/workflows/woa-validation-dispatch.yml
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@isVoid isVoid self-assigned this Oct 7, 2026
@isVoid isVoid added the feature New feature or request label Oct 7, 2026
@isVoid isVoid added this to the cuda.core next milestone Oct 7, 2026
@lijinf2

lijinf2 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

The PR needs manual trigger to run smoke test and dispatch-validate test, if I understand correctly. Are we able to test the manual trigger when the PR is open, or we need to merge the PR to allow manual trigger?

Comment thread .github/workflows/woa-validation-dispatch.yml
@lijinf2

lijinf2 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

The PR introduces a two-phase design: a lightweight smoke check between the public and private repos to cheaply validate cross-repo connectivity/config, followed by a dispatch-validate step that verifies a merged main build and triggers real GB10 run. This lets connectivity/config issues surface cheaply in the first phase, before the costlier validation phase.

LGTM. I just have a few questions.

@isVoid

isVoid commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Are we able to test the manual trigger when the PR is open, or we need to merge the PR to allow manual trigger?

There's a way, as pointed out here: https://github.com/NVIDIA-dev/cuda-python-private/pull/615#issuecomment-5797975839

But there's still a gap: push events require the inputs hard-coded in the workflow to trigger the test. And this PR would still require the private PR to be merged first before we can check the round trip.

@isVoid
isVoid requested a review from lijinf2 October 9, 2026 21:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: f257626e-4b8d-488c-bad5-26dc8c1e75d6
📥 Commits

Reviewing files that changed from the base of the PR and between eb4adea and 39414cc.

📒 Files selected for processing (2)
  • .github/workflows/woa-transport-check.yml
  • .github/workflows/woa-validation-dispatch.yml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread .github/workflows/woa-transport-check.yml
Comment thread .github/workflows/woa-validation-dispatch.yml

@lijinf2 lijinf2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

.path mismatched issue raised by coderabbit seems not blocking merge. We can confirm whether that is an actual issue after merge.

So we will have two new rows under Github Action. One is "woa-transport-check", and the other is "woa-validation-dispath". Does "woa-validation-dispath" changes status (i.e. green or red) before the private run finished or after?

@isVoid

isVoid commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Does "woa-validation-dispath" changes status (i.e. green or red) before the private run finished or after?

The check run will get updated depend on the stage of the private run. For example, after the dispatch is admitted, the private run will create a POST to update the check with "in progress" status. And once test finished, the report job will update the check with Completed status.

Comment thread .github/workflows/woa-transport-check.yml Outdated
Comment thread .github/workflows/woa-transport-check.yml Outdated
Comment thread .github/workflows/woa-transport-check.yml Outdated
Comment thread .github/workflows/woa-transport-check.yml Outdated
Comment on lines +8 to +14
on:
workflow_dispatch:
inputs:
public_run_id:
description: Successful public main CI run containing the exact WoA artifacts
required: true
type: string

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For convenience we can make this optional. We have a lookup-run-id script that can look up the latest run ID, see ci-nightly.yml:

workflow_dispatch:
inputs:
run-id:
description: >
Override the CI run ID to download artifacts from.
Leave empty to auto-detect the latest successful main run.
type: string
default: ''

Comment on lines +45 to +55
jq -e '
.repository.id == 381173759 and
.workflow_id == 155304118 and
.path == ".github/workflows/ci.yml" and
.event == "push" and
.head_branch == "main" and
.status == "completed" and
.conclusion == "success" and
(.head_sha | test("^[0-9a-f]{40}$"))
' <<< "$run" >/dev/null
public_sha=$(jq -r .head_sha <<< "$run")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, this can be retrieved by passing --head-sha to lookup-run-id

artifacts-json: ${{ steps.resolve.outputs.artifacts_json }}
correlation-id: ${{ steps.resolve.outputs.correlation_id }}
public-producer-job-id: ${{ steps.resolve.outputs.public_producer_job_id }}
public-run-attempt: ${{ steps.resolve.outputs.public_run_attempt }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have enough sophisticated artifact passing across pipelines, but so far I don't see any need for run_attempt (because multiple attempts share the same run ID). Is it really needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ditto for public_producer_job_id)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't - to download the artifact we can just use gh run download as suggested.

Comment on lines +78 to +110
expected_names=$(jq -n \
--arg sha "$public_sha" '[
"cuda-pathfinder-wheel",
("cuda-bindings-python313-cuda13.4.2-win-arm64-" + $sha),
("cuda-core-python313-win-arm64-" + $sha)
]')
artifacts_json='[]'
while IFS= read -r artifact_name; do
response=$(gh api --method GET \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/NVIDIA/cuda-python/actions/runs/$PUBLIC_RUN_ID/artifacts" \
-f name="$artifact_name" \
-F per_page=100)
artifact=$(jq -c -e \
--arg name "$artifact_name" '
if .total_count == 1 and
(.artifacts | length) == 1 and
.artifacts[0].name == $name and
.artifacts[0].expired == false
then .artifacts[0] | {id, name, digest}
else error("expected exactly one unexpired artifact named " + $name)
end
' <<< "$response")
artifacts_json=$(jq -c \
--argjson artifact "$artifact" \
'. + [$artifact] | sort_by(.name)' <<< "$artifacts_json")
done < <(jq -r '.[]' <<< "$expected_names")
jq -e '
length == 3 and
all(.[ ];
(.id | type == "number") and
(.digest | test("^sha256:[0-9a-f]{64}$")))
' <<< "$artifacts_json" >/dev/null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: I am a bit confused by this code. Is artifacts_json a hard requirement? I think providing just the repo name and the run ID is enough to retrieve artifacts, akin to gh run download ...? All we need on the private repo side is a GH token that has actions:read.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not. We only need public_run_id with gh run download to download the artifacts. gh run download also support filtering via name or glob flags.

@rwgk rwgk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this PR as-is, although adding some of the simplifications suggested by @leofang would seem nice.

@leofang

leofang commented Oct 14, 2026

Copy link
Copy Markdown
Member

@isVoid the comments above also apply to the private counterpart, so I don't plan to repeat what's stated here. Feel free to merge and create a tracking issue to follow up. I did not block the merge.

@leofang

leofang commented Oct 14, 2026

Copy link
Copy Markdown
Member

FYI, when reviewing the pair of PRs agents just gave a thumbs up without asking all the questions I asked above. Need to bang them particularly hard for them to see a path toward simplification.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 90ce3533-9e8a-4b8b-95c3-e62547f84c2a
📥 Commits

Reviewing files that changed from the base of the PR and between 9ed8032 and 0bdbf88.

📒 Files selected for processing: 1
  • .github/workflows/woa-validation-dispatch.yml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.

set -euo pipefail
public_sha=''
if [[ -z "$PUBLIC_RUN_ID" ]]; then
lookup_output=$(./ci/tools/lookup-run-id --branch main --head-sha NVIDIA/cuda-python CI)

@coderabbitai coderabbitai Bot Oct 14, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

important: Select a successful push run when the run ID is empty. lookup-run-id can select a successful scheduled or manually dispatched main CI run. The later .event == "push" check then rejects that run without trying an older push run. CI supports both event types, including a daily schedule. Filter candidates by push during lookup so the empty-input path can resolve a qualifying run. (raw.githubusercontent.com)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the follow up PR #3026, I will update lookup-run-id to include a push-event filter.

@isVoid
isVoid enabled auto-merge (squash) October 14, 2026 07:44
@isVoid
isVoid merged commit 1cd41ea into main Oct 14, 2026
109 checks passed
@isVoid
isVoid deleted the codex/woa-xrepo-public-manual-broker branch October 14, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD CI/CD infrastructure feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants