Skip to content

Commit 3590059

Browse files
committed
Update RFC-0050
1 parent e452220 commit 3590059

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

RFC-0050-Cross-Repository-CI-Relay-for-PyTorch-Out-of-Tree-Backends.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,193 @@ L4:
210210
- org5/repo5: @oncall1,oncall2
211211
```
212212
213+
### Detailed Design
214+
215+
The level table above defines policy. This section makes the intended `L1` through `L4` runtime behavior explicit, along with the related Check Run re-run flow, so that future `L1` through `L4` work can follow a single design reference.
216+
217+
#### L1: Event Forwarding Only
218+
219+
```mermaid
220+
%%{init: {"theme": "base"}}%%
221+
sequenceDiagram
222+
participant U as UpStream Repo
223+
participant W as webhook_handler
224+
participant R as Redis
225+
participant S as result_handler
226+
participant D as DownStream Repo
227+
228+
U->>W: PR/Push event trigger
229+
W->>R: Get Allowlist
230+
W->>D: Passthrough Payload
231+
```
232+
233+
`L1` is the most basic event forwarding layer. Its core goal is to allow the upstream PyTorch repository to safely forward PR and push events to onboarded downstream repositories, without writing any status back to the upstream side.
234+
235+
The flow in the diagram is straightforward:
236+
237+
1. An upstream PR event (`opened`/`reopened`/`synchronize`/`closed`) or push event triggers `webhook_handler` through the GitHub App.
238+
2. `webhook_handler` reads the `Allowlist` from a remote source and stores it in `Redis` to reduce follow-up calls, determining which downstream repositories should receive the event.
239+
3. The `payload` is then passed through directly to the downstream repositories.
240+
241+
At `L1`, no HUD record is created and no upstream Check Run is created or updated.
242+
243+
#### L2: HUD Reporting
244+
245+
```mermaid
246+
%%{init: {"theme": "base"}}%%
247+
sequenceDiagram
248+
participant U as UpStream Repo
249+
participant W as webhook_handler
250+
participant R as Redis
251+
participant S as result_handler
252+
participant D as DownStream Repo
253+
participant H as HUD
254+
255+
U->>W: PR/Push event trigger
256+
W->>R: Get Allowlist
257+
W->>D: Passthrough Payload
258+
259+
rect rgb(240, 240, 240)
260+
Note over S, D: Creating In Progress in HUD
261+
D->>S: In progress call
262+
S->>R: Get Allowlist
263+
S->>H: Show in progress on HUD
264+
end
265+
rect rgb(240, 240, 240)
266+
Note over S, D: Updating Status in HUD
267+
D->>S: Completed workflow run call
268+
S->>R: Get Allowlist
269+
S->>H: Show completed on HUD
270+
end
271+
```
272+
273+
`L2` adds the ability to report results back to HUD on top of `L1`. The first half of the diagram is the same as `L1`: the upstream event enters `webhook_handler`, the `Allowlist` is read, and the downstream repository is triggered. The new behavior is the callback path from the downstream workflow back into the Relay Server:
274+
275+
- When the downstream workflow run starts running, it sends an `in_progress` callback to `result_handler`.
276+
1. `DownStream Repo` actively sends a callback request to `result_handler` from the first job in the workflow.
277+
2. After authenticating the request, `result_handler` reads the `Allowlist` to verify whether the request from this `DownStream Repo` belongs to `L2` or above.
278+
3. If the request is valid, the run information triggered by the workflow is written to HUD and marked as `in_progress`.
279+
- When the workflow run finishes, it sends a `completed` callback.
280+
1. `DownStream Repo` actively sends a callback request to `result_handler` from the last job in the workflow.
281+
2. After authenticating the request, `result_handler` reads the `Allowlist` to verify whether the request from this `DownStream Repo` belongs to `L2` or above.
282+
3. If the request is valid, the run information triggered by the workflow is written to HUD and marked as `completed`.
283+
284+
At `L2`, results are visible on HUD, but they still do not appear as upstream PR Check Runs.
285+
286+
#### L3: Label-Gated PR Checks
287+
288+
```mermaid
289+
%%{init: {"theme": "base"}}%%
290+
sequenceDiagram
291+
participant U as UpStream Repo
292+
participant W as webhook_handler
293+
participant R as Redis
294+
participant RH as result_handler
295+
participant D as DownStream Repo
296+
participant H as HUD
297+
298+
U->>W: PR/Push event trigger
299+
W->>R: Get Allowlist
300+
W->>D: Passthrough payload
301+
302+
rect rgb(240, 240, 240)
303+
Note over R, D: Scenario 1: label add before workflow run create
304+
U->>W: PR label add
305+
W->>R: Cache PR label info
306+
end
307+
308+
D->>RH: In progress workflow run call
309+
RH->>R: Get Allowlist<br>Cache workflow run info
310+
RH->>H: Show in progress workflow run on HUD
311+
312+
rect rgb(240, 240, 240)
313+
Note over R, D: Scenario 1
314+
RH->>R: Find PR label info record
315+
RH->>U: Create PR in_progress check run
316+
end
317+
318+
rect rgb(240, 240, 240)
319+
Note over R, D: Scenario 2: label add during workflow run execute
320+
U->>W: PR label add
321+
W->>R: Find workflow run info
322+
W->>U: Create PR in_progress check run
323+
end
324+
325+
D->>RH: Completed workflow run call
326+
RH->>R: Get Allowlist<br>Update workflow run info
327+
RH->>H: Show completed workflow run on HUD
328+
329+
rect rgb(240, 240, 240)
330+
Note over R, D: Scenario 1 & 2
331+
RH->>U: Update PR completed check run
332+
end
333+
334+
rect rgb(240, 240, 240)
335+
Note over R, D: Scenario 3: label add after run complete
336+
U->>W: PR label add
337+
W->>R: Find workflow run info
338+
W->>U: Create PR completed check run
339+
end
340+
```
341+
342+
`L3` keeps the HUD display capability from `L2` and further introduces on-demand upstream PR Check Runs. Consistent with the `label_only` design in this RFC, this layer does not attach downstream results to every PR by default. Instead, the status of the corresponding backend is shown as a non-blocking upstream check only after a label is explicitly added to the PR. The key of `L3` is whether the label event or the downstream workflow run status arrives first. Because of that, both sides of the information need to be temporarily stored in Redis, and the Check Run is created or updated when the timing is right.
343+
344+
`L3` has the following three scenarios:
345+
346+
- Scenario 1 means the label arrives before the workflow run.
347+
1. `webhook_handler` first caches the label information in `Redis`.
348+
2. The downstream workflow run starts and calls back to `result_handler`. After finding the matching label record in the cache, `result_handler` immediately creates an `in_progress` Check Run on the upstream PR.
349+
3. After the workflow run completes and `DownStream Repo` sends the completed callback to `result_handler`, `result_handler` updates both the workflow run status in `Redis` and the Check Run status on the PR.
350+
- Scenario 2 means the workflow run is already executing and the label arrives later.
351+
1. When `result_handler` receives the `in_progress` callback from `DownStream Repo`, it first caches the workflow run information.
352+
2. After the user adds a label to the PR, `webhook_handler` looks up that workflow run record in reverse and backfills an `in_progress` Check Run.
353+
3. After the workflow run completes and `DownStream Repo` sends the completed callback to `result_handler`, `result_handler` updates both the workflow run status in `Redis` and the Check Run status on the PR.
354+
- Scenario 3 is the later case where the downstream workflow run has already completed before the user adds the label.
355+
1. In this case, `webhook_handler` directly creates a `completed` Check Run based on the workflow run result already stored in `Redis`, without re-triggering execution.
356+
2. If the record for that workflow run has already been removed from `Redis`, the Check Run will not be created.
357+
358+
> [!NOTE]
359+
> The Redis cache TTL is tentatively set to `3 days` to align with the workflow integration requirements, so Redis data will not grow indefinitely.
360+
361+
#### L4: Always-On PR Checks
362+
363+
`L4` uses the same callback and synchronization behavior as `L3`, but it does not wait for a label. The `L4` scenario is effectively the same as `L3` Scenario 1 except that the downstream result is represented in upstream PR Checks by default, without requiring explicit labeling.
364+
365+
Since `L4` may also be merge-blocking, it should remain reserved for a small set of backends with sufficiently reliable infrastructure and clear ownership.
366+
367+
#### Check Run Re-Run Flow
368+
369+
```mermaid
370+
%%{init: {"theme": "base"}}%%
371+
sequenceDiagram
372+
participant U as UpStream Repo
373+
participant W as webhook_handler
374+
participant R as Redis
375+
participant RH as result_handler
376+
participant D as DownStream Repo
377+
participant H as HUD
378+
379+
U->>W: Re-run workflow run trigger
380+
W->>R: Get Allowlist
381+
W->>D: Re-run dispatch
382+
D->>RH: In progress workflow run call
383+
RH->>R: Get Allowlist
384+
RH->>U: Update in progress check run
385+
RH->>H: Update in progress workflow run in HUD
386+
D->>RH: Completed workflow run call
387+
RH->>R: Get Allowlist
388+
RH->>U: Update completed check run
389+
RH->>H: Update completed workflow run on HUD
390+
```
391+
392+
This diagram focuses on the re-run scenario:
393+
394+
1. After the upstream side triggers a workflow run re-run request from a Check Run, `webhook_handler` first reads the `Allowlist` and then dispatches the re-run request to the downstream side.
395+
2. After the downstream side re-runs the workflow run, it uses `result_handler` to synchronize the `in_progress` and `completed` states back to the upstream Check Run and HUD, which is almost the same as `L2` and `L3`.
396+
397+
> [!NOTE]
398+
> When a Check Run is created, the workflow run's `run_id` is stored in the payload's `external_id`. When a re-run is triggered, the corresponding workflow run can be found by looking up the `external_id` in the Check Run payload.
399+
213400
### Evolution Path
214401

215402
The allowlist is designed to naturally support gradual progression from experimental participation to mature participation, downstream repos that meet the requirements can apply to advance level by level (L1 → L2 → L3 → L4). The table below lists the requirements for advancing to each level.

0 commit comments

Comments
 (0)