repomatic.lint_repo.site module

Checks of the site deployment: GitHub Pages and Cloudflare Pages.

The GitHub Pages source and the redirect of its legacy URLs, the Cloudflare credentials, the _redirects files as the Pages engine reads them, the wrangler.toml file, and the files over the Pages size limit.

repomatic.lint_repo.site.MAX_REPORTED_DEAD_URLS = 5

How many abandoned redirect sources a failing _redirects check names.

Enough to recognize which part of the file fell off the end, short of dumping a tail that can run to hundreds of rules into one lint message. The remainder is counted rather than listed, and the fix is the same reorder either way.

repomatic.lint_repo.site.PAGES_LIMIT_LABEL: Final = '25 MiB'

The Cloudflare Pages file size limit, the way the messages spell it.

repomatic.lint_repo.site.PAGES_DEPLOYMENT_SOURCE: Final = RepoSettingProbe(label='Pages deployment source check', endpoint='pages', field='build_type', pass_message='GitHub Pages deployment source is set to GitHub Actions.', fail_message="GitHub Pages deployment source is set to 'Deploy from a branch'. Change it to 'GitHub Actions' under https://github.com/{repo}/settings/pages so the docs.yaml workflow can deploy.", passing=frozenset({'workflow'}), failing=frozenset({'legacy'}), unknown='unknown build_type {value!r}', unavailable='Pages not configured or API inaccessible')

The GitHub Pages build_type, read by check_pages_deployment_source().

repomatic.lint_repo.site.check_pages_deployment_source(ctx)[source]

Check that GitHub Pages is deployed through GitHub Actions, not a branch.

The docs.yaml workflow uses actions/upload-pages-artifact and actions/deploy-pages, which require the Pages source to be set to GitHub Actions in the repository settings. Branch-based deployment (legacy) is incompatible.

Note

A 404 means Pages is not configured at all. This is treated as indeterminate (None) rather than a failure, because the repository may not have deployed docs yet.

Return type:

CheckResult

repomatic.lint_repo.site.check_pages_redirect_preserved(ctx)[source]

Check that the old github.io URLs still redirect to the live site.

A repository whose site moved to Cloudflare Pages keeps its <owner>.github.io/<repo>/… URLs answering through a single field: the GitHub Pages custom domain. Set it, and GitHub redirects that whole space with a path-preserving 301, for free, covering paths the site never even had. What it rescues is precisely the set of URLs nobody can rewrite: search indexes, other projects’ readmes, and the [project.urls] metadata frozen into every release already published.

Two ways to lose it, both invisible from inside the repository. Disabling Pages deletes the redirect along with the site, and every historical link starts answering 404 with nothing to show a maintainer why. Leaving the custom domain unset is quieter still: the old host keeps serving a copy of the documentation, which stops being rebuilt the moment the deploy job is gated off, so the two hosts disagree more with every release.

Return type:

CheckResult

Returns:

A CheckResult. passed is None when the repository has no legacy Pages URLs to preserve, or the declared URL is unreadable.

repomatic.lint_repo.site.check_stale_gh_pages_branch(ctx)[source]

Check for a leftover gh-pages branch after switching to GitHub Actions.

When Pages is deployed through GitHub Actions, the gh-pages branch is no longer needed and should be deleted to avoid confusion.

Return type:

CheckResult

repomatic.lint_repo.site.check_cloudflare_secrets(ctx)[source]

Report whether the Cloudflare Pages deploy has the credential it needs.

One secret, and no identifier beside it: the account is derived from the token at run time, since an account-owned token holding Cloudflare Pages: Edit and nothing else still enumerates the account it belongs to, measured on 2026-08-16 against a cfat_ token with exactly that scope. The token is the whole of the authentication surface.

Return type:

CheckResult

repomatic.lint_repo.site.check_cloudflare_r2_secrets(ctx)[source]

Report whether the offload can upload to the declared R2 bucket.

Without the key pair the deploy still publishes, but it drops every file over the Pages limit: the very files the bucket was declared to serve. The pair is limited to that bucket, which Cloudflare allows on the S3 API only, so CLOUDFLARE_API_TOKEN cannot stand in for it.

Return type:

CheckResult

repomatic.lint_repo.site.check_pages_redirects(ctx)[source]

Audit every committed _redirects file the way the Pages engine reads it.

The engine’s budget accounting is undocumented and its failures are silent: wrangler pages deploy prints nothing when the parser drops a rule or abandons the file, and a dead redirect looks exactly like a URL nobody visits. One site carried 18 dead rules for years this way. The replica in repomatic.cloudflare.redirects reports here what production would do.

Return type:

Iterator[CheckResult]

repomatic.lint_repo.site.check_wrangler_config(ctx)[source]

Check the committed wrangler.toml against the declared Cloudflare state.

The file only matters to local wrangler commands on a Direct Upload project, but it can still contradict the repository’s declared state in two places Cloudflare will not reconcile for anyone: the project name the CI deploy targets, and the compatibility date the live project honours server-side. One value sat three years behind the live one this way, because nothing read it.

Return type:

Iterator[CheckResult]

repomatic.lint_repo.site.check_oversized_site_files(ctx)[source]

Warn about tracked files the Cloudflare Pages deploy cannot upload.

Direct Upload rejects any file over the Pages limit. The deploy drops such a file unless an R2 bucket takes it, and a dropped file leaves a dead link. No setting names the site’s sources, so the check reads every tracked file: a large file outside the site is a false alarm, which is why this warns and never fails.

Return type:

CheckResult