docs/brev.md
Rama main · réplica de lectura del repositorio original.
# NVIDIA Brev Setup Instructions
Use [start-brev-gha-runner](https://github.com/omsf-eco-infra/start-brev-gha-runner)
and [stop-brev-gha-runner](https://github.com/omsf-eco-infra/stop-brev-gha-runner)
to create ephemeral, repository-scoped GitHub Actions runners on
[NVIDIA Brev](https://docs.nvidia.com/brev/). The actions use the Brev CLI and
the `gha-runner` deployment and teardown lifecycle.
The start action provisions instances, installs the GitHub Actions runner, and
waits for registration. Each runner accepts one job. The stop action removes
the runner registrations and **permanently deletes the Brev instances and their
storage**; it does not use `brev stop`, which retains billable storage.
## Prerequisites
- A Brev organization with access to the instance types you want to use.
- Permission to manage self-hosted runners in the target GitHub repository.
- A Linux GitHub-hosted runner, such as `ubuntu-latest`, to run these
Docker-based actions for provisioning and cleanup.
## Setup
### Create a Brev API key
1. In the Brev organization that will own the runners, create a
[Brev API key](https://docs.nvidia.com/brev/guides/api-keys) with
**Read & Write** access.
2. Copy the full key when it is shown. Brev displays it only once, and it
expires on the date you configure.
3. In your GitHub repository, go to **Settings → Secrets and variables →
Actions** and add a repository secret named `BREV_API_KEY`.
Both actions log in with this key, which selects its Brev organization
automatically. Use a key for the same organization when starting and deleting
instances.
### Create a GitHub access token
Create a token that can manage repository self-hosted runners:
- A fine-grained personal access token with access to the target repository
and repository **Administration: Read and write** permission; or
- A classic personal access token with the `repo` scope.
The token owner must have the required repository administration access. If
your organization requires token approval or SSO authorization, complete that
before using the token. Save it as the repository secret `GH_PAT`.
Pass `GH_PAT` to both actions; the workflow's automatic `GITHUB_TOKEN` is not a
replacement for a token able to manage repository runners.
### Choose an instance type
Use the [Brev CLI](https://docs.nvidia.com/brev/) locally to run `brev search`
and choose an available instance type. Set `brev_instance_type` to a single
type, or a comma-separated capacity fallback chain, for example
`g5.xlarge,g6.xlarge`. Availability depends on your organization and current
capacity; these example types are not guaranteed to be available.
The actions include the CLI, so you do not need to install it in the workflow.
The startup script installs the GitHub runner, not your project's dependencies;
install those in your job as needed.
## Action inputs and outputs
### Start action
| Input | Required from caller | Default | Description |
| --- | --- | --- | --- |
| `brev_instance_type` | yes | — | Instance type or comma-separated fallback chain. |
| `brev_timeout` | no | `600` | Provisioning timeout in seconds for each instance. |
| `extra_gh_labels` | no | — | Additional comma-separated GitHub runner labels. |
| `instance_count` | no | `1` | Number of runners to create. |
| `repo` | no | Current repository | Target repository in `owner/repository` format. |
| `gh_timeout` | no | `1200` | Timeout in seconds waiting for each GitHub runner to register. |
Both `BREV_API_KEY` and `GH_PAT` must be passed as environment variables.
| Output | Description |
| --- | --- |
| `mapping` | JSON object mapping Brev instance names to GitHub runner labels. Pass this to the stop action. |
| `instances` | JSON array of the generated runner labels. Use this to route jobs to the provisioned runners. |
For the default `instance_count: 1`, use
`runs-on: ${{ fromJSON(needs.start-brev-runner.outputs.instances) }}`.
If you provision multiple runners, use a job matrix over `instances` and select
one label per matrix job. A `runs-on` array means a runner must match **all**
labels; it does not distribute jobs across those runners. Each ephemeral runner
can execute only one job.
### Stop action
| Input | Required from caller | Default | Description |
| --- | --- | --- | --- |
| `instance_mapping` | yes | — | The start action's `mapping` output, a non-empty JSON object. |
| `repo` | no | Current repository | Repository containing the runner registrations, in `owner/repository` format. |
Pass `BREV_API_KEY` and `GH_PAT` as environment variables here too. If you set
`repo` on the start action, use the same value on the stop action.
## Example workflow
Save the following as `.github/workflows/brev-runner.yml`. It starts one runner,
runs a GPU check, and deletes the instance even if the test fails. The action
references are pinned to the repositories' `v1` commit SHAs.
```yaml
name: Test Brev Self-Hosted Runner
on:
workflow_dispatch:
permissions:
contents: read
jobs:
start-brev-runner:
runs-on: ubuntu-latest
outputs:
mapping: ${{ steps.brev-start.outputs.mapping }}
instances: ${{ steps.brev-start.outputs.instances }}
steps:
- name: Create Brev runner
id: brev-start
uses: omsf-eco-infra/start-brev-gha-runner@8caae6a56ffe6f455278dea33e20b9b8dc003d4e # v1
with:
brev_instance_type: g5.xlarge,g6.xlarge
instance_count: 1
env:
BREV_API_KEY: ${{ secrets.BREV_API_KEY }}
GH_PAT: ${{ secrets.GH_PAT }}
test:
needs: start-brev-runner
runs-on: ${{ fromJSON(needs.start-brev-runner.outputs.instances) }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check GPU access
run: nvidia-smi
stop-brev-runner:
runs-on: ubuntu-latest
needs: [start-brev-runner, test]
if: ${{ always() && needs.start-brev-runner.outputs.mapping != '' }}
steps:
- name: Delete Brev runner
uses: omsf-eco-infra/stop-brev-gha-runner@54a8a10bd8d455457e71d14e92e78c6b216f07e7 # v1.1.0
with:
instance_mapping: ${{ needs.start-brev-runner.outputs.mapping }}
env:
BREV_API_KEY: ${{ secrets.BREV_API_KEY }}
GH_PAT: ${{ secrets.GH_PAT }}
```
## Cleanup and troubleshooting
- **Keep cleanup on a GitHub-hosted runner.** An ephemeral Brev runner exits
after its job and cannot run a subsequent cleanup job.
- **Keep the mapping guard.** `always()` allows cleanup after a failed test;
the additional check avoids calling the stop action with an empty mapping
when startup did not produce outputs.
- **Check Brev after failed provisioning or interrupted cleanup.** A failure
before the start action emits `mapping` can leave instances without cleanup
outputs. Workflow cancellation or cleanup failure can also leave resources
behind. Inspect your Brev organization and delete leftover instances
manually; do not treat this workflow as a billing safeguard.
- **Missing GitHub registration does not prevent instance deletion.** The stop
action uses the supplied mapping even if an ephemeral runner has already
unregistered itself.
- **Registration timeout:** check the Brev instance's startup logs and network
access to GitHub. Increase `brev_timeout` for slow provisioning or
`gh_timeout` for slow runner registration as appropriate.
- **Authentication failure:** check API-key expiration, its organization and
Read & Write access, and the GitHub token's repository access and permissions.
Run only trusted code on these self-hosted runners. Do not expose the workflow
or its credentials to untrusted pull requests. Upload any needed artifacts
before cleanup: deleting an instance also deletes its storage.
## Useful resources
- [NVIDIA Brev documentation](https://docs.nvidia.com/brev/)
- [Brev API keys](https://docs.nvidia.com/brev/guides/api-keys)
- [Start action source and README](https://github.com/omsf-eco-infra/start-brev-gha-runner)
- [Stop action source and README](https://github.com/omsf-eco-infra/stop-brev-gha-runner)
- [GitHub self-hosted runner security](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#hardening-for-self-hosted-runners)