Skip to content

Commit e703b59

Browse files
authored
ci(e2e): add label dispatcher and contributor CI docs (#975)
1 parent de9dce0 commit e703b59

4 files changed

Lines changed: 360 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: E2E Label Dispatch
2+
3+
# When a maintainer applies `test:e2e` or `test:e2e-gpu`, dispatch the matching
4+
# self-hosted workflow against the copy-pr-bot mirror branch. Without this,
5+
# the gated workflow only runs on push to `pull-request/<N>`, so a label
6+
# applied after the mirror was created leaves the gate stuck red until someone
7+
# manually re-runs the workflow.
8+
#
9+
# Pushes to `pull-request/<N>` (whether from an automatic copy-pr-bot sync or
10+
# a maintainer-typed `/ok to test`) already re-trigger the gated workflow on
11+
# their own - only the label-application case needs this dispatcher.
12+
#
13+
# Uses `pull_request_target` so forked PRs get a write-capable token. The job
14+
# never checks out PR code; it only calls the GitHub API.
15+
16+
on:
17+
pull_request_target:
18+
types: [labeled]
19+
20+
permissions: {}
21+
22+
jobs:
23+
dispatch:
24+
name: Dispatch E2E workflow for labeled PR
25+
if: github.event.label.name == 'test:e2e' || github.event.label.name == 'test:e2e-gpu'
26+
runs-on: ubuntu-latest
27+
permissions:
28+
actions: write
29+
pull-requests: write
30+
steps:
31+
- name: Dispatch workflow against the copy-pr-bot mirror
32+
env:
33+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
GH_REPO: ${{ github.repository }}
35+
PR_NUMBER: ${{ github.event.pull_request.number }}
36+
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
37+
LABEL_NAME: ${{ github.event.label.name }}
38+
shell: bash
39+
run: |
40+
set -euo pipefail
41+
42+
case "$LABEL_NAME" in
43+
test:e2e) workflow=branch-e2e.yml ;;
44+
test:e2e-gpu) workflow=test-gpu.yml ;;
45+
*) echo "Unrecognized label $LABEL_NAME"; exit 1 ;;
46+
esac
47+
48+
mirror_ref="pull-request/$PR_NUMBER"
49+
mirror_sha=$(gh api "repos/$GH_REPO/branches/$mirror_ref" --jq '.commit.sha' 2>/dev/null || echo "")
50+
short_pr=${PR_HEAD_SHA:0:7}
51+
52+
if [ -z "$mirror_sha" ]; then
53+
gh pr comment "$PR_NUMBER" --body "Label \`$LABEL_NAME\` applied, but copy-pr-bot has not mirrored this PR yet. A maintainer needs to comment \`/ok to test $PR_HEAD_SHA\` to start the mirror; re-apply the label once \`$mirror_ref\` exists."
54+
exit 0
55+
fi
56+
57+
if [ "$mirror_sha" != "$PR_HEAD_SHA" ]; then
58+
short_mirror=${mirror_sha:0:7}
59+
gh pr comment "$PR_NUMBER" --body "Label \`$LABEL_NAME\` applied, but \`$mirror_ref\` is at \`$short_mirror\` while the PR head is \`$short_pr\`. Comment \`/ok to test $PR_HEAD_SHA\` to refresh the mirror, then re-apply the label."
60+
exit 0
61+
fi
62+
63+
echo "Dispatching $workflow against $mirror_ref ($short_pr) for label $LABEL_NAME."
64+
gh workflow run "$workflow" --ref "$mirror_ref"
65+
gh pr comment "$PR_NUMBER" --body "Dispatched \`$workflow\` against \`$mirror_ref\` at \`$short_pr\` (label \`$LABEL_NAME\`). Results will post as checks on this PR."

CI.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# CI
2+
3+
This document describes how OpenShell's continuous integration works for pull requests, with a focus on what contributors need to do to get their PR tested.
4+
5+
For local test commands see [TESTING.md](TESTING.md). For PR conventions see [CONTRIBUTING.md](CONTRIBUTING.md).
6+
7+
## Overview
8+
9+
E2E tests run on self-hosted runners (`build-arm64`, GPU runners). To keep untrusted PR code off those runners we use NVIDIA's copy-pr-bot, which mirrors trusted PR commits to internal `pull-request/<N>` branches in this repository. The gated workflows trigger on pushes to those branches, not on the original PR.
10+
11+
Two opt-in labels enable the suites:
12+
13+
- `test:e2e` runs `Branch E2E Checks` (non-GPU E2E)
14+
- `test:e2e-gpu` runs `GPU Test`
15+
16+
Both are required to merge once the corresponding `E2E Gate` checks are marked required in branch protection.
17+
18+
## Commit signing
19+
20+
copy-pr-bot decides whether to mirror a PR automatically based on whether the author is trusted. For org members and collaborators, "trusted" means **all commits in the PR are cryptographically signed**. Unsigned commits, even from an org member, force the bot to wait for a maintainer's `/ok to test <SHA>`.
21+
22+
DCO sign-off (`-s` / `Signed-off-by`) is a separate requirement and does not count as commit signing.
23+
24+
### One-time setup with an SSH key
25+
26+
If you already use an SSH key for `git push`, you can reuse it as a signing key. (You can also generate a separate one - GitHub allows the same SSH key as both auth and signing.)
27+
28+
1. Generate a key (skip if reusing your existing SSH key):
29+
30+
```shell
31+
ssh-keygen -t ed25519 -C "you@example.com" -f ~/.ssh/id_ed25519_signing
32+
```
33+
34+
2. Add the **public** key at <https://github.com/settings/keys> using **New SSH key**, and set **Key type: Signing Key** (not Authentication). Signing keys are managed separately from authentication keys, even when they reuse the same key material - you have to add the entry once for each role.
35+
36+
3. Configure git globally:
37+
38+
```shell
39+
git config --global gpg.format ssh
40+
git config --global user.signingkey ~/.ssh/id_ed25519_signing.pub
41+
git config --global commit.gpgsign true
42+
git config --global tag.gpgsign true
43+
```
44+
45+
4. Verify on a test commit:
46+
47+
```shell
48+
git commit --allow-empty -s -m "test: signing"
49+
```
50+
51+
Push the branch and confirm GitHub shows the commit as **Verified**.
52+
53+
## Pull request flows
54+
55+
### Internal contributor PR
56+
57+
Prerequisites:
58+
59+
- Org member or collaborator on the repo.
60+
- All commits cryptographically signed (see [Commit signing](#commit-signing)).
61+
- All commits include a DCO sign-off (`git commit -s`).
62+
63+
Flow:
64+
65+
1. Open the PR. copy-pr-bot mirrors it to `pull-request/<N>` automatically.
66+
2. A maintainer applies `test:e2e` and/or `test:e2e-gpu`.
67+
3. `E2E Label Dispatch` detects the label and triggers the matching workflow against the mirror.
68+
4. Results post as checks on your PR head SHA.
69+
5. New commits push to the mirror automatically; gated workflows re-run on their own. No re-labeling needed.
70+
71+
### Forked PR
72+
73+
Prerequisites:
74+
75+
- DCO sign-off (`git commit -s`) on every commit. Commit signing is not required for forks - copy-pr-bot trusts forks based on maintainer review, not signing.
76+
- A maintainer must vouch you. See the [Vouch System](AGENTS.md#vouch-system).
77+
78+
Flow:
79+
80+
1. Open the PR. The vouch check confirms you are vouched (otherwise the PR is auto-closed).
81+
2. copy-pr-bot does not mirror forks automatically. A maintainer reviews the diff and comments `/ok to test <SHA>` with your latest commit SHA.
82+
3. After `/ok to test`, copy-pr-bot mirrors to `pull-request/<N>`.
83+
4. A maintainer applies `test:e2e` / `test:e2e-gpu`. The dispatcher runs the matching workflow against the mirror.
84+
5. Results post as checks on your PR.
85+
86+
Important: every new commit you push requires another `/ok to test <new-SHA>` from a maintainer before E2E will run on it. If a label is applied while the mirror is stale, `E2E Label Dispatch` will post a comment explaining what's needed.
87+
88+
## copy-pr-bot
89+
90+
[copy-pr-bot](https://github.com/apps/copy-pr-bot) is a GitHub App maintained by NVIDIA that solves a specific GitHub Actions security problem: by default, `pull_request`-triggered workflows on a self-hosted runner can run an arbitrary contributor's code on hardware the project owns. For projects that need self-hosted runners (GPU access, ARM hardware, on-prem secrets), GitHub's recommended pattern is to never trigger workflows directly from external `pull_request` events.
91+
92+
copy-pr-bot enforces that pattern. When a PR is opened against this repository, the bot evaluates whether the change is trusted - by default, only commits authored by org members and signed with a verified key are trusted, and forks always need an explicit per-SHA approval. Once a change passes that check, the bot mirrors the PR head into a branch named `pull-request/<N>` inside this repository. Our self-hosted workflows then trigger on `push` to those mirror branches, never on the original `pull_request` event.
93+
94+
The user-visible consequences inside this repo:
95+
96+
- A PR cannot run E2E until copy-pr-bot has mirrored it. For trusted authors this happens within seconds of opening the PR; for forked PRs it requires a maintainer to comment `/ok to test <SHA>`.
97+
- New commits to a fork need a fresh `/ok to test <new-SHA>` before the mirror updates.
98+
- The `pull-request/<N>` branches are not for humans to push to - they are managed by the bot.
99+
100+
The bot's full administrator documentation is internal to NVIDIA. The only command contributors may see in PR comments is `/ok to test <SHA>`, used by maintainers to approve a specific commit on a forked PR for testing.
101+
102+
## Workflow files
103+
104+
| File | Role |
105+
|---|---|
106+
| `.github/workflows/branch-e2e.yml` | Non-GPU E2E. Triggers on `push: pull-request/[0-9]+`. |
107+
| `.github/workflows/test-gpu.yml` | GPU E2E. Triggers on `push: pull-request/[0-9]+`. |
108+
| `.github/actions/pr-gate/action.yml` | Composite action that resolves PR metadata and verifies the required label is set. |
109+
| `.github/workflows/e2e-gate.yml` | Posts the required `E2E Gate` check on the PR. Re-evaluates after the gated workflow completes. |
110+
| `.github/workflows/e2e-gate-check.yml` | Reusable gate logic shared by E2E and GPU E2E. |
111+
| `.github/workflows/e2e-label-dispatch.yml` | Triggers gated workflows when a `test:e2e*` label is applied. Posts a comment if the mirror is missing or stale. |

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,9 @@ All contributions must include a `Signed-off-by` line in each commit message. Th
293293
```bash
294294
git commit -s -m "feat(sandbox): add new capability"
295295
```
296+
297+
DCO sign-off is separate from cryptographic commit signing. CI requires signing for org members so that copy-pr-bot can mirror your PR automatically; see [CI.md](CI.md#commit-signing) for setup.
298+
299+
## CI
300+
301+
How E2E runs in CI, the `test:e2e` / `test:e2e-gpu` labels, copy-pr-bot, and commit-signing setup are documented in [CI.md](CI.md).

0 commit comments

Comments
 (0)