docs/source/accelerator/ci.md
Out-of-tree (OOT) accelerator backends need to maintain compatibility with PyTorch's evolving codebase. As PyTorch continues to develop rapidly, changes in the upstream repository can potentially break downstream accelerator integrations. To address this challenge, PyTorch provides a Cross-Repository CI Relay (CRCR) mechanism that enables automatic CI coordination between the PyTorch repository and downstream accelerator repositories.
This chapter guides third-party accelerator vendors through the process of integrating their repositories with PyTorch's CI ecosystem, ensuring continuous compatibility validation.
Integrating with PyTorch's CI ecosystem provides several key benefits:
The CRCR system consists of four components: a GitHub App that bridges authentication and events, the PyTorch repository as the upstream event source, a Relay Server that dispatches events to eligible downstream repos, and downstream repositories that receive events and optionally report results back.
When a PR is opened or updated in PyTorch, GitHub notifies the Relay Server via the GitHub App. The Relay Server verifies the event, reads the allowlist, and dispatches a repository_dispatch event to each registered downstream repository. Downstream repos can optionally report CI results back to the Relay Server, which surfaces them in the PyTorch HUD or as PR check runs.
flowchart TD
PyTorch["PyTorch
(PR Event)"] -->|webhook| RS["Relay Server
(Allowlist/Dispatch/Callback)"]
GH["GitHub APP
(Auth&Bridge)"] <--> RS
RS <--> HUD["HUD
(Dashboard)"]
RS -->|repo_dispatch| DA[Downstream A]
RS -->|repo_dispatch| DB[Downstream B]
RS -->|repo_dispatch| DC[Downstream C]
DA -->|callback| RS
DB -->|callback| RS
DC -->|callback| RS
Participation is governed by a four-tier allowlist:
Downstream repos advance through levels by meeting documented requirements around hardware verification, CI reliability, and success rates.
For a deeper dive into the architecture and design decisions, see the RFC-0050: Cross-Repository CI Relay for PyTorch Out-of-Tree Backends.
The CRCR currently supports **L1 (Silent)** integration only.
Install the PyTorch Cross-Repo CI Relay GitHub App on your repository by clicking the Configure button and selecting your repository.
Submit a pull request to pytorch/pytorch adding your repository to .github/allowlist.yml under the L1 key:
.. code-block:: yaml
L1:
- your-org/your-accelerator
See #180352 for a reference example. The PyTorch team will review and merge the PR to complete the onboarding.
Create a GitHub Actions workflow in your repository to receive repository_dispatch events:
.. code-block:: yaml
:caption: .github/workflows/pytorch_ci.yml
name: PyTorch CI
run-name: >-
PyTorch CI -
${{
github.event.client_payload.event_type == 'pull_request' &&
format('PR #{0} ({1})',
github.event.client_payload.payload.pull_request.number,
github.event.client_payload.payload.action) ||
format('Push {0}', github.event.client_payload.payload.after)
}}
on:
repository_dispatch:
types: [pull_request, push]
concurrency:
group: >-
pytorch-ci-${{ github.event.client_payload.payload.repository.full_name }}-${{
github.event.client_payload.payload.pull_request.number || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
jobs:
cancel-workflow:
if: ${{ github.event.client_payload.payload.action == 'closed' }}
runs-on: ubuntu-latest
steps:
- run: echo "PR closed, canceling in-progress runs"
ci:
if: ${{ github.event.client_payload.payload.action != 'closed' }}
runs-on: ubuntu-latest
steps:
- name: Checkout downstream repo
uses: actions/checkout@v4
- name: Checkout PyTorch at triggered commit
uses: actions/checkout@v4
with:
repository: pytorch/pytorch
ref: >-
${{ github.event.client_payload.event_type == 'pull_request' &&
github.event.client_payload.payload.pull_request.head.sha ||
github.event.client_payload.payload.after }}
path: pytorch
- name: Build and test
run: |
# Your build and test commands
echo "Running tests against PyTorch..."
Verify your integration works correctly:
The CRCR relay is a stateless pass-through: it forwards the complete GitHub webhook payload as client_payload in the repository_dispatch event. There is no simplified intermediary schema.
The client_payload has two top-level fields:
event_type: either pull_request or pushpayload: the raw GitHub webhook payload for that event typeCommonly used fields:
.. code-block:: yaml
github.event.client_payload.event_type # "pull_request" or "push"
github.event.client_payload.payload.action # "opened", "synchronize", "reopened" or "closed" only
github.event.client_payload.payload.pull_request.number # PR number (pull_request events only)
github.event.client_payload.payload.pull_request.head.sha # Head commit SHA to checkout
github.event.client_payload.payload.after # Commit SHA (push events only)
Supported action values for pull_request events:
| Action | Description |
|---|---|
opened | New PR created |
synchronized | New commits pushed to an existing PR |
reopened | Previously closed PR reopened |
closed | PR closed or merged; triggers the cancel-workflow job to stop in-progress runs |
repository_dispatch event type in your workflow matches what the relay sends