CLI¶
Tip
Each [tool.repomatic] config option maps to CLI behavior. See the configuration reference for project-level defaults.
Help screen¶
$ repomatic --help
Usage: repomatic [OPTIONS] COMMAND [ARGS]...
Options:
--jobs [auto|max|INTEGER] Number of parallel jobs. Accepts an integer, auto
(the host's logical CPUs, minus one when there
are three or more) or max (all logical CPUs).
--jobs 0 runs sequentially. [default: auto]
-h, --help Show this message and exit.
Configuration options:
--config LOCATION Location of the configuration file. Supports
local path with glob patterns or remote URL.
[default: ~/.config/repomatic/]
--no-config Ignore all configuration files and only use
command line parameters and environment
variables.
--validate-config LOCATION Validate the configuration file and exit.
--export-config FORMAT Export the configuration in the selected format
to <stdout>, then exit.
Output options:
--accessible Accessibility mode: disable colors and render
tables in a borderless, screen-reader-friendly
format.
--color [auto|always|never] Colorize the output. A bare --color is the same
as --color=always. [default: auto]
--no-color Disable colorization (alias of --color=never).
--progress / --no-progress Show progress indicators during long operations.
Disabled for non-interactive output (pipes, dumb
terminals, CI) and by --accessible. [default:
progress]
--theme [auto|dark|dracula|light|manpage|monokai|nord|solarized-dark]
Color theme used for help screens. [default:
dark]
--table-format FORMAT Rendering style of tables. [default: rounded-
outline]
Logging options:
--verbosity LEVEL Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
[default: WARNING]
-v, --verbose Increase the default WARNING verbosity by one
level for each additional repetition of the
option. [default: 0]
-q, --quiet Decrease the default WARNING verbosity by one
level for each additional repetition of the
option. [default: 0]
--debug Shorthand for --verbosity DEBUG.
Introspection options:
--time / --no-time Measure and print elapsed execution time.
[default: no-time]
--params Show all CLI parameters, their provenance,
defaults and value, then exit.
--tree Show the tree of nested subcommands and exit.
--man Read the command's manual page and exit.
--help-format [carapace|json|json-full|man|markdown|markdown-full]
Render the command in the given format and exit.
--version Show the version and exit.
Project setup:
init Bootstrap a repository to use reusable workflows
list-skills List available Claude Code skills
show-config Print [tool.repomatic] configuration reference
show-metadata Print repository and CI state as key/value pairs for
workflows
show-test-matrix Render the CI test matrix as a grid
update-dep-graph Generate dependency graph from uv lockfile
Linting & checks:
audit Report (and optionally fix) vulnerable dependencies
fix-awesome-toc Remove the table-of-contents entries awesome-lint
rejects
format-images Format images with lossless optimization
lint-changelog Check changelog dates against release dates
lint-deps Check dependencies resolve from the public index
lint-repo Check repository files against repomatic conventions
Sync:
sync-action-pins Bump SHA-pinned GitHub Actions to their latest release
sync-binaries Regenerate the binaries catalog page
sync-bumpversion Sync bumpversion config from bundled template
sync-dep-sources Swap git-tracked dependencies to their released versions
sync-deps Update dependencies, all or a named subset
sync-dev-release Sync rolling dev pre-release on GitHub
sync-github-releases Sync GitHub release notes from changelog
sync-gitignore Sync .gitignore from gitignore.io templates
sync-labels Sync repository labels via labelmaker
sync-mailmap Sync Git's .mailmap file with missing contributors
sync-runner-images Move runner images forward as GitHub retires and
supersedes them
sync-tool-versions Bump registry tool versions from upstream releases
sync-uv-lock Re-lock dependencies and roll cooldown overrides forward
sync-workflow-pins Bump npm/PyPI version literals in workflow YAML
Release & versioning:
bump-version Bump a version part and sync its pull request
changelog Maintain a Markdown-formatted changelog
create-release Create the GitHub release draft of a version
git-tag Create and push a Git tag
pack-attestation Name an attestation bundle after the asset it attests
pack-binaries Pack compiled binaries and their versionless aliases
pack-manpages Pack the rendered man pages as a release tarball
pack-plugin Pack the skills and agents as a Claude Code plugin
prepare-release Freeze version, changelog and pins for a release
scan-virustotal Upload release binaries to VirusTotal
squashed-release Report a release pull request merged by squashing
verify-binary Verify binary architecture and OS floor
wait-pypi Wait until PyPI serves a release just published
GitHub issues & PRs:
apply-labels Label an issue or PR from its content and changed files
broken-links Check links, and manage the broken links issue
lock-threads Lock closed, inactive issues and PRs
pr-body Generate PR body with workflow metadata
pr-sync Create, refresh or retire an automation PR
setup-guide Manage setup guide issue lifecycle
sponsor-label Label issues/PRs from GitHub sponsors
unsubscribe-threads Unsubscribe from closed, inactive notification threads
CI & runners:
cancel-runs Cancel in-progress workflow runs for a branch
ci-status Report which CI jobs are red, and which of them gate a
merge
job-timings Measure how long each runner image takes, from finished
runs
Site & docs:
cloudflare-pages Create, check or update the Cloudflare Pages project
cloudflare-r2 Serve site files over the Pages size limit from
Cloudflare R2
update-docs Regenerate Sphinx API docs and dynamic content
Forge sampling:
sample-metrics Record what forges say about the repositories this
project tracks
Tools:
cache Manage the download cache
run Run a registered external tool, pinned and checksum-
verified
update-checksums Recompute SHA-256 checksums for the binary tool registry
Other commands:
help Show help for a command.
repomatic apply-labels¶
$ repomatic apply-labels --help
Usage: repomatic apply-labels [OPTIONS]
Label a freshly opened issue or pull request from the project's rules.
Two rule families, both tables under `[tool.repomatic.labels]` mapping a label
to the patterns that apply it, overlaid on the bundled defaults:
content-rules keywords or /regex/flags matched against the title and
body, of an issue or a pull request alike
file-rules globs matched against the paths a pull request changes
Additive only. A label already on the thread stays, and none is ever removed,
so a classification made by hand survives every later run.
This pre-labels for the maintainer's first pass and never replaces it, so the
rules are tuned for precision: a missing label costs one click, a wrong one is
noise on every issue that trips it.
Requires the gh CLI to be authenticated.
Options:
--number INTEGER RANGE Issue or PR number. Defaults to the number in
$GITHUB_EVENT_PATH. [x>=1]
--pr / --issue Specify issue or pull request. Auto-detected from
$GITHUB_EVENT_PATH.
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote of the
current clone.
--dry-run / --live Report what would be done without making changes.
[default: dry-run]
-h, --help Show this message and exit.
Examples:
Preview what the current event's issue or PR would earn:
$ repomatic apply-labels
Apply them, as the labeller job does:
$ repomatic apply-labels --live
Manual invocation against one pull request:
$ repomatic apply-labels --live --pr --number 42
repomatic audit¶
$ repomatic audit --help
Usage: repomatic audit [OPTIONS]
Scan locked dependencies for known security vulnerabilities.
Read-only by default: queries every advisory database enabled in
[tool.repomatic] vulnerable-deps.sources (default: uv-audit and
github-advisories), unions and deduplicates the results, and prints
them. The GitHub Advisory Database needs a repository, so it is skipped
without --repo. The table respects the global --table-format option
(github, json, csv, etc.), so --table-format json yields a
machine-readable report. Report mode exits 1 when any vulnerability is
found (use --exit-zero to override), so it can gate CI.
With --fix, upgrades each fixable package with uv lock --upgrade-package
and:
- bypasses the exclude-newer cooldown for security fixes
- persists exclude-newer-package entries in pyproject.toml
- prints a markdown report of vulnerabilities and version changes
Options:
--lockfile FILE Path to the uv.lock file. [default: uv.lock]
--repo TEXT Repository in owner/repo format, for the GitHub
Advisory Database source. Defaults to
$GITHUB_REPOSITORY.
--fix / --no-fix Upgrade fixable packages and persist cooldown
exemptions (mutates uv.lock and pyproject.toml).
Default: report only. [default: no-fix]
--exit-zero / --no-exit-zero In report mode, exit 0 even when vulnerabilities
are found. [default: no-exit-zero]
-o, --output FILE Write a markdown report to this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
--sort-by [package|version|advisory|fixed|sources]
Sort table by this column. Repeat to set
priority. [default: package]
-h, --help Show this message and exit.
Examples:
Report known vulnerabilities (read-only):
$ repomatic audit
Machine-readable output:
$ repomatic --table-format json audit
Upgrade fixable packages (mutates uv.lock and pyproject.toml):
$ repomatic audit --fix
CI autofix job: write the markdown report as a step output:
$ repomatic audit --fix --repo owner/name --output "$GITHUB_OUTPUT" --output-format github-actions
repomatic broken-links¶
$ repomatic broken-links --help
Usage: repomatic broken-links [OPTIONS]
Check the documentation links, and manage the broken links issue.
Crawls the documentation files with lychee, then combines its report with the
Sphinx linkcheck output into a single "Broken links" issue. Creates or updates
the issue when a checker found broken links, and closes it when every checker
that ran completed clean. A checker that did not complete leaves the issue as
it is. The repository name selects the labels the issue carries.
Requires the gh CLI to be authenticated. lychee reads $GITHUB_TOKEN to lift
GitHub's rate limit on the links it checks there.
In GitHub Actions, most options are auto-detected:
- --repo-name defaults to $GITHUB_REPOSITORY name component.
- --output-json defaults to ./docs/_linkcheck/output.json if it exists.
- --source-url is composed from $GITHUB_SERVER_URL, $GITHUB_REPOSITORY,
and $GITHUB_SHA when --output-json is set.
Options:
--lychee / --no-lychee Crawl the documentation files with lychee, as
`repomatic run lychee` does. Skipped when the
repository holds none. A crawl that does not complete
leaves the issue as it is. [default: lychee]
--output-json FILE Path to Sphinx linkcheck output.json file.
--source-url TEXT Base URL for linking filenames and line numbers in the
Sphinx report. Example:
https://github.com/owner/repo/blob/<sha>/docs
--repo-name TEXT Repository name. Defaults to the name component of
$GITHUB_REPOSITORY.
-h, --help Show this message and exit.
Examples:
In GitHub Actions, with every default auto-detected:
$ repomatic broken-links
Report the Sphinx linkcheck output alone:
$ repomatic broken-links --no-lychee --repo-name "my-repo"
repomatic bump-version¶
$ repomatic bump-version --help
Usage: repomatic bump-version [OPTIONS]
Bump a version part and converge its draft pull request.
When the bump is allowed, bumps the part with bump-my-version, re-locks
uv.lock, then opens or refreshes the draft pull request on the <part>-version-
increment branch, rendered from the bump-version template.
When it is not, because the version already moved past that part since the
last release, closes the pull request an earlier run left open, and deletes
its branch.
Requires the gh CLI to be authenticated.
Options:
--part [minor|major] The version part to bump. [required]
-h, --help Show this message and exit.
Examples:
Bump the minor version, or retire a stale minor bump:
$ repomatic bump-version --part minor
repomatic cache¶
$ repomatic cache --help
Usage: repomatic cache [OPTIONS] COMMAND [ARGS]...
Manage the local download cache.
Binary tools, HTTP API responses and generated tool configs are cached to
avoid redundant downloads. This group provides subcommands to inspect, clean,
and locate the cache.
Options:
-h, --help Show this message and exit.
Commands:
clean Remove cached entries
help Show help for a command.
path Print the cache directory path
show List cached entries
repomatic cache clean¶
$ repomatic cache clean --help
Usage: repomatic cache clean [OPTIONS]
Remove cached binaries, tool configs and HTTP responses.
Without options, removes everything. Use --tool to target a specific binary
tool and its cached config, --namespace for a specific HTTP namespace, or
--max-age for entries older than a threshold.
Options:
--tool TEXT Only remove the binary and config entries for this tool.
--namespace TEXT Only remove HTTP entries in this namespace, like pypi or
github-release-tags.
--max-age INTEGER Only remove entries older than this many days.
-h, --help Show this message and exit.
Examples:
Drop every cached download:
$ repomatic cache clean
Only one tool's entries:
$ repomatic cache clean --tool ruff
Only one namespace:
$ repomatic cache clean --namespace pypi
Only entries older than a week:
$ repomatic cache clean --max-age 7
repomatic cache help¶
$ repomatic cache help --help
Usage: repomatic cache help [OPTIONS] [COMMAND_PATH]...
Show help for a command.
Options:
--search TEXT Search all subcommands for matching options or descriptions.
-h, --help Show this message and exit.
repomatic cache path¶
$ repomatic cache path --help
Usage: repomatic cache path [OPTIONS]
Print the absolute path to the cache directory.
Useful for CI integration with actions/cache or similar tools.
Options:
-h, --help Show this message and exit.
repomatic cache show¶
$ repomatic cache show --help
Usage: repomatic cache show [OPTIONS]
List all cached binaries, HTTP responses and tool configs.
Options:
--sort-by [type|name|detail|size|age]
Sort table by this column. Repeat to set priority. [default:
name]
-h, --help Show this message and exit.
repomatic cancel-runs¶
$ repomatic cancel-runs --help
Usage: repomatic cancel-runs [OPTIONS]
Cancel the in-progress and queued workflow runs of a branch.
Fired when a pull request closes: GitHub does not cancel PR-triggered runs on
close, so the branch's live runs would burn CI minutes to completion. The
repository is resolved by the gh CLI from GH_REPO or the current checkout.
Options:
--branch TEXT Head branch whose in-progress and queued runs to
cancel. [required]
--current-run-id TEXT Run ID to spare (the cancelling run itself). Defaults
to $GITHUB_RUN_ID. [default: ""]
-h, --help Show this message and exit.
Examples:
From the cancel-runs workflow, sparing its own run:
$ repomatic cancel-runs --branch "$BRANCH"
repomatic changelog¶
$ repomatic changelog --help
Usage: repomatic changelog [OPTIONS] [OUTPUT]
Add an unreleased section for the current version to the changelog.
Writes the result back to the changelog, unless OUTPUT names another file.
Pass - as OUTPUT to print the result instead.
Options:
--changelog FILE Path to the changelog file. Defaults to
[tool.repomatic] changelog.location.
--default-branch TEXT Branch name the unreleased comparison URL points at.
[default: main]
-h, --help Show this message and exit.
Examples:
Open the next release's section, in place:
$ repomatic changelog
Print the result instead:
$ repomatic changelog -
repomatic ci-status¶
$ repomatic ci-status --help
Usage: repomatic ci-status [OPTIONS]
Report the latest CI run of each workflow, and what is actually broken.
Reads jobs rather than runs, so a crashed allowed-failure probe cannot hide
inside a green run conclusion and a run still reading "queued" cannot hide the
dozen jobs of it that already finished.
A job whose name carries the unstable glyph anywhere is allowed to fail and
never affects the exit code. Every other job is required, including the non-
matrix ones that carry no glyph at all. A matrix job whose name still holds
its template never evaluated: no cell of it ran.
A run that was cancelled, or that ran no job, is reported as such and never as
green: it has no result for its commit. A workflow that ran no job on the tip
is read on the last commit whose run of it was not skipped.
--wait polls in-process, at --interval, and ends on the first failed required
job rather than at the end of the slowest matrix: that is the moment to act.
--until-change and --state-file turn it into a watch that a scheduler re-arms,
waking once per event. --failed-logs then fetches the logs to read, one file
per failed job.
Options:
--branch TEXT Branch whose latest run of each workflow to read.
[default: main]
--workflow WORKFLOW Workflow file to read, repeatable. Defaults to every
workflow a push can start, derived from
.github/workflows/.
--fatal / --no-fatal Exit non-zero when a required job failed. [default:
fatal]
--wait / --no-wait Poll until a required job fails, or until every run
settled and the tip has a run of its own. Each poll
prints the runs whose verdict changed. [default: no-
wait]
--interval FLOAT RANGE Seconds between two polls under --wait. [default:
60; x>=5]
--until-change Under --wait, stop after the first poll reporting a
verdict the state file has not seen, so a re-armed
watch wakes once per event.
--state-file FILE JSON file of the verdicts already reported: read
before the first poll, written on every change.
--timeout FLOAT RANGE Seconds after which --wait gives up, 0 for no limit.
[default: 0; x>=0]
--failed-logs DIRECTORY Write the log of every failed required job into this
directory, control sequences stripped. A settled
job's log is readable while its run goes.
--automation-prs Also list the open pull requests of the automation,
with how many commits each one lags its base.
--release-pr Also report the open release pull request: its draft
state, head and how many commits it lags the branch.
--sort-by [workflow|commit|run-status|verdict]
Sort table by this column. Repeat to set priority.
[default: workflow]
-h, --help Show this message and exit.
Examples:
What is red on main right now:
$ repomatic ci-status
One workflow, without failing the shell:
$ repomatic ci-status --workflow tests.yaml --no-fatal
repomatic cloudflare-pages¶
$ repomatic cloudflare-pages --help
Usage: repomatic cloudflare-pages [OPTIONS]
Reconcile the Cloudflare Pages project against the declared state.
A Direct Upload project's live settings (compatibility date, Smart Placement,
build image, attached source) exist only server-side, where they drift with
nothing watching. This command diffs them against the `[tool.repomatic]
site.*` declarations, enforces them, and warns when the API token is within a
month of its expiry, which Cloudflare itself never signals.
Credentials come from CLOUDFLARE_API_TOKEN, falling back to the OAuth token a
local `wrangler login` stored. The account is derived from the credential at
run time, never declared beside it.
Options:
--project TEXT Cloudflare Pages project to reconcile. Defaults to
[tool.repomatic] site.cloudflare-project, then to the
repository name.
--check Diff the live project against the declared state; exit
1 on drift.
--apply Write the declared values back to the live project.
--dump Print the live project state as JSON, secrets
redacted.
--create Create the Direct Upload project when missing, then
apply the declared values: the rebuild-from-nothing
verb. An existing project is reused and reconciled, so
re-running is safe.
--attach-domain DOMAIN Serve the project at DOMAIN, creating the proxied
CNAME it needs. The API attaches a hostname without
any DNS, unlike the dashboard, leaving the domain
pending forever; this does both.
-h, --help Show this message and exit.
Examples:
In CI: fail the job when the live project drifted:
$ repomatic cloudflare-pages --check
Write the declared compatibility date and placement back:
$ repomatic cloudflare-pages --apply
Create the project if missing; an existing one is reconciled, not re-created:
$ repomatic cloudflare-pages --create --project my-site
Serve the project at a custom domain, DNS record included:
$ repomatic cloudflare-pages --attach-domain example.com
repomatic cloudflare-r2¶
$ repomatic cloudflare-r2 --help
Usage: repomatic cloudflare-r2 [OPTIONS]
Serve a static site's files over the Pages size limit from Cloudflare R2.
Cloudflare Pages Direct Upload rejects any file over 25 MiB. --offload moves
each such file from the built site to the bucket that [tool.repomatic]
site.cloudflare-r2-bucket declares, and redirects its path to the copy.
Without a bucket, or when a file cannot move, the file is dropped with an
error annotation and the command exits 1. The rest of the tree stays ready to
deploy, so everything else can still publish.
Uploads use a key pair limited to the bucket, from CLOUDFLARE_R2_ACCESS_KEY_ID
and CLOUDFLARE_R2_SECRET_ACCESS_KEY. --create and --check manage the bucket
through the REST API, with CLOUDFLARE_API_TOKEN or a local `wrangler login`.
The account resolves from the credential, never from a declared identifier.
Options:
--project TEXT Cloudflare Pages project of the site, which resolves the
account. Defaults to [tool.repomatic] site.cloudflare-
project, then to the repository name.
--offload DIRECTORY Move every file over 25 MiB out of the built site in
DIRECTORY, to the bucket, and redirect its path there in
DIRECTORY/_redirects. Without a bucket, drop the file
with an error. Exits 1 when it drops a file, with the
rest of DIRECTORY still ready to deploy.
--create Create the bucket when missing, attach the domain with
TLS 1.2 at least, and turn the r2.dev URL off. Re-running
is safe.
--check Compare the live bucket against the declared state; exit
1 on drift.
-o, --output FILE Write the --offload table, one row per file over the
limit, to this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions writes step
outputs, for $GITHUB_OUTPUT. [default: markdown]
-h, --help Show this message and exit.
Examples:
In CI, between the build and `wrangler pages deploy`:
$ repomatic cloudflare-r2 --offload ./docs/_build
Write the offload table to the step summary of a GitHub Actions run:
$ repomatic cloudflare-r2 --offload ./docs/_build --output "$GITHUB_STEP_SUMMARY"
Create the bucket and attach its domain, or converge an existing one:
$ repomatic cloudflare-r2 --create
Compare the live bucket against the declared state:
$ repomatic cloudflare-r2 --check
repomatic create-release¶
$ repomatic create-release --help
Usage: repomatic create-release [OPTIONS]
Create the release draft of a version, with its notes and assets.
The notes are the changelog section of the version. A project published on
PyPI gets them with the availability admonition linking to PyPI and GitHub,
which lint-changelog later writes into the changelog itself.
The release stays a draft: the release workflow attaches the binaries and
other assets to it, then publishes it last, since a published immutable
release accepts no new asset.
Idempotent: with --skip-existing, the default, a release that already carries
the tag is left as it is, so a re-run of the workflow passes.
Options:
--version TEXT Version to release, like 1.2.3. The release takes the tag
v1.2.3. [required]
--commit TEXT Commit the release tag points at. Defaults to HEAD.
--assets DIRECTORY Directory of files to attach to the draft. A directory
that does not exist attaches nothing.
--skip-existing / --error-existing
Skip silently if a release carries the tag, or fail with
an error. [default: skip-existing]
--changelog FILE Path to the changelog file. Defaults to [tool.repomatic]
changelog.location.
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote of the
current clone.
-h, --help Show this message and exit.
Examples:
Create the draft of the release commit, attaching the built package:
$ repomatic create-release --version 1.2.3 --commit 6f27db4 --assets release_artifact
repomatic fix-awesome-toc¶
$ repomatic fix-awesome-toc --help
Usage: repomatic fix-awesome-toc [OPTIONS]
Remove the table-of-contents entries awesome-lint forbids.
Deletes the Contents, Contributing, Footnotes and Related Lists entries from
the mdformat-toc block of readme.md and of every readme.{lang}.md translation
beside it.
A translation names those sections in its own language, so they are
matched by their position in the heading sequence of readme.md rather
than by name.
Run it right after mdformat regenerates the ToC: mdformat-toc lists every
heading it finds and has no way to leave one out.
Options:
-h, --help Show this message and exit.
Examples:
Fix the readme and every translation beside it:
$ repomatic fix-awesome-toc
repomatic format-images¶
$ repomatic format-images --help
Usage: repomatic format-images [OPTIONS]
Format images by losslessly optimizing them with external CLI tools.
Discovers PNG and JPEG files and compresses them losslessly in-place using
oxipng and jpegoptim. Produces a markdown summary table showing before/after
sizes and savings.
Only lossless optimizers are used so that results are idempotent: running the
command twice produces no further changes.
Required tools:
oxipng is downloaded and checksum-verified from the pinned tool
registry, once per run. jpegoptim has to be on $PATH:
sudo apt-get install jpegoptim
Options:
--min-savings FLOAT RANGE Minimum percentage savings to keep an optimized
file. [default: 5; 0<=x<=100]
--min-savings-bytes INTEGER RANGE
Minimum absolute byte savings to keep an optimized
file. [default: 1024; x>=0]
-o, --output FILE Write the summary table to this file. [default: -]
--output-format [markdown|github-actions]
Format of the --output file. github-actions writes
step outputs, for $GITHUB_OUTPUT. [default:
markdown]
-h, --help Show this message and exit.
Examples:
Format images and print summary:
$ repomatic format-images
CI: write as a GitHub Actions step output:
$ repomatic format-images --output "$GITHUB_OUTPUT" --output-format github-actions
Use a 10% minimum savings threshold:
$ repomatic format-images --min-savings 10
repomatic git-tag¶
$ repomatic git-tag --help
Usage: repomatic git-tag [OPTIONS]
Create and optionally push a Git tag.
This command is idempotent: if the tag already exists and --skip-existing is
used, it exits successfully without making changes. This allows safe re-runs
of workflows interrupted after tag creation.
Options:
--tag TEXT Tag name to create (e.g., v1.2.3). [required]
--commit TEXT Commit to tag. Defaults to HEAD.
--push / --no-push Push the tag to remote after creation. [default: push]
--skip-existing / --error-existing
Skip silently if tag exists, or fail with an error.
[default: skip-existing]
-o, --output FILE Write created=true or created=false to this file, like
$GITHUB_OUTPUT.
-h, --help Show this message and exit.
Examples:
Create and push a tag:
$ repomatic git-tag --tag v1.2.3
Tag a specific commit:
$ repomatic git-tag --tag v1.2.3 --commit abc123def
Create tag without pushing:
$ repomatic git-tag --tag v1.2.3 --no-push
Fail if tag exists:
$ repomatic git-tag --tag v1.2.3 --error-existing
Output result for GitHub Actions:
$ repomatic git-tag --tag v1.2.3 --output "$GITHUB_OUTPUT"
repomatic help¶
$ repomatic help --help
Usage: repomatic help [OPTIONS] [COMMAND_PATH]...
Show help for a command.
Options:
--search TEXT Search all subcommands for matching options or descriptions.
-h, --help Show this message and exit.
repomatic init¶
$ repomatic init --help
Usage: repomatic init [OPTIONS] [COMPONENT[/FILE]]...
Bootstrap a repository to use reusable workflows from kdeldycke/repomatic.
With no arguments, generates thin-caller workflow files, exports configuration
files (labels), and creates a minimal changelog. Specify COMPONENTS to
initialize only selected parts.
Scope restrictions (awesome-only, non-awesome) and [tool.repomatic] exclude
entries only apply during bare init (no arguments). Explicitly naming a
component bypasses scope, allowing workflows to materialize out-of-scope
configs at runtime.
Selectors use the same syntax as the exclude config in [tool.repomatic]: bare
names select an entire component, qualified component/file entries select a
single file.
The derived upstream pin honors the [tool.repomatic] minimum-release-age
cooldown when it would adopt a release newer than the one already pinned in
this repository: if the running repomatic version is still inside that window,
the workflow pin steps back to the newest release that has cleared it, and
never below the pin already on disk. Re-running init at the pinned version
leaves it untouched. Pass --no-cooldown to pin the running version
immediately, or --version to pin an exact tag.
--upgrade runs init as the newest release past that window instead, and hands
off to it through uvx when it is not the running one: the upstream pin and
every managed file then move in one run. With --output, it writes a report of
the move for the upgrade pull request.
Components:
labels Label definitions for labelmaker (labels.toml)
publish-pypi-action Composite action that publishes to PyPI via Trusted Publishing (.github/actions/publish-pypi/)
subagents Agent subagent definitions (.claude/agents/)
skills Claude Code skill definitions (.claude/skills/)
workflows Thin-caller workflow files
awesome-template Boilerplate for awesome-* repositories
changelog Minimal changelog.md
plugin Claude Code plugin marketplace wiring (.claude/settings.json)
uv uv resolver pin and dependency cooldown policy
lychee Lychee link checker configuration
ruff Ruff linter/formatter configuration
pytest Pytest test configuration
coverage Coverage.py measurement and reporting configuration
mypy Mypy type checking configuration
mdformat mdformat Markdown formatter configuration
bumpversion bump-my-version configuration
typos Typos spell checker configuration
File-level selectors (labels, publish-pypi-action, subagents, skills, workflows):
workflows/autofix.yaml A single workflow
skills/repomatic-topics A single skill
labels/labels.toml A single label config file
Options:
--version TEXT Version pin for upstream workflows (e.g.,
v5.10.0). Defaults to the latest release derived
from the package version.
--cooldown / --no-cooldown When adopting a repomatic release newer than the
one this repository already pins, hold the
upstream pin back to the newest release past the
[tool.repomatic] minimum-release-age window. Never
moves a pin at or above the running version. --no-
cooldown pins the running repomatic version
immediately. Ignored when --version is set.
[default: cooldown]
--upstream-repo TEXT Upstream repository containing reusable workflows.
[default: kdeldycke/repomatic]
--output-dir DIRECTORY Root directory of the target repository.
[default: .]
--delete-excluded Delete files that are excluded by config but still
on disk.
--delete-unmodified Delete config files identical to bundled defaults.
--keep-removed Keep orphaned files of assets repomatic no longer
ships (report them instead of auto-pruning).
--delete-removed-modified Also delete orphaned files of removed assets that
were modified locally (normally reported for
manual review, never deleted).
--upgrade Run as the newest repomatic release past the
[tool.repomatic] minimum-release-age window, never
below the release already pinned, so the upstream
pin and every managed file move together. Hands
off to that release through uvx when it is not the
running one. Overrides --cooldown when it picks a
release, and takes no COMPONENTS and no --version.
-o, --output FILE Write the report of the move to this file, when
--upgrade moves the pin.
--output-format [markdown|github-actions]
Format of the --output file. github-actions writes
step outputs, for $GITHUB_OUTPUT. [default:
markdown]
-h, --help Show this message and exit.
Examples:
Full bootstrap (workflows + labels + changelog):
$ repomatic init
Pin to a specific version:
$ repomatic init --version v5.9.1
Adopt the running version now, skipping the release-age cooldown:
$ repomatic init --no-cooldown
Upgrade to the newest release past the release-age cooldown:
$ repomatic init --upgrade
Install a single skill:
$ repomatic init skills/repomatic-topics
One workflow + all labels:
$ repomatic init workflows/autofix.yaml labels
Only merge ruff config into pyproject.toml:
$ repomatic init ruff
Multiple components:
$ repomatic init ruff bumpversion
repomatic job-timings¶
$ repomatic job-timings --help
Usage: repomatic job-timings [OPTIONS]
Report median whole-job wall-clock per runner image.
Runner choice rests on measurement, and the measurement that matters is the
whole job: a benchmark that times only the tool pass misses checkout and
install. The jobs API reports start and end timestamps, so what this reads is
whole-job by construction.
Only successful runs are sampled, because a failed run's jobs stop early and
time where the failure landed rather than what the image costs. The figure is
a median across several runs, which is what turns a queue stall into noise
instead of a verdict.
Options:
--workflow WORKFLOW Workflow file whose runs to sample, from
.github/workflows/. [default: tests.yaml]
--branch TEXT Branch whose runs to sample. [default: main]
--limit INTEGER How many recent successful runs to sample. [default: 5]
-o, --output FILE Write the report as a Markdown table to this file, for
documentation.
--sort-by [runner|jobs|median|slowest-job|slowest]
Sort table by this column. Repeat to set priority.
[default: median]
-h, --help Show this message and exit.
Examples:
Which image is holding the matrix up:
$ repomatic job-timings
A wider sample, written out for documentation:
$ repomatic job-timings --limit 10 --output timings.md
repomatic lint-changelog¶
$ repomatic lint-changelog --help
Usage: repomatic lint-changelog [OPTIONS]
Verify that changelog release dates match canonical release dates.
Uses PyPI upload dates as the canonical reference when the project is
published to PyPI. Falls back to git tag dates for non-PyPI projects.
PyPI timestamps are immutable and reflect the actual publication date, making
them more reliable than git tags which can be recreated.
Also detects orphaned versions: versions that exist as git tags, GitHub
releases, or PyPI packages but have no corresponding changelog entry. Orphans
cause a non-zero exit code.
Reads pypi-package-history from [tool.repomatic] to fetch releases published
under former package names (for renamed projects).
Reads abandoned-versions from [tool.repomatic] to skip "not found on PyPI"
warnings for releases that were frozen but never published (skip-and-move-
forward releases).
Reads changelog.bullet-word-threshold from [tool.repomatic] to warn, non-
fatally, about unreleased changelog bullets longer than that many words. A
changelog entry is a release note, not a commit message.
Warns, non-fatally, about a released section holding no entry: a published
release heading with nothing under it reads as broken to anyone scanning the
notes for that version.
Warns, non-fatally, about an unreleased entry marked Breaking or Deprecated
that follows an unmarked one, and about an unreleased entry naming a #N that
is no issue or pull request of the repository.
Fails on a heading writing its version with the v of a git tag, which no check
reads. --fix strips the prefix instead.
Output symbols:
✓ Dates match
⚠ Version not found on reference source (warning, non-fatal)
✗ Date mismatch (error, fatal)
With --fix, the command also:
- Corrects mismatched dates to match the canonical source.
- Strips the v tag prefix off a heading.
- Adds a PyPI link admonition under each released version.
- Adds a CAUTION admonition for yanked releases.
- Adds a WARNING admonition for versions not on PyPI.
- Inserts placeholder sections for orphaned versions.
Exit codes:
0 All dates match, or --fix corrected the file.
1 Date mismatch or orphan detected without --fix.
2 Sanity gate refused to rewrite: upstream lookup (PyPI or
GitHub Releases) looks unhealthy and the existing changelog
has substantial coverage that would be silently stripped.
Re-run when the API is reachable.
Options:
--changelog FILE Path to the changelog file. Defaults to [tool.repomatic]
changelog.location.
--package TEXT PyPI package name for date lookups. Auto-detected from
pyproject.toml.
--fix Fix date mismatches and add PyPI admonitions to the
changelog.
-h, --help Show this message and exit.
Examples:
Check the default changelog.md (auto-detects PyPI package):
$ repomatic lint-changelog
Fix dates and add admonitions:
$ repomatic lint-changelog --fix
Explicit package name:
$ repomatic lint-changelog --package repomatic
repomatic lint-deps¶
$ repomatic lint-deps --help
Usage: repomatic lint-deps [OPTIONS]
Check that every dependency resolves from the index users install from.
A dependency is shippable when whoever installs the published artifact gets
the same code the release was tested against. A git branch, a local path, a
fork, a direct URL or a private index all break that, and most of them break
it silently: a `[tool.uv.sources]` override never reaches the published
metadata, so the wheel builds and uploads exactly as it would have, and only
the install fails.
Runs entirely offline, reading pyproject.toml and uv.lock. The lockfile pass
is what catches a source override on a package no table names, since it
records the resolved origin of the whole tree.
Reads lint-deps.allow from [tool.repomatic] for packages exempted by name,
each mapped to the reason it is safe, and lint-deps.comment-word-threshold for
the length a floor comment may run to.
Output symbols:
✗ Blocks a release
⚠ Warning, does not block
ℹ Covered by lint-deps.allow
Exit codes:
0 Nothing blocks a release, or --no-fatal was passed.
1 At least one finding blocks a release.
Options:
--pyproject FILE Path to the pyproject.toml file. [default:
pyproject.toml]
--lockfile FILE Path to the uv.lock file. [default: uv.lock]
--fatal / --no-fatal Exit non-zero when a finding blocks a release. Pass
--no-fatal to report without failing, for continuous
visibility on ordinary pushes. [default: fatal]
--policy / --no-policy Also report declarations departing from the project's
version policy: upper bounds, missing floors, unsorted
lists, misplaced type stubs, uncommented and over-long
floor comments. Never blocks a release. [default:
policy]
-o, --output FILE Write a markdown report of the blocking findings to
this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions writes
step outputs, for $GITHUB_OUTPUT. [default: markdown]
--sort-by [package|kind|location|verdict]
Sort table by this column. Repeat to set priority.
[default: package]
-h, --help Show this message and exit.
Examples:
Check the current project:
$ repomatic lint-deps
Report without failing, for an ordinary CI push:
$ repomatic lint-deps --no-fatal
Emit a markdown report for a PR body:
$ repomatic lint-deps --no-fatal --output report.md
repomatic lint-repo¶
$ repomatic lint-repo --help
Usage: repomatic lint-repo [OPTIONS]
Run consistency checks on repository metadata.
Reads package_name, is_sphinx, and project_description from pyproject.toml in
the current directory.
Checks, in report order. An error fails the command, a warning never does:
- Package name matches the repository name (warning).
- A Sphinx project's website field names the documentation URL declared in
[project.urls] (warning).
- GitHub Pages publishes from GitHub Actions, when site.deploy targets
GitHub Pages (warning).
- CLOUDFLARE_API_TOKEN secret set, when site.deploy targets Cloudflare
Pages (warning).
- CLOUDFLARE_R2_ACCESS_KEY_ID and CLOUDFLARE_R2_SECRET_ACCESS_KEY secrets
set, when site.cloudflare-r2-bucket is declared (warning).
- Legacy github.io URLs still redirect, for a site moved to Cloudflare
Pages (warning).
- Committed _redirects files survive the Cloudflare Pages engine: no
dropped rules, no silent budget abort (error).
- wrangler.toml agrees with the declared Cloudflare project name and
compatibility date (warning).
- No tracked file over the 25 MiB Cloudflare Pages limit, unless an R2
bucket is declared to serve it (warning).
- No leftover gh-pages branch in a Sphinx project (warning).
- Repository description matches the project description (error).
- GitHub topics are a subset of the pyproject.toml keywords (warning).
- Funding file present when the owner has GitHub Sponsors (warning).
- No stale draft release, whose tag is not a .dev0 (warning).
- Every repository label is declared by a configured label source
(warning).
- Install guide download URLs resolve to real release assets (warning).
- No active tag ruleset that can block a release tag push (warning).
- At least one active branch ruleset (warning).
- No classic branch protection rule beside the rulesets (warning).
- Immutable releases enabled, for a repository publishing releases
(warning).
- Fork PR workflow approval policy strict enough (warning).
- Actions required to be pinned to a full-length commit SHA (warning).
- The latest PyPI release's provenance names this repository's
release.yaml (warning).
- Workflows and reusable-workflow callers declare their permissions
(warning).
- Every standalone workflow can be started by hand (warning).
- Thin callers pin the upstream workflows to a release, not to @main
(warning).
- Thin callers carry the triggers of the workflow they call (warning).
- Thin callers pass every secret the workflow they call declares
(warning).
- Every test-matrix exclude entry names a value on some matrix axis
(warning).
- Python classifiers, requires-python and the workflow test matrices agree
(warning).
- No job runs on a -latest alias or on an image outside the test matrices
(warning).
- Each release-only step tests the capability it needs, and runs on a
release commit (warning).
- The manpages.script lockfile pins a click-extra able to render man pages
(warning).
- Seeded tool configs carry every bundled template entry, or decline it
with a reason (warning).
- No bare [tool.lychee] exclude entry the bundled template now anchors
(warning).
- Inline upstream pins match the version the uses: refs name (error).
- Inline upstream pins resolving under a cooldown carry their
--exclude-newer-package exemption (error).
- Every astral-sh/setup-uv step pins one uv version (warning).
- The pinned uv carries a checksum in the pinned astral-sh/setup-uv
(warning).
- Every repomatic run tool pin is past the cooldown, or an
exclude-newer-package entry admits it (warning).
- Workflows only ask repomatic show-metadata for keys it still emits
(error).
- Repository-local PR body templates sit in .github/pr-templates/ and
carry valid frontmatter (warning).
- VIRUSTOTAL_API_KEY secret set, when Nuitka is active (warning).
- REPOMATIC_NOTIFICATIONS_PAT secret set, when the unsubscribe workflow is
enabled (warning).
- With a PAT, the Administration, Contents, Issues, Pull requests,
Dependabot alerts and Workflows permissions of REPOMATIC_PAT (error).
- With a PAT, a REPOMATIC_PAT limited to this repository (warning).
Options:
--repo-name TEXT Repository name. Defaults to the name component of
$GITHUB_REPOSITORY.
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY.
--has-cloudflare-api-token Whether CLOUDFLARE_API_TOKEN is configured.
--has-cloudflare-r2-keys Whether CLOUDFLARE_R2_ACCESS_KEY_ID and
CLOUDFLARE_R2_SECRET_ACCESS_KEY are both
configured.
--has-notifications-pat Whether REPOMATIC_NOTIFICATIONS_PAT is configured.
--has-pat / --no-has-pat Whether REPOMATIC_PAT is configured, enabling the
PAT capability checks. Auto-detected from the
REPOMATIC_PAT environment variable when omitted.
[default: (dynamic)]
--has-virustotal-key Whether VIRUSTOTAL_API_KEY is configured.
-h, --help Show this message and exit.
Examples:
In GitHub Actions (reads pyproject.toml automatically):
$ repomatic lint-repo --repo-name my-package
Local run (derives repo from $GITHUB_REPOSITORY or --repo):
$ repomatic lint-repo --repo owner/repo
With PAT capability checks:
$ repomatic lint-repo --has-pat
repomatic list-skills¶
$ repomatic list-skills --help
Usage: repomatic list-skills [OPTIONS]
List all bundled Claude Code skills, in lifecycle-phase order.
Reads skill definitions from the bundled data files and renders them as a
table. Respects the global --table-format option.
The rows keep the canonical lifecycle order, Setup first and Release last. No
--sort-by is offered against it: sorting the phase column alphabetically would
spell that lifecycle Development first.
Options:
-h, --help Show this message and exit.
repomatic lock-threads¶
$ repomatic lock-threads --help
Usage: repomatic lock-threads [OPTIONS]
Lock closed issues and pull requests left inactive too long.
Keeps spam and necro-posting off threads whose discussion is over, without
touching anything still moving: the clock counts from a thread's last update,
so a closed issue people are still replying to keeps resetting it.
Locking is one-way here. Nothing unlocks a thread on a schedule, and a thread
already locked never reappears in the search, so re-running the command right
after a run finds nothing left to do.
Issues repomatic maintains itself are excluded by default: they are meant to
reopen when their condition recurs, which a lock would block.
Requires the gh CLI to be authenticated.
Options:
--inactive-days INTEGER RANGE Days without activity before a closed thread is
locked. [default: 90; x>=1]
--issue-comment TEXT Comment posted on an issue before locking it.
Empty to post none. [default: This issue has
been automatically locked since there has not
been any recent activity after it was closed.
Please open a new issue for related bugs.]
--pr-comment TEXT Comment posted on a pull request before locking
it. Empty to post none. [default: This pull
request has been automatically locked since
there has not been any recent activity after it
was closed. Please open a new issue for related
bugs.]
--exclude-label TEXT Leave threads carrying this label unlocked.
Repeatable. [default: 🤖 ci]
--limit INTEGER RANGE Maximum number of threads to examine in one
run. [default: 200; 1<=x<=1000]
--reason [off_topic|resolved|spam|too_heated]
Reason recorded with the lock. [default:
resolved]
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote
of the current clone.
--dry-run / --live Report what would be done without making
changes. [default: dry-run]
-h, --help Show this message and exit.
Examples:
Preview what a run would lock:
$ repomatic lock-threads
Lock them, as the autolock workflow does:
$ repomatic lock-threads --live
Lock silently after six months, sparing triaged threads:
$ repomatic lock-threads --live --inactive-days 180 --issue-comment "" --exclude-label "🚧 needs triage"
repomatic pack-attestation¶
$ repomatic pack-attestation --help
Usage: repomatic pack-attestation [OPTIONS]
Rename an attestation bundle after its subject, print the upload list.
actions/attest writes every bundle to the same `attestation.json` basename, so
a release attaching several would keep only the last. This reads back the
subjects the bundle actually attests, names it after them, and prints every
file the release upload step should attach: the assets and their bundle, one
path per line.
A bundle covering several assets has no single name to take, so pass --name to
name the set instead.
With --require-declared, a file the project declares as an extra release asset
but whose artifact never landed fails the command, before anything is
attached: an immutable release could never gain it afterwards.
Idempotent: re-running copies the same bytes over the same name, and an upload
replaces the assets of the same name.
Options:
--bundle FILE Attestation bundle written by actions/attest.
[required]
--dir DIRECTORY Directory holding the attested assets, and where the
bundle lands. [default: .]
--name TEXT Stem naming the set, for a bundle attesting more than
one asset.
--require-declared / --no-require-declared
Fail unless the bundle attests every file the release-
assets setting of [tool.repomatic] declares.
[default: no-require-declared]
--verify / --no-verify Check the provenance of every attested asset with gh
attestation verify. Needs --repo. [default: no-
verify]
--upload-to TAG Attach the packed files to the release of this tag,
replacing same-named assets. Needs --repo.
--repo TEXT Repository the release belongs to. Defaults to
$GITHUB_REPOSITORY.
-h, --help Show this message and exit.
Examples:
Single asset, named papaya.tar.gz.attestation.json:
$ repomatic pack-attestation --bundle "${BUNDLE_PATH}"
A glob's worth of assets, all covered by one bundle:
$ repomatic pack-attestation --bundle b.json --dir dist --name papaya-set
Check the provenance, then attach to a release draft:
$ repomatic pack-attestation --bundle "${BUNDLE_PATH}" --verify --upload-to v1.2.3
repomatic pack-binaries¶
$ repomatic pack-binaries --help
Usage: repomatic pack-binaries [OPTIONS]
Materialize versionless binary aliases and print the upload list.
Copies each versioned binary (`repomatic-1.2.3-linux-arm64.bin`) to its
versionless alias (`repomatic-linux-arm64.bin`) so the stable
releases/latest/download URLs always resolve, then prints every file the
release upload step should attach, one path per line. Python distributions
(.tar.gz, .whl) are skipped: create-release already uploaded them.
Idempotent: re-running overwrites the same aliases with the same bytes, and an
upload replaces the assets of the same name.
Options:
--version TEXT Release version whose binaries earn versionless aliases.
[required]
--dir DIRECTORY Directory holding the compiled binaries and attestation
bundles. [required]
--upload-to TAG Attach the packed files to the release of this tag, replacing
same-named assets. Needs --repo.
--repo TEXT Repository the release belongs to. Defaults to
$GITHUB_REPOSITORY.
-h, --help Show this message and exit.
Examples:
Pack the binaries a build run downloaded:
$ repomatic pack-binaries --version 1.2.3 --dir ./compile-assets
Pack them and attach them to the release draft:
$ repomatic pack-binaries --version 1.2.3 --dir ./compile-assets --upload-to v1.2.3
repomatic pack-manpages¶
$ repomatic pack-manpages --help
Usage: repomatic pack-manpages [OPTIONS]
Bundle the rendered man pages into the tarball a release attaches.
The tarball holds the pages under the name of their directory, like `tar
--create man/` stores them. It is byte-deterministic: re-packing an unchanged
tree gives an identical file, with the same attestation digest.
Prints the path of the tarball.
Options:
--dir DIRECTORY Directory holding the rendered roff pages. [default: man]
-o, --output FILE Write the tarball to this file. Defaults to the
manpages_asset_name metadata key with a .tar.gz extension,
in the working directory.
-h, --help Show this message and exit.
Examples:
Pack ./man into <manpages_asset_name>.tar.gz:
$ repomatic pack-manpages
Pack another directory into an explicit file:
$ repomatic pack-manpages --dir build/man --output papaya-manpages.tar.gz
repomatic pack-plugin¶
$ repomatic pack-plugin --help
Usage: repomatic pack-plugin [OPTIONS]
Pack the bundled skills and agents into a Claude Code plugin archive.
Assembles `.claude/.claude-plugin/plugin.json` and every skill and agent the
component registry declares into a zip holding a single top-level folder,
which the release lane attaches to each GitHub release. The archive is byte-
deterministic, so re-packing an unchanged tree produces an identical file.
To load a packed plugin without a marketplace, unzip the archive and point
`claude --plugin-dir` at the extracted folder.
Options:
-o, --output FILE Write the plugin archive to this file. [default:
./repomatic-claude-plugin.zip]
-h, --help Show this message and exit.
Examples:
Pack into the default ./repomatic-claude-plugin.zip:
$ repomatic pack-plugin
Pack for a local install, without a marketplace:
$ repomatic pack-plugin --output /tmp/repomatic-claude-plugin.zip
repomatic pr-body¶
$ repomatic pr-body --help
Usage: repomatic pr-body [OPTIONS]
Generate a PR body with a collapsible workflow metadata block.
Reads GITHUB_* environment variables to produce a <details> block listing the
workflow metadata (documentation, trigger, actor, ref, commit, job, workflow,
run).
The prefix can be set via --template (built-in templates), --prefix (arbitrary
content) or --prefix-file (the same content read from a file). If a template
and a prefix are both given, the prefix is prepended before the rendered
template content.
Options:
--prefix TEXT Content to prepend before the metadata details
block. [default: ""]
--prefix-file FILE Read the prefix from a file instead of --prefix,
for a report too large to pass as an argument.
Wins over --prefix when both are given.
--template [available-admonition|broken-links-issue|bump-version|development-warning|fix-changelog|fix-typos|fix-vulnerable-deps|format-images|format-json|format-markdown|format-pyproject|format-python|format-shell|generated-footer|github-releases|immutable-releases|pr-metadata|prepare-release|refresh-tip|release-notes|release-sync-report|sample-metrics|scan-virustotal|setup-guide|setup-guide-branch-ruleset|setup-guide-cloudflare-pages|setup-guide-cloudflare-r2|setup-guide-dependabot|setup-guide-fork-pr-approval|setup-guide-notifications-pat|setup-guide-pages-source|setup-guide-pypi-trusted-publisher|setup-guide-sha-pinning-required|setup-guide-token|setup-guide-verify|setup-guide-virustotal|squashed-release|sync-action-pins|sync-bumpversion|sync-dep-sources|sync-gitignore|sync-mailmap|sync-repomatic|sync-repomatic-upgrade|sync-runner-images|sync-tool-versions|sync-uv-lock|sync-workflow-pins|unavailable-admonition|unsubscribe-report|update-dep-graph|update-docs|upgrade-invite|yanked-admonition]
Built-in template to render the content from.
--template-file FILE Template file to render the content from,
instead of --template: markdown with optional
YAML frontmatter, for project-specific content.
Set 'footer: false' in its frontmatter: the
metadata block already carries the attribution
footer.
--template-arg KEY=VALUE Pass an arbitrary key/value pair to the
template. Repeat to provide multiple. Use this
to feed template variables not covered by the
dedicated flags. Example: --template-arg
channel=Nix.
--template-arg-file KEY=PATH Read a template value from a file. Repeat to
provide multiple. Use this for a value with no
ceiling on its size, like a generated table: a
report travels as a path rather than inline.
Example: --template-arg-file
summary=proposal.md.
--version TEXT Version string passed to the template (like
1.2.0).
--part [minor|major] Version part passed to the bump-version
template.
-o, --output FILE Write the PR body to this file. github-actions
writes the body, title and commit message as
step outputs. [default: -]
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
-h, --help Show this message and exit.
Examples:
Preview metadata block locally:
$ repomatic pr-body
CI: write as GitHub Actions step outputs:
$ repomatic pr-body --output "$GITHUB_OUTPUT" --output-format github-actions
Use a built-in template:
$ repomatic pr-body --template bump-version --version 1.2.0 --part minor
Use a downstream-shipped template with custom variables:
$ repomatic pr-body --template-file path/to/template.md --template-arg fruit=mango --template-arg crate=10
With a prefix above the metadata block:
$ repomatic pr-body --prefix "Fix formatting"
repomatic pr-sync¶
$ repomatic pr-sync --help
Usage: repomatic pr-sync [OPTIONS]
Converge a branch and its PR onto whatever the working tree holds.
Opens the pull request when the tree carries changes, refreshes it when those
changes moved, does nothing at all when the branch already matches, and closes
the PR (deleting the branch) once the changes are gone.
Idempotent: re-running with an unchanged tree performs no write, so a workflow
re-run never churns the PR or re-triggers its checks.
With --template, the title, body and commit message are rendered internally
and the branch, labels and draft state come from the template and its
frontmatter, so the whole operation is one flag. Without one, pass --title,
--body and --commit-message explicitly.
Works from a detached HEAD: the base falls back to the repository default
branch read from the CI event payload, and any commits the job made itself are
carried through.
Commits the whole tree unless --add-path narrows it. A job that installs its
own linter into the checkout, or runs a package manager that rewrites a lock
file on the way past, wants the narrow form: those writes are not what the
pull request is for.
Options:
--template [available-admonition|broken-links-issue|bump-version|development-warning|fix-changelog|fix-typos|fix-vulnerable-deps|format-images|format-json|format-markdown|format-pyproject|format-python|format-shell|generated-footer|github-releases|immutable-releases|pr-metadata|prepare-release|refresh-tip|release-notes|release-sync-report|sample-metrics|scan-virustotal|setup-guide|setup-guide-branch-ruleset|setup-guide-cloudflare-pages|setup-guide-cloudflare-r2|setup-guide-dependabot|setup-guide-fork-pr-approval|setup-guide-notifications-pat|setup-guide-pages-source|setup-guide-pypi-trusted-publisher|setup-guide-sha-pinning-required|setup-guide-token|setup-guide-verify|setup-guide-virustotal|squashed-release|sync-action-pins|sync-bumpversion|sync-dep-sources|sync-gitignore|sync-mailmap|sync-repomatic|sync-repomatic-upgrade|sync-runner-images|sync-tool-versions|sync-uv-lock|sync-workflow-pins|unavailable-admonition|unsubscribe-report|update-dep-graph|update-docs|upgrade-invite|yanked-admonition]
Built-in template to render the content from.
--template-file FILE Template file to render the content from,
instead of --template: markdown with optional
YAML frontmatter, for project-specific content.
Set 'footer: false' in its frontmatter: the
metadata block already carries the attribution
footer.
--template-arg KEY=VALUE Pass an arbitrary key/value pair to the
template. Repeat to provide multiple. Use this
to feed template variables not covered by the
dedicated flags. Example: --template-arg
channel=Nix.
--template-arg-file KEY=PATH Read a template value from a file. Repeat to
provide multiple. Use this for a value with no
ceiling on its size, like a generated table: a
report travels as a path rather than inline.
Example: --template-arg-file
summary=proposal.md.
--version TEXT Version string passed to the template (like
1.2.0).
--part [minor|major] Version part passed to the bump-version
template.
--branch TEXT Head branch to create, update or retire. By
convention the job ID; defaults to the template
name, or to the stem of the template file.
--title TEXT Pull-request title, when not using a template.
--body TEXT Rendered markdown body, when not using a
template.
--commit-message TEXT Commit message, when not using a template.
--base TEXT Base branch. Defaults to the currently checked-
out branch, or to the repository default branch
when the checkout is detached in CI.
--label TEXT Label to attach, overriding the template's
frontmatter labels. Repeat to provide multiple.
Best-effort: a label GitHub refuses warns
instead of failing the command.
--assignee TEXT Assignee to attach. Repeat to provide multiple.
Defaults to the workflow actor via the ambient
GITHUB_ACTOR variable. Best-effort: github-
actions[bot] cannot be assigned and only warns.
--draft / --no-draft Hold the pull request in draft, overriding the
template's frontmatter. Re-applied on every
update, not just at creation, so a PR marked
ready-for-review goes back to draft on the next
sync.
--add-path TEXT Git pathspec limiting what the pull request
commits. Repeat to provide multiple. Defaults to
the whole tree, which is right when a job's only
writes are the ones it means to publish; narrow
it when the job also provisions tooling into the
checkout, so an installed package or a rewritten
lock file cannot ride along.
-h, --help Show this message and exit.
Examples:
Refresh an autofix job's pull request:
$ repomatic pr-sync --template format-python
Open a version-bump PR on its conventional branch:
$ repomatic pr-sync --template bump-version --part minor --branch minor-version-increment
A one-off PR with explicit content:
$ repomatic pr-sync --branch my-fix --title "Fix" --body "…" --commit-message "Fix the thing"
repomatic prepare-release¶
$ repomatic prepare-release --help
Usage: repomatic prepare-release [OPTIONS]
Prepare files for a release or post-release version bump.
This command consolidates all release preparation steps:
- Set release date in changelog (replaces "(unreleased)" with today's date).
- Set release date in citation.cff.
- Update changelog comparison URL from "...main" to "...v{version}".
- Remove the "[!WARNING]" development warning block from changelog.
- Optionally update workflow URLs to use versioned tag.
When running in GitHub Actions, --update-workflows is auto-detected:
it defaults to True when $GITHUB_REPOSITORY matches the canonical
workflows repository (kdeldycke/repomatic).
For post-release (after the release commit), use --post-release to retarget
workflow URLs back to the default branch.
With --commit, the changes to tracked files are then committed by the CI bot.
The release commit is named after the version to release. The post-release
commit, made on top of it once the next version is bumped, names both
versions. The edits are idempotent, so committing after running them once
already changes nothing more.
Options:
--changelog FILE Path to the changelog file. Defaults to
[tool.repomatic] changelog.location.
--citation FILE Path to the citation file. Skipped when it does not
exist. [default: citation.cff]
--workflow-dir DIRECTORY Path to the GitHub workflows directory. [default:
.github/workflows]
--default-branch TEXT Name of the default branch for workflow URL updates.
[default: main]
--update-workflows / --no-update-workflows
Update workflow URLs to use versioned tag instead of
default branch. Defaults to True when
$GITHUB_REPOSITORY is the canonical workflows repo.
--post-release Run post-release steps (retarget workflow URLs to
default branch).
--commit Commit every tracked change once the files are
prepared, as the release commit, or with --post-
release as the post-release commit.
-o, --output FILE Write version=X.Y.Z, the version being released, to
this file, like $GITHUB_OUTPUT.
-h, --help Show this message and exit.
Examples:
Prepare release (changelog + citation):
$ repomatic prepare-release
Post-release: retarget workflows to main branch:
$ repomatic prepare-release --post-release
Commit the freeze, and hand its version to a later step:
$ repomatic prepare-release --commit --output "$GITHUB_OUTPUT"
Commit the post-release bump:
$ repomatic prepare-release --post-release --commit
repomatic run¶
$ repomatic run --help
Usage: repomatic run [OPTIONS] [TOOL] [EXTRA_ARGS]...
Run an external tool with managed configuration.
Installs the tool at a pinned version, resolves config through a 4-level
precedence chain (native config file, [tool.X] in pyproject.toml, bundled
default, bare invocation), and invokes the tool.
Binary tools are cached locally to avoid re-downloading on repeated runs. Use
--no-cache to force a fresh download. See repomatic cache for cache
management.
Pass extra arguments to the tool after --:
repomatic run yamllint -- --strict .
repomatic run zizmor -- --persona auditor .
Report what a formatter would rewrite, leaving the tree alone:
repomatic run mdformat --verify -- changelog.md
Override the pinned version:
repomatic run shfmt --version 3.14.0 --skip-checksum -- .
List all managed tools and their resolved config source:
repomatic run --list
Options:
--list List all managed tools.
--verify Report which targets the tool would rewrite, without touching
them. Runs the write path against throwaway copies, so the
answer holds even for a tool whose own --check mode is
unreliable.
--version TEXT Override the pinned version of the tool.
--checksum TEXT Override the SHA-256 checksum for the current platform.
--skip-checksum Skip SHA-256 verification of binary downloads.
--no-cache Bypass the binary cache (download fresh every time).
--sort-by [tool|version|config-source]
Sort table by this column. Repeat to set priority. [default:
tool]
-h, --help Show this message and exit.
repomatic sample-metrics¶
$ repomatic sample-metrics --help
Usage: repomatic sample-metrics [OPTIONS]
Record what forges say about the repositories this project tracks.
Reads every subject through whichever API its host speaks (GitHub, GitLab or
Forgejo) and appends one row per subject, metric and date. A counter like the
star count accrues, so its curve can be charted; an attribute like the date of
the newest commit keeps a single row, restamped only when it moves.
GitHub restricted its stargazer endpoints to a repository's own admins in
2026, which left every third-party star chart on the web rendering an error
card. It reopened an anonymous star history later that year, and this reads it
on a schedule and commits the result: a history that accrues locally cannot be
revoked.
Each reading records where it came from, since the curves are not all measured
the same way. A GitHub repository has its whole curve rebuilt from that star
history, which counts the stars it still holds; every other forge is sampled
forward, one reading per run.
Options:
--store FILE CSV store to accumulate into. Defaults to
[tool.repomatic.metrics] store.
--carry-from BRANCH Restore the store from this remote branch before
sampling, so readings still pending in an open pull
request are appended to instead of dropped. Name the
branch the job publishes to. Ignored when the branch
does not exist, which is every run that follows a
merge.
--forward / --no-forward Read every subject's current metrics from its own
forge. [default: forward]
--reconstruct / --no-reconstruct
Rebuild each GitHub subject's star curve from its
star history. [default: reconstruct]
--render / --no-render Redraw the configured charts from the stored
history. [default: render]
-h, --help Show this message and exit.
Examples:
Record today's readings:
$ repomatic sample-metrics
Take today's readings without rebuilding the star curves:
$ repomatic sample-metrics --no-reconstruct
repomatic scan-virustotal¶
$ repomatic scan-virustotal --help
Usage: repomatic scan-virustotal [OPTIONS]
Upload release binaries to VirusTotal.
Scans all .bin and .exe files in the given directory and uploads them to
VirusTotal, seeding antivirus vendor databases with the signatures of the
freshly built binaries.
With --download, first fetches the tag's versioned binaries from its GitHub
release into the directory, waiting for a freshly published release to list
its assets.
With --poll, waits for the analyses to complete and reports each binary's
flagged / total verdict counts. With --records, the polled snapshots are
merged into a CSV history, which sync-binaries renders into the binaries
catalog page.
Options:
--tag TEXT Release tag the binaries belong to (e.g.,
v1.2.3). [required]
--api-key TEXT VirusTotal API key. [required]
--binaries-dir DIRECTORY Directory containing binary files to upload.
[required]
--download / --no-download Download the tag's versioned binaries from its
GitHub release into --binaries-dir first,
waiting for the release to list its assets.
[default: no-download]
--repo TEXT Repository in owner/repo format that --download
reads the release from. Defaults to
$GITHUB_REPOSITORY.
--rate-limit INTEGER RANGE Maximum VirusTotal API requests per minute.
[default: 4; 1<=x<=60]
--poll / --no-poll Poll for detection statistics after uploading.
[default: no-poll]
--poll-timeout INTEGER RANGE Maximum seconds to wait for analysis completion
when polling. [default: 600; 60<=x<=3600]
--records FILE CSV scan history to record detection snapshots
in (requires --poll).
--carry-from BRANCH Restore --records from this remote branch before
scanning, so snapshots still pending in an open
pull request are appended to instead of dropped.
Name the branch the job publishes to. Ignored
when the branch does not exist, which is every
run that follows a merge.
-h, --help Show this message and exit.
Examples:
Scan the binaries attached to a tag:
$ repomatic scan-virustotal --tag v1.2.3 --binaries-dir ./binaries
Wait for verdicts and record them:
$ repomatic scan-virustotal --tag v1.2.3 --binaries-dir ./binaries --poll --records docs/assets/virustotal-scans.csv
Download the release's binaries first:
$ repomatic scan-virustotal --tag v1.2.3 --download --repo owner/repo --binaries-dir ./binaries
repomatic setup-guide¶
$ repomatic setup-guide --help
Usage: repomatic setup-guide [OPTIONS]
Manage the setup guide issue lifecycle.
Each setup step is shown as a collapsible section with a status indicator:
incomplete steps are expanded with a warning emoji, completed steps are
collapsed with a checkmark.
PAT availability is auto-detected from the REPOMATIC_PAT environment variable
when --has-pat/--no-has-pat is not specified.
When a PAT is detected and --repo is provided, the command runs granular PAT
permission checks and repository settings checks. The issue closes only when
all verifiable steps pass.
Requires the gh CLI to be authenticated.
Options:
--has-cloudflare-api-token Whether CLOUDFLARE_API_TOKEN is configured.
--has-cloudflare-r2-keys Whether CLOUDFLARE_R2_ACCESS_KEY_ID and
CLOUDFLARE_R2_SECRET_ACCESS_KEY are both
configured.
--has-notifications-pat Whether REPOMATIC_NOTIFICATIONS_PAT is configured.
--has-pat / --no-has-pat Whether REPOMATIC_PAT is configured, enabling the
PAT capability checks. Auto-detected from the
REPOMATIC_PAT environment variable when omitted.
[default: (dynamic)]
--has-virustotal-key Whether VIRUSTOTAL_API_KEY is configured.
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY.
-h, --help Show this message and exit.
Examples:
No secret: create or reopen the setup issue:
$ repomatic setup-guide
Secret configured: close the issue if all checks pass:
$ repomatic setup-guide --has-pat
repomatic show-config¶
$ repomatic show-config --help
Usage: repomatic show-config [OPTIONS]
Print the [tool.repomatic] configuration reference table.
Renders a table of all available options, their types, defaults, and
descriptions, generated from the Config dataclass docstrings. Respects the
global --table-format and --sort-by options.
Options:
--sort-by [option|type|default|description]
Sort table by this column. Repeat to set priority. [default:
option]
-h, --help Show this message and exit.
repomatic show-metadata¶
$ repomatic show-metadata --help
Usage: repomatic show-metadata [OPTIONS] [KEYS]...
Dump project metadata to a file.
Prints all metadata keys to stdout by default. Use --output to write to a
file. Pass key names as arguments to filter output.
Options:
--output-format [github|github-json|json]
Rendering format of the metadata. [default:
github]
--overwrite / --no-overwrite Overwrite the output file if it already holds
content. [default: overwrite]
-o, --output FILE Write the metadata to this file. [default: -]
--list-keys List all available metadata keys with
descriptions and exit.
--sort-by [key|description] Sort table by this column. Repeat to set
priority. [default: key]
-h, --help Show this message and exit.
Examples:
Print two keys:
$ repomatic show-metadata current_version is_python_project
List every key:
$ repomatic show-metadata --list-keys
CI: write as GitHub Actions step outputs:
$ repomatic show-metadata --output-format github-json --output "$GITHUB_OUTPUT" current_version is_python_project
repomatic show-test-matrix¶
$ repomatic show-test-matrix --help
Usage: repomatic show-test-matrix [OPTIONS] [full|pr]
List every job of the computed CI test matrix, one row per job.
Each row carries one column per axis and states whether that job runs stable
or unstable (continue-on-error), which is the job list CI schedules. Sort it
on the axes you care about with --row-axis and --col-axis. Pass "full" for the
push and schedule matrix (the default), or "pr" for the reduced pull-request
matrix. Respects the global --table-format option.
--grid trades that listing for a two-axis grid: the two axes head the sides
and every other axis collapses into the cells. It is the compact read of the
same jobs, and it is lossy, so a cell standing for several jobs states how
many.
Options:
--emoji / --no-emoji Decorate cells with a status emoji. Use --no-emoji for
plain words. [default: emoji]
--grid / --no-grid Collapse the listing into a two-axis grid, one cell per
intersection. [default: no-grid]
--row-axis [os|python-label|python-version|resolution|state]
Job key sorted on first, heading the grid's rows.
[default: python-version]
--col-axis [os|python-label|python-version|resolution|state]
Job key sorted on next, heading the grid's columns.
[default: os]
-h, --help Show this message and exit.
Examples:
One row per job:
$ repomatic show-test-matrix
The PR subset, in plain words:
$ repomatic show-test-matrix pr --no-emoji
Pivot columns on a custom axis:
$ repomatic show-test-matrix --col-axis click-version
The compact two-axis grid:
$ repomatic show-test-matrix --grid
Choose both grid axes:
$ repomatic show-test-matrix --grid --row-axis os --col-axis python-version
The full matrix as a GitHub-flavored table:
$ repomatic --table-format github show-test-matrix full
repomatic sponsor-label¶
$ repomatic sponsor-label --help
Usage: repomatic sponsor-label [OPTIONS]
Add a label to issues or PRs from GitHub sponsors.
Checks if the author of an issue or PR is a sponsor of the repository owner.
If they are, adds the specified label.
This command requires the gh CLI to be authenticated.
When run in GitHub Actions, all parameters are auto-detected from environment
variables ($GITHUB_REPOSITORY_OWNER, $GITHUB_REPOSITORY) and the event payload
($GITHUB_EVENT_PATH). You can override any auto-detected value by passing it
explicitly.
Options:
--owner TEXT GitHub username or organization to check sponsorship
for. Defaults to $GITHUB_REPOSITORY_OWNER.
--author TEXT GitHub username of the issue/PR author to check.
Defaults to author from $GITHUB_EVENT_PATH.
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote of the
current clone.
--number INTEGER RANGE Issue or PR number. Defaults to the number in
$GITHUB_EVENT_PATH. [x>=1]
--pr / --issue Specify issue or pull request. Auto-detected from
$GITHUB_EVENT_PATH.
--label TEXT Label to add if author is a sponsor. [default: 💖
sponsor]
-h, --help Show this message and exit.
Examples:
In GitHub Actions, with every default auto-detected:
$ repomatic sponsor-label
Override specific values:
$ repomatic sponsor-label --label "sponsor"
Manual invocation with all values:
$ repomatic sponsor-label --owner kdeldycke --author some-user --repo kdeldycke/repomatic --number 123 --issue
repomatic squashed-release¶
$ repomatic squashed-release --help
Usage: repomatic squashed-release [OPTIONS]
Open an issue when a release pull request was squash-merged, then fail.
A release needs its freeze and unfreeze commits to land separately, through
"Rebase and merge". Squashing them leaves no release commit to tag, so no tag,
package or GitHub release is published. This reports that to the maintainer in
one issue, rendered from the squashed-release template and assigned to the
workflow actor, and exits with code 1.
A re-run updates the open issue instead of opening a second one, and a later
squash merge reopens it.
Exits with code 0, opening nothing, when the message is not the one of a
squash-merged release pull request.
Options:
--message TEXT Commit message to check. Defaults to the head commit message
of the event in $GITHUB_EVENT_PATH.
--repo TEXT Repository to open the issue in. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote of the current
clone.
-h, --help Show this message and exit.
Examples:
Check the head commit of the current push event:
$ repomatic squashed-release
Check an explicit commit message:
$ repomatic squashed-release --message 'Release `v1.2.3` (#42)'
repomatic sync-action-pins¶
$ repomatic sync-action-pins --help
Usage: repomatic sync-action-pins [OPTIONS]
Bump SHA-pinned GitHub Actions across `.github/` to their latest release.
Scans workflow and composite-action files for
`uses: owner/repo@<sha> # vX.Y.Z` pins, resolves each action's latest
release passing the [tool.repomatic] minimum-release-age cooldown to its
commit SHA, and rewrites the SHA and version comment. repomatic's own
reusable-workflow refs are left to `repomatic init`.
Options:
-o, --output FILE Write a markdown report (version table) to this
file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the minimum-
release-age cooldown. [default: held-back]
-h, --help Show this message and exit.
Examples:
Bump every SHA-pinned action past the cooldown:
$ repomatic sync-action-pins
repomatic sync-binaries¶
$ repomatic sync-binaries --help
Usage: repomatic sync-binaries [OPTIONS]
Regenerate the binaries catalog from the GitHub Releases API.
Writes the catalog data to assets/binaries.csv next to the page, one row per
released binary: its version linking to the release, its platform linking to
the download, its release date, and the VirusTotal detection snapshot when a
scan history file is given. The page renders the CSV through a csv-table
directive and is created from a default template when missing; only its chart
region is rewritten afterwards, so the prose can be edited per repository.
Options:
--repo TEXT Repository in owner/repo format. Defaults to
$GITHUB_REPOSITORY, then to the GitHub remote of the current
clone.
--page FILE Markdown page to create or refresh. [default:
docs/binaries.md]
--records FILE CSV scan history written by scan-virustotal.
-h, --help Show this message and exit.
Examples:
Regenerate the binaries catalog page:
$ repomatic sync-binaries --repo owner/repo
With the detection snapshots of a scan history:
$ repomatic sync-binaries --records docs/assets/virustotal-scans.csv
repomatic sync-bumpversion¶
$ repomatic sync-bumpversion --help
Usage: repomatic sync-bumpversion [OPTIONS]
Sync [tool.bumpversion] in pyproject.toml from the bundled template.
Re-derives the [tool.bumpversion] section from the canonical template bundled
in repomatic, keeping the local additions. Designed for the sync-bumpversion
autofix job. The repomatic init bumpversion command remains available for
interactive bootstrapping.
Options:
-h, --help Show this message and exit.
repomatic sync-dep-sources¶
$ repomatic sync-dep-sources --help
Usage: repomatic sync-dep-sources [OPTIONS]
Swap git-tracked dependencies back to their released versions.
Manages one idiom: a [tool.uv.sources] entry tracking a git branch,
paired with a .dev version floor naming the awaited release (like
'mango>=2.1.0.dev0'). Once a stable release satisfying the floor ships
on PyPI, the swap:
- drops the [tool.uv.sources] override
- tightens the .dev floor to its base release
- freezes the adopted release through the exclude-newer cooldown
(an exclude-newer-package entry the ordinary sync-uv-lock lifecycle
prunes once it ages out)
- re-locks and verifies the adopted version landed
Overrides outside the idiom (path or workspace sources, rev/tag pins,
floor-less branch tracks) are never touched. A resolution conflict or a
lock landing on an unexpected version restores the project untouched.
Options:
--lockfile FILE Path to the uv.lock file. [default: uv.lock]
--table / --no-table Print a summary table of updated packages.
[default: table]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the exclude-
newer cooldown (runs a second uv resolution).
[default: held-back]
-o, --output FILE Write a markdown report (table and release
notes) to this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
-h, --help Show this message and exit.
Examples:
Swap whatever is ready and show changes:
$ repomatic sync-dep-sources
CI: write markdown report as a GitHub Actions step output:
$ repomatic sync-dep-sources --no-table --release-notes --output "$GITHUB_OUTPUT" --output-format github-actions
repomatic sync-deps¶
$ repomatic sync-deps --help
Usage: repomatic sync-deps [OPTIONS] [sync-dep-sources|sync-uv-lock|sync-action-pins|sync-workflow-pins|sync-tool-versions]...
Update project dependencies, the whole set or a named subset.
The single entry point for dependency updates. It drives
sync-dep-sources, sync-uv-lock, sync-action-pins, sync-workflow-pins, and
sync-tool-versions: their network discovery runs concurrently (one shared
HTTP cache, one spinner), then the file rewrites apply serially because
two of them touch the same workflow files. Name one or more updaters to
run just those; with none named, every enabled updater runs.
The [tool.repomatic] feature flags are always authoritative: a disabled
updater never runs. With no names, updaters not meaningful in the current
working tree are skipped too (sync-tool-versions outside the repomatic
checkout, the pin updaters without workflow files); naming one runs it
regardless of the working tree.
With --pr-sync, each updater instead runs on its own, from a tree put back
to HEAD, and opens, refreshes or closes the pull request on the branch
named after it. A named updater with nothing to act on in this tree runs
nothing, and only closes a stale pull request. A failed updater leaves its
pull request alone, the others still run, and the command exits 1.
Options:
-o, --output FILE Write a combined markdown report (one section
per updater) to this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the minimum-
release-age cooldown. [default: held-back]
--dry-run / --live Report what would be done without making
changes. [default: live]
--pr-sync Run the updaters one after the other, each from
a clean tree, and open, refresh or close the
pull request of each, as `pr-sync` does. The
mode the autofix workflow runs.
-h, --help Show this message and exit.
Examples:
Update everything enabled:
$ repomatic sync-deps
Only the lockfile and action pins:
$ repomatic sync-deps sync-uv-lock sync-action-pins
Preview without writing:
$ repomatic sync-deps --dry-run
CI: one pull request per updater:
$ repomatic sync-deps --pr-sync --release-notes sync-uv-lock
repomatic sync-dev-release¶
$ repomatic sync-dev-release --help
Usage: repomatic sync-dev-release [OPTIONS]
Sync a rolling dev pre-release on GitHub.
Maintains a single pre-release that mirrors the unreleased changelog section.
The dev tag is force-updated to point to the latest main commit.
In --delete mode, removes the dev pre-release without recreating it. This is
used during real releases to clean up.
Options:
--dry-run / --live Report what would be done without making changes.
[default: dry-run]
--delete / --no-delete Delete-only mode: remove the dev pre-release
without recreating. [default: no-delete]
--upload-assets DIRECTORY Directory containing assets (binaries, packages) to
upload.
-h, --help Show this message and exit.
Examples:
Dry run to preview what would be synced:
$ repomatic sync-dev-release --dry-run
Create or update the dev pre-release:
$ repomatic sync-dev-release --live
Create or update with asset upload:
$ repomatic sync-dev-release --live --upload-assets release_assets/
Delete the dev pre-release, as a real release does:
$ repomatic sync-dev-release --live --delete
repomatic sync-github-releases¶
$ repomatic sync-github-releases --help
Usage: repomatic sync-github-releases [OPTIONS]
Sync GitHub release notes from changelog.md.
Compares each GitHub release body against the corresponding changelog.md
section and updates any that have drifted.
Options:
--dry-run / --live Report what would be done without making changes.
[default: dry-run]
-h, --help Show this message and exit.
Examples:
Dry run to preview what would be updated:
$ repomatic sync-github-releases --dry-run
Update drifted release notes:
$ repomatic sync-github-releases --live
repomatic sync-gitignore¶
$ repomatic sync-gitignore --help
Usage: repomatic sync-gitignore [OPTIONS]
Sync a .gitignore file from gitignore.io templates.
Fetches templates for a base set of categories plus any extras from
[tool.repomatic] config, then appends gitignore-extra-content. Writes to the
path specified by gitignore-location (default ./.gitignore).
The generated file is the whole file: nothing is read back from the copy on
disk. A rule added there by hand is therefore dropped on the next sync, so the
write aborts when it would lose one. Move the rule into gitignore-extra-
content to keep it, or pass --drop-orphans to let it go.
Options:
-o, --output FILE Write the .gitignore to this file. Defaults to
[tool.repomatic] gitignore.location.
--drop-orphans / --no-drop-orphans
Overwrite rules found on disk but absent from the generated
file, instead of refusing to drop them. [default: no-drop-
orphans]
-h, --help Show this message and exit.
Examples:
Generate .gitignore using config from pyproject.toml:
$ repomatic sync-gitignore
Write to custom location:
$ repomatic sync-gitignore --output ./custom/.gitignore
Preview on stdout:
$ repomatic sync-gitignore --output -
repomatic sync-labels¶
$ repomatic sync-labels --help
Usage: repomatic sync-labels [OPTIONS]
Sync repository labels from bundled definitions using labelmaker.
Applies the bundled label definitions to the repository using labelmaker: the
default profile to all repositories, plus the awesome profile for awesome-*
repos, then the definitions the project adds. Each one is staged in a scratch
directory, so syncing labels leaves the working tree untouched.
Authentication follows the canonical token resolution (REPOMATIC_PAT, then
GH_TOKEN, then GITHUB_TOKEN). Downloads labelmaker automatically via the tool
registry.
Options:
--repo TEXT Repository in owner/repo format. Defaults to $GITHUB_REPOSITORY,
then to the GitHub remote of the current clone.
-h, --help Show this message and exit.
repomatic sync-mailmap¶
$ repomatic sync-mailmap --help
Usage: repomatic sync-mailmap [OPTIONS] [DESTINATION_MAILMAP]
Update .mailmap with missing contributors from Git history.
Reads the existing .mailmap as a reference for grouped identities, then
appends any contributors not already covered. Results are sorted but not
regrouped: manual editing may be needed.
The destination defaults to the source file (in-place update). Pass - to print
to stdout instead.
Options:
--source FILE Mailmap source file to use as reference for contributors
identities that are already grouped. [default: .mailmap]
--create-if-missing / --skip-if-missing
If not found, either create the missing destination mailmap
file, or skip the update process entirely. This option is
ignored if the destination is stdout. [default: create-if-
missing]
-h, --help Show this message and exit.
repomatic sync-runner-images¶
$ repomatic sync-runner-images --help
Usage: repomatic sync-runner-images [OPTIONS]
Move retiring runner images forward, and probe superseding ones.
Every label this repository runs is looked up in GitHub's available-images
table. A **retirement** rewrites each literal `runs-on:` naming a deprecated
image onto its successor, because those jobs carry an end date. An **upgrade**
adds a strictly newer *version* to the full test matrix as a `continue-on-
error` probe rather than migrating onto it: nothing is bet on it, but the
suite starts exercising it at once, which surfaces a dependency breaking there
while there is runway to report it upstream.
Strictly newer by version is what separates an upgrade from a flavour. A same-
version variant carrying a different toolchain is not a newer image and is
never proposed as one.
Merging is the decision; the CI run this triggers is the evidence for it. To
decline a proposal for good, name the label in `[tool.repomatic.sync-runner-
images] ignore`: closing the pull request alone brings it back on the next
run.
Options:
--dry-run / --live Report what would be done without making changes.
[default: live]
-o, --output FILE Write the proposal as a Markdown table to this file, for
feeding a pull request body through `pr-sync --template-
arg-file`.
-h, --help Show this message and exit.
Examples:
What would change, without touching the tree:
$ repomatic sync-runner-images --dry-run
repomatic sync-tool-versions¶
$ repomatic sync-tool-versions --help
Usage: repomatic sync-tool-versions [OPTIONS]
Bump every `repomatic run` tool to its latest eligible release.
For each registry tool, finds the highest version that has cleared the
[tool.repomatic] minimum-release-age cooldown (GitHub releases for binary
tools, PyPI otherwise), writes it into tooling/registry.py, recomputes binary
checksums in the same pass, and refreshes the bundled actionlint problem
matcher from the tag of the actionlint it pins.
Upstream-only: it rewrites repomatic's own package source, so invoke it with
`uv run` (editable), never `uvx` (whose isolated wheel is discarded).
Options:
-o, --output FILE Write a markdown report (version table) to this
file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the minimum-
release-age cooldown. [default: held-back]
-h, --help Show this message and exit.
Examples:
Bump every registry tool past the cooldown:
$ repomatic sync-tool-versions
CI: write a markdown report as a GitHub Actions step output:
$ repomatic sync-tool-versions --output "$GITHUB_OUTPUT" --output-format github-actions
repomatic sync-uv-lock¶
$ repomatic sync-uv-lock --help
Usage: repomatic sync-uv-lock [OPTIONS]
Upgrade all dependencies and clean up stale cooldown overrides.
Wraps uv lock --upgrade and:
- syncs the repomatic-owned [tool.uv] policy pins (required-version,
exclude-newer) in pyproject.toml from the bundled template, so every
machine resolves the lockfile against the same uv floor and cooldown
- prunes exclude-newer-package entries from pyproject.toml whose held
version has aged past the exclude-newer cutoff, or whose own cutoff
has when the lock holds no version, then freezes the survivors at
their locked version (a fixed date) so the upgrade holds them
instead of tracking newer releases
- prints a table of updated packages with upload dates
- reports the cooldown-bypass lifecycle: entries pruned or frozen by
the run, and each active freeze with the date it expires
- optionally fetches release notes from GitHub (markdown)
- optionally reports newer releases held back by the cooldown, with the
date each ages out of the exclude-newer window (--held-back)
The table respects the global --table-format option (github, json,
csv, etc.). Release notes are always rendered as markdown.
Options:
--lockfile FILE Path to the uv.lock file. [default: uv.lock]
--table / --no-table Print a summary table of updated packages.
[default: table]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the exclude-
newer cooldown (runs a second uv resolution).
[default: held-back]
-o, --output FILE Write a markdown report (table and release
notes) to this file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
-h, --help Show this message and exit.
Examples:
Upgrade and show changes:
$ repomatic sync-uv-lock
With release notes:
$ repomatic sync-uv-lock --release-notes
Render the report as a GitHub-flavored table:
$ repomatic --table-format github sync-uv-lock
Render the report as JSON:
$ repomatic --table-format json sync-uv-lock
CI: write markdown report as a GitHub Actions step output:
$ repomatic sync-uv-lock --no-table --release-notes --output "$GITHUB_OUTPUT" --output-format github-actions
repomatic sync-workflow-pins¶
$ repomatic sync-workflow-pins --help
Usage: repomatic sync-workflow-pins [OPTIONS]
Bump npm and PyPI version literals embedded in workflow YAML.
Scans workflow and composite-action files for `npm install pkg@x` and
`uvx '<pkg>==x'` pins, resolves each to its latest release passing the
[tool.repomatic] minimum-release-age cooldown, and rewrites the literal.
Options:
-o, --output FILE Write a markdown report (version table) to this
file.
--output-format [markdown|github-actions]
Format of the --output file. github-actions
writes step outputs, for $GITHUB_OUTPUT.
[default: markdown]
--release-notes / --no-release-notes
Fetch release notes from GitHub (markdown,
appended after the table). [default: no-
release-notes]
--held-back / --no-held-back Report newer releases withheld by the minimum-
release-age cooldown. [default: held-back]
-h, --help Show this message and exit.
Examples:
Bump every workflow version literal past the cooldown:
$ repomatic sync-workflow-pins
repomatic unsubscribe-threads¶
$ repomatic unsubscribe-threads --help
Usage: repomatic unsubscribe-threads [OPTIONS]
Unsubscribe from closed, inactive GitHub notification threads.
Processes notifications in two phases:
Phase 1, REST notification threads:
Fetches Issue/PullRequest notification threads, inspects each for
closed + stale status, and unsubscribes via DELETE + PATCH.
Phase 2, GraphQL threadless subscriptions:
Searches for closed issues/PRs the user is involved in and
unsubscribes via the updateSubscription mutation.
Options:
--months INTEGER RANGE Inactivity threshold in months. Threads updated more
recently are kept. [default: 3; x>=1]
--max-unsubscribes INTEGER RANGE
Maximum unsubscribes per phase. Inspection is not
capped. [default: 200; x>=1]
--dry-run / --live Report what would be done without making changes.
[default: dry-run]
-h, --help Show this message and exit.
Examples:
Dry run to preview what would be unsubscribed:
$ repomatic unsubscribe-threads --dry-run
Unsubscribe from threads inactive for 6+ months:
$ repomatic unsubscribe-threads --months 6
Unsubscribe from at most 50 threads per phase:
$ repomatic unsubscribe-threads --max-unsubscribes 50
repomatic update-checksums¶
$ repomatic update-checksums --help
Usage: repomatic update-checksums [OPTIONS]
Recompute SHA-256 checksums for the binary tool registry.
Downloads each binary-distributed tool in the `repomatic run` registry at its
pinned version, computes the SHA-256, and rewrites any stale hash (and its
version stamp) in tooling/registry.py.
A repair path for a manual version edit: sync-tool-versions already
refreshes checksums when it bumps a version.
Options:
-h, --help Show this message and exit.
Examples:
Recompute every checksum in the tool registry:
$ repomatic update-checksums
repomatic update-dep-graph¶
$ repomatic update-dep-graph --help
Usage: repomatic update-dep-graph [OPTIONS]
Generate a Mermaid dependency graph from the project's uv lockfile.
Parses the CycloneDX SBOM export from uv and renders it as a Mermaid flowchart
for documentation. Version specifiers from uv.lock are shown as edge labels.
Group filtering:
-g, --group [docs|test|typing] Include dependencies from the specified group.
Can be repeated.
--all-groups Include all dependency groups from
pyproject.toml.
--no-group [docs|test|typing] Exclude the specified group. Takes precedence
over --all-groups and --group. Can be
repeated.
--only-group [docs|test|typing]
Only include dependencies from the specified
group, excluding main dependencies. Can be
repeated.
Extra filtering:
-e, --extra EXTRA Include dependencies from the specified extra.
Can be repeated.
--all-extras Include all optional extras from
pyproject.toml.
--no-extra EXTRA Exclude the specified extra, if --all-extras
is supplied. Can be repeated.
--only-extra EXTRA Only include dependencies from the specified
extra, excluding main dependencies. Can be
repeated.
Other options:
-p, --package TEXT Focus on a specific package's dependency tree.
--frozen / --no-frozen Use --frozen to skip lock file updates.
[default: frozen]
-l, --level INTEGER RANGE Maximum depth of the dependency graph. 1 =
directly-declared deps only, 2 = adds their
deps, etc. [x>=1]
-o, --output FILE Write the graph to this file. Defaults to
[tool.repomatic] dependency-graph.output, then
to stdout.
-h, --help Show this message and exit.
Examples:
Generate Mermaid graph:
$ repomatic update-dep-graph
Include test dependencies:
$ repomatic update-dep-graph --group test
Include all groups and extras:
$ repomatic update-dep-graph --all-groups --all-extras
Include all groups except typing:
$ repomatic update-dep-graph --all-groups --no-group typing
Include all extras except one:
$ repomatic update-dep-graph --all-extras --no-extra json5
Show only test group dependencies (no main deps):
$ repomatic update-dep-graph --only-group test
Show only a specific extra's dependencies:
$ repomatic update-dep-graph --only-extra xml
Focus on a specific package:
$ repomatic update-dep-graph --package click-extra
Limit graph depth to 2 levels:
$ repomatic update-dep-graph --level 2
Save to file:
$ repomatic update-dep-graph --output ./docs/assets/dependencies.mmd
repomatic update-docs¶
$ repomatic update-docs --help
Usage: repomatic update-docs [OPTIONS]
Regenerate the Sphinx API pages and the dynamic content of the docs.
Runs these phases in order, and stops at the first one that fails:
1. Run sphinx-apidoc to generate the RST stub of every module.
2. Convert the RST stubs to MyST Markdown, if the project uses MyST-Parser.
3. List every generated page in the toctree of its parent index page.
4. Run docs/docs_update.py (docs.update-script), if it exists.
5. Reformat with pyproject-fmt each pyproject.toml an earlier phase changed.
6. Refresh the {matrix} and :mirror: blocks of docs/ and readme.md.
With --check, only phases 4 and 6 run, in their own check modes: they report
out-of-date content and write nothing. The update script must accept a --check
flag to take part.
The phases read their settings from [tool.repomatic.docs].
Options:
--check Report out-of-date self-updating content and exit non-zero,
without writing anything. For CI drift detection.
-h, --help Show this message and exit.
repomatic verify-binary¶
$ repomatic verify-binary --help
Usage: repomatic verify-binary [OPTIONS]
Verify a compiled binary's architecture and minimum-OS floor.
Parses the executable headers natively (ELF, Mach-O, PE), with no external
tool: the architecture is checked on every platform, then the glibc floor on
Linux and the deployment target on macOS are measured over the binary plus the
Nuitka dist directories whose content its onefile payload repacks.
Options:
--target [linux-arm64|linux-x64|macos-arm64|macos-x64|windows-arm64|windows-x64]
Target platform. [required]
--binary FILE Path to the binary file to verify. [required]
--dist-dir DIRECTORY Nuitka dist directory to include in the OS floor scan.
Repeatable. Defaults to every *.dist directory in the
working directory.
-h, --help Show this message and exit.
Examples:
Verify a Linux ARM64 binary:
$ repomatic verify-binary --target linux-arm64 --binary ./mpm-linux-arm64.bin
Verify a Windows x64 binary:
$ repomatic verify-binary --target windows-x64 --binary ./mpm-windows-x64.exe
repomatic wait-pypi¶
$ repomatic wait-pypi --help
Usage: repomatic wait-pypi [OPTIONS]
Block until the PyPI JSON API serves the release of DIR's sdist.
uv publish returns once PyPI accepts the upload, but its index and CDN can
take minutes to serve the release everywhere. Automation reacting to the
release at once, like a downstream repository bumping its pin, would race that
window and fail to resolve the version.
Exits with code 1 when the release is still not served after the last lookup.
Options:
--dir DIRECTORY Directory holding the distributions just published.
The project name and version are read off its sdist.
[required]
--attempts INTEGER RANGE Lookups to make before giving up. [default: 20;
x>=1]
--delay INTEGER RANGE Seconds to wait between two lookups. [default: 15;
x>=0]
-h, --help Show this message and exit.
Examples:
Wait for the release of the distributions in dist/:
$ repomatic wait-pypi --dir dist
Command hierarchy¶
classDiagram
Choice <|-- LazyChoice
LazyChoice <|-- DependencyGroup
LazyChoice <|-- MatrixAxis
LazyChoice <|-- ProjectExtra
LazyChoice <|-- WorkflowFile
ParamType <|-- ComponentSelector
The repomatic.cli.main module holds the repomatic group and the table that names every command. Each command’s signature and docstring is on the page of its domain module, under the repomatic.cli package.
