ci: skip Go jobs and add docs-site build for docs-only PRs#21028
Conversation
Add a `changes` job that detects whether any non-docs files changed. Go CI jobs (tests, race-tests, lint, bench, kurtosis, repro, sonar, caplin, hive) are skipped when every changed file is under docs/, saving ~30 min of unnecessary CI for docs-only PRs. Add `docs-site` job (npm ci → typecheck → docusaurus build) that runs whenever docs/site/** is touched. Docusaurus is configured with onBrokenLinks/onBrokenMarkdownLinks/onBrokenAnchors all set to 'throw', so the build catches internal broken links at PR time. For merge_group and workflow_dispatch the full suite always runs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the CI gate workflow to detect docs-only pull requests and skip expensive Go CI jobs when only docs/** files changed, while adding a dedicated docs-site build (typecheck + Docusaurus build) when docs/site/** is touched.
Changes:
- Add a
changesjob to classify PRs as “code changed” vs “docs-only”, and conditionally skip Go CI jobs for docs-only PRs. - Add a reusable
docs-site-build.ymlworkflow and adocs-sitejob inci-gateto runnpm ci→typecheck→buildwhendocs/site/**changes. - Wire
changesoutputs into jobif:conditions and includechanges/docs-sitein theci-gateaggregation.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| .github/workflows/docs-site-build.yml | Adds a reusable workflow to typecheck and build the Docusaurus docs site. |
| .github/workflows/ci-gate.yml | Adds PR-change detection and uses it to skip Go CI for docs-only PRs; triggers docs-site build when needed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add pull-requests:read permission so the gh api call in the changes job can fetch PR file lists without a 403 - Remove the pull_request guard on lint so it also runs in merge_group Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
llms.txt and llms-full.txt live at the repo root and are regenerated by the Docusaurus build (docs/site/scripts/generate-llms.py). Without this, PRs that update those files would trigger the full Go CI suite despite being pure docs changes. Also extends the pattern to root-level *.md files (README.md, CLAUDE.md, etc.) for the same reason. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs/site/ does not exist on main until PR #21013 merges. Without a guard, the docs-site job fires for merge_group events (docs_site=true for all non-PR events) and fails on npm ci in a missing directory, blocking this PR from merging itself. Add a presence check on docs/site/package.json; steps are skipped (job passes) when the directory is absent. Also: - node-version '20' -> '20.x' (standard semver range notation) - drop secrets:inherit from docs-site job (build needs no secrets) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Additional fix pushed (llms.txt coverage): After reviewing #21000, noticed that Extended the This excludes from the "code changed" check:
Nested |
- Fail explicitly if gh api call returns an error instead of silently continuing with empty $files (which would default to code=true) - Add comment explaining the file-pattern regex for future maintainers
When a PR touches docs/site/**, also verify: - generate-llms.py --check (regenerated outputs match committed files) - unittest discover (25-test suite stays green) Mirrors the guard in #21000's docs-deploy.yml so PRs to main get the same llms.txt drift protection that release/3.4 gets at deploy time.
## Summary Sibling of #21028 (which lands the same path-filter on `main`'s `ci-gate.yml`). When a PR only touches `docs/`, root `llms*.txt`, or root `*.md`, skip the `linux` and `win` Go test runs (~20-30 min saved per PR) and instead run a docs-site typecheck/build with the llms.txt drift + unittest guard. ### How it works A new fast `changes` job calls `gh api .../pulls/{n}/files` and emits two outputs: - `code` — `false` if every changed file is under `docs/`, root `llms*.txt`, or root `*.md`; otherwise `true`. Defaults to `true` for `push` / `workflow_dispatch` so nothing is skipped on merge. - `docs_site` — `true` when any `docs/site/**` file is touched. `linux` and `win` are gated on `code != 'false'`. A new `docs-site` job (calling the new reusable `docs-site-build.yml`) runs when `docs_site == 'true'`. If the `gh api` call fails, the step exits with code 1 — the gate fails rather than silently defaulting to skipping jobs. ### What runs when | PR scope | linux/win | docs-site | |----------|-----------|-----------| | Pure code (`*.go`, etc.) | ✅ runs | ⏭️ skipped | | Mixed code + docs | ✅ runs | ✅ runs | | Pure docs (`docs/site/**`) | ⏭️ skipped | ✅ runs | | Pure root-level docs (`llms.txt`, `README.md`) | ⏭️ skipped | ⏭️ skipped | | `push` to `main` / `release/**` | ✅ runs | ✅ runs | ### File-pattern logic A PR is **docs-only** (skips Go CI) when every changed file matches: ``` ^(docs/|llms[^/]*\.txt$|[^/]*\.md$) ``` i.e. files under `docs/`, root-level `llms*.txt`, or root-level `*.md`. Nested `.md` files (e.g. `execution/README.md`) still count as code changes. ### `docs-site-build.yml` Reusable `workflow_call` leaf that: 1. Sets up Python 3.11 + runs `python3 docs/site/scripts/generate-llms.py --check` and `python3 -m unittest discover docs/site/scripts -v` (the llms drift guard from #21000) 2. Sets up Node 20 + runs `npm ci`, `npm run typecheck`, `npm run build` against `docs/site/` Has a defensive guard that skips silently if `docs/site/package.json` **or** `docs/site/scripts/generate-llms.py` is absent — covering both fully absent `docs/site/` and partial migration states. ### Files | File | Change | |------|--------| | `.github/workflows/ci.yml` | Add `permissions: pull-requests: read`, `changes` job, gate `linux`/`win` with `code != 'false'`, add `docs-site` job | | `.github/workflows/docs-site-build.yml` | New reusable workflow (Python llms guard + Node typecheck/build) | ## Test plan - [ ] Open a docs-only PR (touch `docs/site/docs/...`) — confirm `linux`/`win` are skipped and `docs-site` runs - [ ] Open a mixed PR (one `.go` file + one `.md` file) — confirm both `linux`/`win` and `docs-site` run - [ ] Open a pure code PR — confirm `docs-site` is skipped, `linux`/`win` run - [ ] Push to `release/3.4` — confirm everything runs (no skipping) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Bloxster <bloxster@proton.me> Co-authored-by: Gianni <gianni@erigon.dev> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/erigontech/erigon/sessions/72fb002f-851c-4b56-82dd-b85f795002bc Co-authored-by: bloxster <40316187+bloxster@users.noreply.github.com>
Applied in |
|
@copilot apply changes based on the comments in this thread |
Applied in |
yperbasis
left a comment
There was a problem hiding this comment.
LGTM. Nice job on the docs-only fast path and on addressing the prior review comments (pull-requests:read, eest-spec-tests gating, docs-site prereq validation).
A few non-blocking nits:
-
needs.changes.outputs.code != 'false'vs== 'true'— functionally equivalent here, but== 'true'reads more directly. Style only. -
The
docs-sitesilent-skip path (present=false) is essentially dead code onmain: the job only triggers whendocs_site=true, which requires^docs/site/in the PR file list, which requires the directory to exist at HEAD. It's only useful on backports to legacy branches that predate the Docusaurus migration. Worth a one-line comment clarifying that, or just leaving as-is. -
The PR summary lists
npm ci → typecheck → docusaurus build, butdocs-site-build.ymlalso runsgenerate-llms.py --checkandpython3 -m unittest discover docs/site/scripts. The drift check is valuable — but worth surfacing in the description so reviewers aren't surprised that a docs-only PR now also exercises the Python tooling. -
large-filesisn't gated oncode— docs-only PRs still pay for it. Cheap job, fine to leave, but for consistency you could add the sameneeds.changes.outputs.code != 'false'guard.
Worth watching after merge:
- First docs-only PR that lands: confirm Go jobs show as
skippedandci-gatestill passes. - First
merge_grouprun: confirmlintnow actually runs (was previously PR-only). - First fork-PR docs-only change: confirm
pull-requests: readis sufficient for thegh api pulls/N/filescall from a forked head — that's the most likely surprise.
…21277) ## Summary Pure mechanical regeneration of `llms-full.txt` (both root and `docs/site/static/` copies) via `python3 docs/site/scripts/generate-llms.py`. Catches up accumulated drift from prior docs PRs that landed before #21028 added the `--check` step to `ci-gate`. ## Drift content - **New flags documented**: `--erigondb.domain.steps-in-frozen-file`, `--caplin.nat`, `--caplin.columns-keep-slots` - **Corrected defaults**: `--log.dir.verbosity` (added missing default), `--rpc.subscription.filters.maxlogs/maxheaders/maxtxs` (`0` → `10000`) - **Smart-quote normalization** in two CLI flag descriptions - **New "Caplin (consensus layer) NAT" doc section** pulled in from `docs/site/docs/` ## Why now #21028 is stuck in the merge queue because its `docs-site` job now runs `generate-llms.py --check` against every `merge_group` event. That check correctly catches the pre-existing drift on main and fails the queue's CI Gate. Landing this PR clears the drift so #21028's next requeue passes. ## Test plan - [x] `python3 docs/site/scripts/generate-llms.py --check` → "OK: 4 llms files match regenerated content" - [x] Diff is pure regeneration (no manual edits) - [ ] After merge, requeue #21028 → expect docs-site / build to pass 🤖 Generated with Claude Code --------- Co-authored-by: Bloxster <bloxster@proton.me> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The action's OIDC token exchange requires write access; fork PRs fail with 'User does not have write access on this repository'. Gate on head.repo.full_name == github.repository to skip cleanly on forks.
The claude-code-action validates that the workflow file on the PR branch is identical to the version on main — a security safeguard against PRs disabling their own code review. The previous commit caused that check to hard-fail. If a fork guard is still wanted it must land on main first via a separate PR.
Summary
changesjob that queries the GitHub API to detect whether any non-docs files changed in the PR.tests,race-tests,eest-spec-tests,lint,bench,kurtosis,repro,sonar,caplin,hive) when every changed file is docs-only.docs-sitejob that runs wheneverdocs/site/**is touched. It runs four steps:npm ci→typecheck→docusaurus build(withonBrokenLinks/onBrokenMarkdownLinks/onBrokenAnchorsall set tothrow, so internal broken links fail at PR time)python3 docs/site/scripts/generate-llms.py --check— drift check that the committedllms.txt/llms-full.txtmatch what the generator produces (mirrors the guard in [r3.4] docs: add llms.txt generator script and update root llms.txt #21000'sdocs-deploy.ymlso PRs tomainget the same protection thatrelease/3.4gets at deploy time)python3 -m unittest discover docs/site/scripts -v— 25-test suite for the generatormerge_groupandworkflow_dispatch.changesanddocs-siteinci-gateneeds; if the GitHub API call inchangesfails, the step exits non-zero instead of silently skipping jobs (which would have defaulted tocode=true, but better to fail loud than absorb errors).pull-requests: readpermission so thegh api pulls/N/filescall works without a 403.lintfor all event types, includingmerge_group(was previously PR-only).docs-site-build.yml guard behavior
docs/site/directory is entirely absent (e.g. backports to branches that predate the Docusaurus migration).package.json,package-lock.json,scripts/,scripts/generate-llms.py) — these would indicate a partially-broken docs setup that should not pass CI silently.CI matrix after this merges
large-filesdocs-sitedocs/site/**onlydocs/site/**+ codedocs/site/(root*.md,llms*.txt)docs/site/**touchedmerge_grouplarge-filesis intentionally not gated oncode— it's cheap and remains useful for docs-only PRs.File-pattern logic
A PR is considered docs-only, and skips Go CI, when every changed file matches:
That means files under
docs/, root-levelllms*.txt(e.g.llms.txt,llms-full.txt— regenerated bygenerate-llms.pyon every docs build), or root-level*.md(README.md,CLAUDE.md, etc.). Nested Markdown outsidedocs/, such asexecution/README.md, still counts as a code change.Validation
.github/workflows/, so it is intentionally not docs-only and the full CI suite runs.changesjob completed successfully on this PR.ci-gatecompleted successfully on the latest pushed commit.🤖 Generated with Claude Code