Skip to content

feat: read shared data files locally instead of fetching from GitHub - #1614

Draft
neon60 wants to merge 9 commits into
developfrom
feat/local-common-data
Draft

feat: read shared data files locally instead of fetching from GitHub#1614
neon60 wants to merge 9 commits into
developfrom
feat/local-common-data

Conversation

@neon60

@neon60 neon60 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Motivation

Every rocm-docs-core build fetched shared data files from GitHub at build time, and this ran in every component repo (ROCm, rocm-systems, rocm-libraries). The version and toolkit files were fetched on the html-page-context event — once per page — so a ~100-page build made roughly 430 raw.githubusercontent.com requests, scaling linearly with page count. In parallel CI, all of these builds drew from the same anonymous GitHub quota simultaneously.

Two of the .txt fetches had no error handling, so a single 429 crashed the build outright; others retried (up to 100×, or looped for up to 10 minutes) which only amplified request volume under throttling. The projects.yaml fetch additionally used the unauthenticated GitHub REST API (60 requests/hour hard limit). Together this produced the rate-limit failures seen across component-repo CI.

Technical Details

  • New rocm_docs/common.py — centralizes access to the shared data checkout:
    • get_common_dir() / read_common_file() resolve the checkout location and read data files locally.
    • ensure_common_dir() resolves the checkout during extension setup so a consumer's conf.py needs no configuration. Precedence: rocm_docs_common_dir config value → ROCM_DOCS_COMMON_DIR env var → auto-clone rocm-docs-common to /rocm-docs-common.
    • clone_common_if_missing() clones the checkout when absent and fast-forwards it to the branch tip when already present, so repeated local builds don't read stale data. The refresh is best-effort (a failure logs a warning and uses the existing copy); the initial clone still raises.
    • There is no per-file remote fetch fallback: once resolved, all data files are read from the checkout, and a missing directory or file fails the build.
  • rocm_docs/projects.py — _load_projects() reads projects.yaml from the checkout; removed the GitHub-API fetch path, _fetch_projects, MappingFileFetchError, the bundled fallback, and the now-unused os/github/requests imports. Registered the rocm_docs_common_dir config value and calls ensure_common_dir() in setup().- rocm_docs/theme.py — all four data-file fetches now read locally; removed the requests/time/MAX_RETRY retry machinery.
  • .readthedocs.yaml — added a post_checkout job that clones rocm-docs-common to the repo root, matching the path ensure_common_dir() resolves to (so the automatic clone is a no-op on RTD). Added the clone directory to .gitignore.
  • Docs — added docs/developer_guide/local_common_data.md (and its TOC entry) documenting resolution order, local builds, and RTD behavior.
  • Tests — added a tests/common_data/ fixture (placeholder secrets, no real tokens) and an autouse fixture that points test builds at it.
  • Prerequisite — none for consumers: builds auto-clone rocm-docs-common by default. To pin a specific checkout (for example, unreleased data), set the rocm_docs_common_dir config value or the ROCM_DOCS_COMMON_DIR env var. The data files previously lived on the new_data/data branches of this repo (and projects.yaml on develop); they now live in rocm-docs-common.

Test Plan

  • ruff and mypy run clean on the changed files.
  • Full unit test suite via pytest.
  • Full ROCm docs build using the ROCM_DOCS_COMMON_DIR environment variable, checking the build log for any remaining rocm-docs-core GitHub fetches.
  • Full ROCm docs build using -D rocm_docs_common_dir=... with the env var unset, to exercise the config-value path.
  • Build with neither the config value nor env var set, to confirm the automatic clone resolves the checkout.
  • Second consecutive local build with the auto-cloned checkout in place, to confirm it refreshes to the branch tip rather than going stale.

Test Result

  • ruff: all checks passed. mypy: no issues found.
  • pytest: 54 passed.
  • Full ROCm build (107 pages) via env var: build succeeded, 0 rocm-docs-core GitHub fetches (down from ~430).
  • Full ROCm build via -D rocm_docs_common_dir=... with env var unset: build succeeded, 0 fetches.
  • With neither set: build auto-cloned rocm-docs-common and succeeded, 0 data-file fetches.
  • Second build with the checkout present: refreshed to the branch tip (git fetch + checkout FETCH_HEAD) before reading data.

Known Issues

  • COMMON_REPO_URL in common.py and the post_checkout clone in .readthedocs.yaml currently point at github.com/neon60/rocm-docs-common (a fork). These move to the ROCm-org rocm-docs-common repo before merge.

Submission Checklist

@neon60
neon60 marked this pull request as draft August 14, 2026 13:20
@neon60
neon60 requested a review from alexxu-amd August 14, 2026 13:28
neon60 and others added 9 commits August 28, 2026 12:19
Replace every per-build GitHub fetch of shared data (latest_version.txt,
release_candidate.txt, rocm_toolkits.txt, google_site_verification.txt,
and projects.yaml) with local reads from a rocm-docs-common checkout.

The checkout location is resolved from the new rocm_docs_common_dir
config value (settable in conf.py) or the ROCM_DOCS_COMMON_DIR
environment variable, config value taking precedence. There is no
remote fallback: a missing directory or file fails the build so that
builds always use pinned common data rather than a moving branch.

This removes hundreds of raw.githubusercontent.com requests per build
(the version/toolkit fetches ran once per page) plus the unauthenticated
GitHub API call for projects.yaml, eliminating the rate-limit failures
seen across parallel component-repo CI. The retry loops that could stall
a build for minutes on throttling are gone with them.

Add a tests/common_data fixture (with a placeholder google site
verification token) and an autouse fixture so the test builds read
from it.
Read the Docs clones the rocm-docs-common repo (tip of main) in a
post_checkout job so rocm_docs reads the shared build-data files locally;
docs/conf.py points rocm_docs_common_dir at that checkout. The cloned
directory is gitignored so it is never committed.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Local sphinx-build now works without a manual clone: conf.py clones
rocm-docs-common (tip of main) to the repo root if the folder is absent,
then points rocm_docs_common_dir at it. On Read the Docs the post_checkout
job already provides the clone, so the guard skips re-cloning.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Add clone_common_if_missing() plus COMMON_REPO_URL/COMMON_REPO_BRANCH so
the clone-if-absent logic and the repo URL live in one place. Consumer
conf.py files call the helper instead of duplicating the git clone block
and hardcoding the URL.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
rocm_docs now resolves the common-data checkout itself at config-inited:
if neither rocm_docs_common_dir nor ROCM_DOCS_COMMON_DIR is set it clones
a default to <repo>/rocm-docs-common. Consumer conf.py files need no
common-dir setup at all; the value is stored back on the config so the
theme and projects reads reuse it.

Add ensure_common_dir() to rocm_docs.common and drop the now-redundant
clone call from this repo's own conf.py.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Add docs/developer_guide/local_common_data.md explaining how rocm_docs reads
shared build data from a local rocm-docs-common checkout, the resolution order
(config value, env var, auto-clone), and the local/RTD workflows. Expand the
.readthedocs.yaml post_checkout comment to describe the automatic resolution
and how to override it, and link the guide from the toc.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
The spellcheck CI splits "component-repo" on the hyphen and flags "repo",
which is not in .wordlist.txt. Use the full word "repository", matching
the terminology already used elsewhere in this file.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
The auto-clone only ran when <dest>/data was absent, so after the first
local build the persisted checkout was never updated and silently went
stale. Fast-forward the checkout to the branch tip when it already exists
so repeated local builds read the latest shared data. The refresh is
best-effort: a failure (offline, throttling) warns and builds against the
existing copy, while the initial clone still raises. Only the auto-managed
clone is refreshed; an explicit rocm_docs_common_dir/ROCM_DOCS_COMMON_DIR
is left untouched.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
@neon60
neon60 force-pushed the feat/local-common-data branch from d3ea703 to 0b8c3be Compare August 28, 2026 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant