repomatic.lint_repo.pins module¶

Checks of the version pins the workflows and the tool registry carry.

The inline upstream pins and their cooldown exemption, the setup-uv version pin and the checksum that covers it, the registry tool pins still inside the cooldown, and the click-extra version the man pages render with.

repomatic.lint_repo.pins.LOCK_FILE = PosixPath('uv.lock')¶

The lockfile the manpages release job installs from.

repomatic.lint_repo.pins.MANPAGES_RENDERER = 'click-extra'¶

The package whose wrap CLI the manpages release job renders through.

repomatic.lint_repo.pins.MANPAGES_RENDERER_FLOOR = <Version('9')>¶

Lowest MANPAGES_RENDERER the manpages release job can render with.

9.0.0 moved the roff source from wrap --man to wrap --help-format man and gave --man the paged manual instead, which writes no file. The job runs in the consumer’s own environment, so the floor is a property of that project’s lock rather than of repomatic’s dependencies.

repomatic.lint_repo.pins.check_manpages_toolchain(ctx)[source]¶

Check that a project opting into man pages locks a click-extra that renders.

The manpages job is release-only: it first runs on the commit that tags and publishes, where a failure costs the release its man-page asset for good, since a published release locks its asset list. Reading the floor off uv.lock on every ordinary push is what moves that answer forward of the one run nothing rehearses.

uv.lock is the subject rather than the pyproject.toml floor because the job installs with uv sync --frozen: the lock is what it gets. A project with no lock, or one whose lock never mentions click-extra, is indeterminate rather than failing, the same way a PAT-gated check reports a scope it could not read.

Return type:

CheckResult

repomatic.lint_repo.pins.check_inline_pins_match_upstream(ctx)[source]¶

Check inline upstream pins match the workflow uses: ref version.

A workflow that pins the upstream toolkit in a run: shell command (like uvx 'repomatic==1.2.3' show-metadata) must keep that version in lockstep with the SHA-pinned uses: refs. init realigns the inline pin whenever it writes the refs, so the two drift apart only when a ref is edited by hand, until the next sync-workflow-pins run. When the stale version drops a symbol the newer refs rely on, the metadata job fails and a release can publish to PyPI yet never tag (the toolkit chicken-and-egg). Flag the drift so the lint fails before a release does.

Reads the pins through inline_pin_re(), the matcher both rewriters use, so every pin flagged here is one they fix.

Return type:

CheckResult

repomatic.lint_repo.pins.check_self_pin_cooldown_exemption(ctx)[source]¶

Check every inline upstream pin carries its cooldown exemption.

A workflow pinning the upstream toolkit in a run: command (uvx 'repomatic==1.2.3' show-metadata) resolves under the workflow-wide UV_EXCLUDE_NEWER, and that pin moves in lockstep with the uses: refs, so it routinely names a release published hours ago. Without the exemption of cooldown_exemption() on the command line, uvx cannot resolve it at all. uvx reads no project configuration, so there is nowhere else the bypass could live.

The failure is total rather than partial, which is why this is worth a dedicated check: the pin usually sits in the metadata job, every other job is needs: metadata, and the whole workflow reports failure while executing nothing. Downstream repos are the exposed ones. tests/test_workflows.py pins the canonical workflows, sync-workflow-pins splices a missing flag in on any run that also moves the version, and a repo already pinned at the newest release falls through both.

Only flags a pin under a workflow that actually sets a cooldown: a repo without one has nothing to exempt.

Return type:

CheckResult

repomatic.lint_repo.pins.check_setup_uv_version_pin(ctx)[source]¶

Check every astral-sh/setup-uv step pins the uv version it installs.

[tool.uv] required-version is a floor for everyone; what a runner downloads is a separate question, and left to setup-uv the answer is “the newest release satisfying the floor”, installed seconds after it lands. That makes the tool enforcing every cooldown the one tool without one, so each step carries with: version: "X.Y.Z" and sync-workflow-pins walks it forward once a uv release clears minimum-release-age.

Steps naming two different versions in one repository are flagged too: the pin exists so every job resolves through the same uv, and a split fleet silently tests two.

Reads the parsed workflow rather than its text: a with: input is a plain mapping, so the step a pin belongs to is a fact the parser already knows. Matching the raw text instead means bounding a step’s block by hand, and a body running past its own step lets one pinned step vouch for every unpinned one above it.

Return type:

CheckResult

repomatic.lint_repo.pins.check_setup_uv_checksum_coverage(ctx)[source]¶

Check the pinned uv is one the pinned setup-uv can checksum-verify.

check_setup_uv_version_pin() settles that CI resolves through a uv somebody chose. Whether the bytes it downloads are the bytes that version shipped is a second question, and setup-uv answers it with a pinned hash only for the versions listed in the checksum table its own release bundles. Anything else installs with no verification before v10.1.0, and against a hash fetched at run time from v10.1.0 on (see setup_uv_verified_versions()). So a repository can hold two perfectly good pins that together pin no hash, which is what this reports.

Advisory, and not fatal for the same reason the pin check is not: the download succeeds and the job runs, it just carries a cooldown where it could have carried a cooldown and a pinned hash. sync-workflow-pins repairs it by stepping the uv pin back onto the table, and a sync-action-pins bump lets the pin move forward again (see repomatic.deps.sync._gate_uv_on_checksums).

Return type:

CheckResult

Returns:

A CheckResult, indeterminate when the table cannot be read.

repomatic.lint_repo.pins.check_registry_pin_cooldown(ctx, *, registry=None, now=None)[source]¶

Check that a repomatic run tool pinned inside the cooldown can install.

sync-tool-versions adopts a release only after it clears minimum-release-age, but a hand bump can pin a release still inside the window. The result depends on how repomatic run installs the tool, which ToolBackend records:

  • A virtualenv tool installs through uv commands that read the project’s [tool.uv] exclude-newer-package. A dated entry there admits the pin. When no entry admits it, the warning names the entry to add. The entry covers one repository, so a downstream repository that adopts the release inside the window needs its own entry, and gets the same warning.

  • A uvx or npm tool resolves its pin under the cooldown and reads no entry. No exemption in the repository can admit the pin, so the warning gives the date the install starts to work.

  • A binary tool is not checked. Its download verifies the registry checksum and applies no cooldown, so a pin inside the window installs, and no entry can admit it or hold it back. Listing its releases would also cost GitHub API calls on every run.

Advisory: the pins come with repomatic, and a downstream repository can act on the first case only. A tool whose datasource gives no date for its pinned version is reported as skipped, never as a failure.

Parameters:
  • ctx (LintContext) – The context. Its [tool.uv] exclude-newer-package holds the entries that admit a pin, and its minimum-release-age the cooldown.

  • registry (Mapping[str, ToolSpec] | None) – The tools to audit, keyed by name. The bundled tool registry when None.

  • now (datetime | None) – The current instant. Read from the clock when None.

Return type:

list[CheckResult]

Returns:

One result per pin inside the window, one for the pins past it, and one that names the tools without a release date.