|
| 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. | |
0 commit comments