diff --git a/website/docs/guides/ci.md b/website/docs/guides/ci.md index 4fd21d8..1964c22 100644 --- a/website/docs/guides/ci.md +++ b/website/docs/guides/ci.md @@ -47,6 +47,33 @@ between CI runs turns unchanged targets into instant hits. Cache the heph home directory (set with [`homeDir`](/docs/reference/configuration#keys)) across jobs using your CI's caching mechanism, keyed on your lockfiles. +## Live build status (GitHub Actions) + +The [GitHub Actions hook](../plugins/gha.md) writes a live status comment on the +pull request under review and a step summary when the command finishes. Load it +from a `ci.hephconfig` overlay so it only activates in CI: + +```yaml title="ci.hephconfig" +plugins: + - url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/v/heph-gha-plugin.json +``` + +```yaml title=".github/workflows/build.yml" +jobs: + build: + permissions: + pull-requests: write # required for the live PR comment + steps: + - uses: actions/checkout@v4 + - name: Build + env: + HEPH_PROFILES: ci + run: heph run //... --no-tui +``` + +See the [GitHub Actions plugin page](../plugins/gha.md) for the full options +reference. + ## A representative job ```bash title="terminal" diff --git a/website/docs/plugins/gha.md b/website/docs/plugins/gha.md new file mode 100644 index 0000000..35ac5cd --- /dev/null +++ b/website/docs/plugins/gha.md @@ -0,0 +1,145 @@ +--- +title: "GitHub Actions" +sidebar_position: 11 +description: Live build-status PR comments and step summaries for GitHub Actions. +--- + +# GitHub Actions + +The `gha` hook observes the engine's build-event stream and surfaces build +progress in GitHub Actions two ways: + +- **Live PR comment** — a sticky comment on the current pull request is created + at job start and patched on a timer. It shows targets matched, built, cached, + and failed, plus any targets running longer than 10 seconds. One comment per + CI job; a job's multiple heph steps each get their own collapsible section, so + earlier steps' results are preserved as later steps update. +- **Step summary** — the full markdown is written once to + `$GITHUB_STEP_SUMMARY` when the command finishes. + +The live comment is only created when running inside a pull request (GitHub +populates `GITHUB_EVENT_PATH` or `GITHUB_REF` with the PR number). On a push, +schedule, or manual dispatch there is no PR to comment on — only the step +summary is written. + +## What it is + +`gha` is a **hook** — a third plugin kind alongside providers and drivers. A +hook receives every `BuildEvent` the engine emits but never produces or runs +targets. It runs in the same process as heph on a background thread. + +## Enabling it + +The GHA plugin is an **external plugin** — it ships as a shared library +(cdylib) with a manifest file (`heph-gha-plugin.json`). + +### Loading from a URL + +```yaml title=".hephconfig" +plugins: + - url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/v/heph-gha-plugin.json + checksum: sha256: # optional; pin from heph-gha-plugin.json.sha256 +``` + +See [Pinning manifests with checksums](/docs/reference/configuration#pinning-manifests-with-checksums) +for details. + +### CI-only via a profile overlay + +The hook only makes sense in CI, so the recommended pattern is to load it from +a profile overlay so local runs are unaffected: + +```yaml title="ci.hephconfig" +plugins: + - url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/v/heph-gha-plugin.json + checksum: sha256: +``` + +```yaml title=".github/workflows/build.yml" +jobs: + build: + permissions: + pull-requests: write # required for the live PR comment + steps: + - uses: actions/checkout@v4 + - name: Build + env: + HEPH_PROFILES: ci + run: heph run //... --no-tui +``` + +See [Profiles](/docs/reference/configuration#profiles--layered-config-overlays) for +how profile overlays work. + +## GitHub token permissions + +The live PR comment is written via the GitHub REST API using `GITHUB_TOKEN` by +default. The token must have `pull-requests: write` permission: + +```yaml title=".github/workflows/build.yml" +permissions: + pull-requests: write +``` + +The hook needs three things to create or update the comment: + +1. A non-empty `GITHUB_TOKEN` (or the env var named by `tokenEnv`) +2. `GITHUB_REPOSITORY` set by Actions +3. A PR number — read from the event payload (`GITHUB_EVENT_PATH`) or inferred + from the ref (`refs/pull//merge` or `/head`) + +When any of the three is absent the comment is silently skipped and a log +message is emitted. The step summary is always written regardless. + +## Options + +```yaml title="ci.hephconfig" +plugins: + - url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/v/heph-gha-plugin.json + options: + refreshSecs: 30 # optional + summaryPath: "" # optional + tokenEnv: GITHUB_TOKEN # optional +``` + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `refreshSecs` | `number` | `30` | How often (in seconds) the live PR comment is patched while the build runs. Minimum 1. | +| `summaryPath` | `string` | `$GITHUB_STEP_SUMMARY` | Path where the final markdown is written at the end of the run. When neither the option nor the env var is set, the step summary is skipped. | +| `tokenEnv` | `string` | `GITHUB_TOKEN` | Name of the environment variable holding the GitHub API token used for PR comment operations. | + +## What the comment looks like + +While the build runs the comment shows live progress: + +```markdown +## ⏳ heph: run //... + +**Targets:** 12 / ~40  •  **built:** 3  •  **cached:** 9  •  **failed:** 0 + +
🐢 Slow targets (1) + +| target | phase | running for | +| --- | --- | --- | +| `//heavy:compile` | execute | 23s | + +
+``` + +The heading emoji reflects the current state: ⏳ while running, ✅ once every +matched target finishes without error, ❌ as soon as any target fails. + +A total shown as `~40` means the matcher hasn't resolved all targets yet; the +tilde drops once resolution is complete. + +When failures occur a **Failed** section is appended, listing each failed target +address and the first line of its error message. + +## One comment per job, one section per step + +The comment is scoped by `GITHUB_JOB` — one comment per CI job, reused across +reruns (found by a hidden HTML marker, never duplicated). Within the comment, +each heph invocation owns a section keyed by its command line (the arguments +passed to `heph`). A job with three separate `heph run` steps produces one +comment with three independently-updated sections, so earlier steps' results +are preserved as later steps write theirs. diff --git a/website/docs/plugins/index.md b/website/docs/plugins/index.md index 46b5e4b..5499c4a 100644 --- a/website/docs/plugins/index.md +++ b/website/docs/plugins/index.md @@ -1,18 +1,19 @@ --- title: Plugins sidebar_position: 1 -description: The plugins that supply heph's functionality — the drivers targets execute through and the providers that discover them. +description: The plugins that supply heph's functionality — the drivers targets execute through, the providers that discover them, and the hooks that observe build events. slug: /plugins --- # Plugins -Almost everything heph can do comes from **plugins**. A plugin is either a -**driver** — a named executor a target references via its `driver` field — or a -**provider** — it discovers or generates targets. For example, when you write `driver = -"bash"` in a BUILD file, you are reaching for a driver registered by the -[Exec](./exec.md) plugin; when heph scans the workspace for BUILD files, that is -a provider at work. +Almost everything heph can do comes from **plugins**. Plugins come in three +kinds: a **driver** is a named executor a target references via its `driver` +field; a **provider** discovers or generates targets; a **hook** observes the +engine's build-event stream without producing or running anything. For example, +when you write `driver = "bash"` in a BUILD file, you are reaching for a driver +registered by the [Exec](./exec.md) plugin; when heph scans the workspace for +BUILD files, that is a provider at work. ## Drivers @@ -46,3 +47,14 @@ so it registers no driver. |-----------------------------|------------------------------------------------------------------| | [Buildfile](./buildfile.md) | Scans the workspace for BUILD files and parses target definitions. | | [Query](./query.md) | Selects targets dynamically by label, package, prefix, or output. | + +## Hooks + +Hook plugins observe the engine's `BuildEvent` stream — targets matched, +started, finished, cache hits, failures — without producing or running targets. +They are purely build-event consumers and run in the same process as heph on a +background thread. + +| Plugin | Purpose | +|-------------------------------------|----------------------------------------------------------------------------| +| [GitHub Actions](./gha.md) | Live PR comment and step summary for GitHub Actions builds. | diff --git a/website/sidebars.ts b/website/sidebars.ts index 0d51f0b..5f3a9ed 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -47,6 +47,7 @@ const sidebars: SidebarsConfig = { 'plugins/nix', 'plugins/query', 'plugins/textfile', + 'plugins/gha', ], }, {