repomatic 6.31.0__tar.gz → 7.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. {repomatic-6.31.0 → repomatic-7.0.0}/PKG-INFO +6 -6
  2. {repomatic-6.31.0 → repomatic-7.0.0}/pyproject.toml +24 -16
  3. {repomatic-6.31.0 → repomatic-7.0.0}/readme.md +3 -2
  4. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/__init__.py +2 -2
  5. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/changelog.py +14 -1
  6. repomatic-7.0.0/repomatic/checksums.py +127 -0
  7. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/cli.py +482 -251
  8. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/config.py +81 -0
  9. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/_release-engine.yaml +17 -17
  10. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/agent-sphinx-docs.md +1 -1
  11. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/autofix.yaml +212 -66
  12. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/changelog.yaml +18 -18
  13. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/debug.yaml +3 -3
  14. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/docs.yaml +7 -7
  15. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/labeller-content-based.yaml +0 -1
  16. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/labeller-file-based.yaml +0 -1
  17. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/labels.yaml +11 -11
  18. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/lint.yaml +26 -23
  19. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/release.yaml +1 -1
  20. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/ruff.toml +7 -0
  21. repomatic-7.0.0/repomatic/data/skill-babysit-ci.md +245 -0
  22. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-repomatic-audit.md +2 -3
  23. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-repomatic-changelog.md +1 -1
  24. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-repomatic-deps.md +2 -2
  25. repomatic-7.0.0/repomatic/data/skill-repomatic-ship.md +150 -0
  26. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/tests.yaml +3 -3
  27. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/unsubscribe.yaml +2 -2
  28. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/zizmor.yaml +1 -1
  29. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/deps_graph.py +180 -77
  30. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/git_ops.py +151 -7
  31. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/matrix.py +1 -1
  32. repomatic-7.0.0/repomatic/github/releases.py +408 -0
  33. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/token.py +12 -47
  34. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/workflow_sync.py +11 -10
  35. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/init_project.py +2 -102
  36. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/lint_repo.py +67 -7
  37. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/metadata.py +78 -105
  38. repomatic-7.0.0/repomatic/npm.py +89 -0
  39. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/pypi.py +1 -1
  40. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/registry.py +10 -10
  41. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/release_prep.py +25 -75
  42. repomatic-7.0.0/repomatic/sync_ops.py +886 -0
  43. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/fix-changelog.md +1 -0
  44. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-dependabot.md +2 -2
  45. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-token.md +4 -5
  46. repomatic-7.0.0/repomatic/templates/sync-action-pins.md +18 -0
  47. repomatic-7.0.0/repomatic/templates/sync-tool-versions.md +18 -0
  48. repomatic-7.0.0/repomatic/templates/sync-workflow-pins.md +18 -0
  49. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/tool_runner.py +407 -27
  50. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/uv.py +159 -125
  51. repomatic-7.0.0/repomatic/version_sync.py +482 -0
  52. repomatic-6.31.0/repomatic/checksums.py +0 -197
  53. repomatic-6.31.0/repomatic/data/renovate.json5 +0 -204
  54. repomatic-6.31.0/repomatic/data/renovate.yaml +0 -138
  55. repomatic-6.31.0/repomatic/data/skill-babysit-ci.md +0 -246
  56. repomatic-6.31.0/repomatic/data/skill-repomatic-ship.md +0 -147
  57. repomatic-6.31.0/repomatic/github/releases.py +0 -141
  58. repomatic-6.31.0/repomatic/renovate.py +0 -358
  59. repomatic-6.31.0/repomatic/templates/renovate-migration.md +0 -13
  60. repomatic-6.31.0/repomatic/tool_checksums.py +0 -223
  61. {repomatic-6.31.0 → repomatic-7.0.0}/license +0 -0
  62. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/__main__.py +0 -0
  63. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/binary.py +0 -0
  64. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/broken_links.py +0 -0
  65. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/cache.py +0 -0
  66. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/__init__.py +0 -0
  67. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/action-publish-pypi.yaml +0 -0
  68. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/agent-grunt-qa.md +0 -0
  69. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/agent-qa-engineer.md +0 -0
  70. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/autolock.yaml +0 -0
  71. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/ISSUE_TEMPLATE/config.yml +0 -0
  72. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/ISSUE_TEMPLATE/new-link.yaml +0 -0
  73. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/code-of-conduct.md +0 -0
  74. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/contributing.md +0 -0
  75. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/contributing.zh.md +0 -0
  76. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/funding.yml +0 -0
  77. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/.github/pull_request_template.md +0 -0
  78. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/__init__.py +0 -0
  79. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/awesome_template/license +0 -0
  80. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/bumpversion.toml +0 -0
  81. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/cancel-runs.yaml +0 -0
  82. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/codecov.yaml +0 -0
  83. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/labels.toml +0 -0
  84. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/lychee.toml +0 -0
  85. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/mdformat.toml +0 -0
  86. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/mypy.toml +0 -0
  87. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/pytest.toml +0 -0
  88. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-av-false-positive.md +0 -0
  89. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-awesome-triage.md +0 -0
  90. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-benchmark-update.md +0 -0
  91. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-brand-assets.md +0 -0
  92. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-file-bug-report.md +0 -0
  93. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-repomatic-init.md +0 -0
  94. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-repomatic-topics.md +0 -0
  95. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-sphinx-docs-sync.md +0 -0
  96. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-translation-sync.md +0 -0
  97. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/skill-upstream-audit.md +0 -0
  98. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/typos.toml +0 -0
  99. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/uv.toml +0 -0
  100. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/data/yamllint.yaml +0 -0
  101. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/__init__.py +0 -0
  102. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/actions.py +0 -0
  103. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/advisories.py +0 -0
  104. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/dev_release.py +0 -0
  105. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/gh.py +0 -0
  106. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/issue.py +0 -0
  107. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/pr.py +0 -0
  108. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/pr_body.py +0 -0
  109. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/release_sync.py +0 -0
  110. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/status.py +0 -0
  111. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/github/unsubscribe.py +0 -0
  112. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/images.py +0 -0
  113. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/mailmap.py +0 -0
  114. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/myst_converter.py +0 -0
  115. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/myst_docstrings.py +0 -0
  116. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/py.typed +0 -0
  117. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/pyproject.py +0 -0
  118. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/rst_to_myst.py +0 -0
  119. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/sponsor.py +0 -0
  120. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/__init__.py +0 -0
  121. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/available-admonition.md +0 -0
  122. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/broken-links-issue.md +0 -0
  123. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/bump-version.md +0 -0
  124. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/detect-squash-merge.md +0 -0
  125. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/development-warning.md +0 -0
  126. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/fix-typos.md +0 -0
  127. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/fix-vulnerable-deps.md +0 -0
  128. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-images.md +0 -0
  129. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-json.md +0 -0
  130. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-markdown.md +0 -0
  131. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-pyproject.md +0 -0
  132. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-python.md +0 -0
  133. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/format-shell.md +0 -0
  134. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/generated-footer.md +0 -0
  135. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/github-releases.md +0 -0
  136. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/immutable-releases.md +0 -0
  137. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/pr-metadata.md.noformat +0 -0
  138. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/prepare-release.md +0 -0
  139. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/refresh-tip.md +0 -0
  140. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/release-notes.md +0 -0
  141. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/release-sync-report.md +0 -0
  142. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-branch-ruleset.md +0 -0
  143. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-fork-pr-approval.md +0 -0
  144. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-pages-source.md +0 -0
  145. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-pypi-trusted-publisher.md +0 -0
  146. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-verify.md +0 -0
  147. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide-virustotal.md +0 -0
  148. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/setup-guide.md +0 -0
  149. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/sync-bumpversion.md +0 -0
  150. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/sync-gitignore.md +0 -0
  151. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/sync-mailmap.md +0 -0
  152. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/sync-repomatic.md +0 -0
  153. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/sync-uv-lock.md +0 -0
  154. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/unavailable-admonition.md +0 -0
  155. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/unsubscribe-phase1.md +0 -0
  156. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/unsubscribe-phase2.md +0 -0
  157. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/update-deps-graph.md +0 -0
  158. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/update-docs.md +0 -0
  159. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/templates/yanked-admonition.md +0 -0
  160. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/test_matrix.py +0 -0
  161. {repomatic-6.31.0 → repomatic-7.0.0}/repomatic/virustotal.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repomatic
3
- Version: 6.31.0
3
+ Version: 7.0.0
4
4
  Summary: 🏭 Automate repository maintenance, releases, and CI/CD workflows
5
- Keywords: changelog-formatter,dependabot-alternative,github-actions,github-labels,github-workflow,gitignore,mailmap,mypy,nuitka,python-automation,release-automation,renovate,repository-automation,repository-management,reusable-workflows,software-factory,sphinx-doc,typo,uv,workflow-reusable
5
+ Keywords: changelog-formatter,dependabot-alternative,github-actions,github-labels,github-workflow,gitignore,mailmap,mypy,nuitka,python-automation,release-automation,repository-automation,repository-management,reusable-workflows,software-factory,sphinx-doc,typo,uv,workflow-reusable
6
6
  Author: Kevin Deldycke
7
7
  Author-email: Kevin Deldycke <kevin@deldycke.com>
8
8
  License-Expression: GPL-2.0-or-later
@@ -50,7 +50,6 @@ Requires-Dist: click-extra>=8.1
50
50
  Requires-Dist: extra-platforms>=12.0.2
51
51
  Requires-Dist: packaging>=17
52
52
  Requires-Dist: py-walk>=0.3.1
53
- Requires-Dist: pydriller>=2
54
53
  Requires-Dist: pyproject-metadata>=0.9
55
54
  Requires-Dist: pyyaml>=6.0.3
56
55
  Requires-Dist: tomlrt>=1.7.6
@@ -59,7 +58,7 @@ Requires-Dist: wcmatch>=10
59
58
  Requires-Python: >=3.10
60
59
  Project-URL: Changelog, https://github.com/kdeldycke/repomatic/blob/main/changelog.md
61
60
  Project-URL: Documentation, https://kdeldycke.github.io/repomatic
62
- Project-URL: Download, https://github.com/kdeldycke/repomatic/releases/tag/v6.31.0
61
+ Project-URL: Download, https://github.com/kdeldycke/repomatic/releases/tag/v7.0.0
63
62
  Project-URL: Funding, https://github.com/sponsors/kdeldycke
64
63
  Project-URL: Homepage, https://github.com/kdeldycke/repomatic
65
64
  Project-URL: Issues, https://github.com/kdeldycke/repomatic/issues
@@ -89,7 +88,8 @@ A Python CLI and `pyproject.toml` configuration that let you **release Python pa
89
88
  - Cross-platform binary compilation (Linux / macOS / Windows, x86_64 / arm64)
90
89
  - Formatting autofix for Python, Markdown, JSON, Shell, and typos
91
90
  - Linting: Python types with mypy, YAML, GitHub Actions, workflow security, URLs, secrets, and Awesome lists
92
- - Synchronization of `uv.lock`, `.gitignore`, `.mailmap`, and Mermaid dependency graph
91
+ - Synchronization of `uv.lock`, GitHub Action pins, workflow version literals, and `repomatic run` tool versions with configurable stabilization cooldowns
92
+ - Synchronization of `.gitignore`, `.mailmap`, and Mermaid dependency graph
93
93
  - Label management with file-based and content-based rules
94
94
  - Inactive issue locking
95
95
  - Static image optimization
@@ -101,7 +101,7 @@ A Python CLI and `pyproject.toml` configuration that let you **release Python pa
101
101
  - [18 third-party GitHub Actions replaced](https://kdeldycke.github.io/repomatic/security.html#third-party-action-minimization) by internal CLI commands and SHA-256-verified binary downloads, keeping the supply chain attack surface minimal
102
102
  - [8 Python linters and formatters](https://kdeldycke.github.io/repomatic/security.html#ruff-consolidation) (pylint, black, isort, pyupgrade, pydocstyle, pycln, docformatter, blacken-docs) consolidated into ruff
103
103
  - [5 packaging and install tools](https://kdeldycke.github.io/repomatic/security.html#uv-consolidation) (poetry, build, twine, check-wheel-contents, pip-audit) consolidated into uv
104
- - All `uses:` references [pinned to full commit SHAs](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) via Renovate, with stabilization windows before adopting new versions
104
+ - All `uses:` references [pinned to full commit SHAs](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) with stabilization windows before adopting new versions, managed entirely by self-hosted sync jobs
105
105
  - [SLSA provenance attestations](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) on every release artifact (wheels and compiled binaries)
106
106
  - [VirusTotal scanning](https://kdeldycke.github.io/repomatic/security.html#av-false-positive-submissions) of compiled binaries to seed AV vendor databases and reduce false positives
107
107
  - [Trusted Publishing](https://kdeldycke.github.io/repomatic/workflows.html#github-workflows-release-yaml-jobs) for PyPI uploads: no long-lived tokens stored as secrets
@@ -5,7 +5,7 @@ requires = [ "uv-build>=0.9" ]
5
5
  [project]
6
6
  # Docs: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
7
7
  name = "repomatic"
8
- version = "6.31.0"
8
+ version = "7.0.0"
9
9
  description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
10
10
  readme = "readme.md"
11
11
  keywords = [
@@ -20,7 +20,6 @@ keywords = [
20
20
  "nuitka",
21
21
  "python-automation",
22
22
  "release-automation",
23
- "renovate",
24
23
  "repository-automation",
25
24
  "repository-management",
26
25
  "reusable-workflows",
@@ -86,9 +85,8 @@ dependencies = [
86
85
  # boltons 25.0.0 dropped Python 3.9, matching our requires-python >= 3.10.
87
86
  "boltons>=25",
88
87
  # 8.1.0 is the first release carrying the APIs repomatic uses: the `test-suite`
89
- # engine (renamed from `test-plan`), the `CONFIG_PATH_METADATA_KEY` /
90
- # `NORMALIZE_KEYS_METADATA_KEY` schema-metadata constants, and the
91
- # `@sort_by_option` / `ColumnSpec` `columns=` table registry.
88
+ # engine (renamed from `test-plan`) and the `CONFIG_PATH_METADATA_KEY` /
89
+ # `NORMALIZE_KEYS_METADATA_KEY` schema-metadata constants.
92
90
  "click-extra>=8.1",
93
91
  # extra-platforms 12.0.2 reimplemented is_macos() with sys.platform, avoiding
94
92
  # the platform.platform() shell-out to ``cmd /c ver`` on Windows that broke
@@ -101,8 +99,6 @@ dependencies = [
101
99
  # XXX Replace py-walk with wcmatch once the latter supports gitignore files:
102
100
  # https://github.com/facelessuser/wcmatch/issues/226
103
101
  "py-walk>=0.3.1",
104
- # pydriller 2.0 redesigned the API; Git, Commit, and Repository are core 2.x classes.
105
- "pydriller>=2",
106
102
  # pyproject-metadata 0.9 added PEP 639 (license expressions) and PEP 685 (extras
107
103
  # normalization); our StandardMetadata.from_pyproject() call benefits from these.
108
104
  "pyproject-metadata>=0.9",
@@ -126,7 +122,7 @@ dependencies = [
126
122
  ]
127
123
  urls.Changelog = "https://github.com/kdeldycke/repomatic/blob/main/changelog.md"
128
124
  urls.Documentation = "https://kdeldycke.github.io/repomatic"
129
- urls.Download = "https://github.com/kdeldycke/repomatic/releases/tag/v6.31.0"
125
+ urls.Download = "https://github.com/kdeldycke/repomatic/releases/tag/v7.0.0"
130
126
  urls.Funding = "https://github.com/sponsors/kdeldycke"
131
127
  urls.Homepage = "https://github.com/kdeldycke/repomatic"
132
128
  urls.Issues = "https://github.com/kdeldycke/repomatic/issues"
@@ -207,7 +203,7 @@ exclude-newer = "1 week"
207
203
  # "0 day" span. click-extra is held at its 8.1.0 release date so the lock adopts
208
204
  # it before the 1-week cooldown elapses; sync-uv-lock prunes this entry once
209
205
  # 8.1.0 ages past `exclude-newer`.
210
- exclude-newer-package = { click-extra = "2026-06-25T00:00:00Z", repomatic = "0 day" }
206
+ exclude-newer-package = { repomatic = "0 day" }
211
207
  # Package is at root level, not in "./src/".
212
208
  build-backend.module-root = ""
213
209
 
@@ -220,7 +216,7 @@ copyright = "Kevin Deldycke <kevin@deldycke.com> and contributors. Distributed u
220
216
  file-description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
221
217
  # Numeric only: Nuitka rejects PEP 440 .devN suffixes. Kept in sync with the
222
218
  # package version by the dedicated [tool.bumpversion] rule that strips the suffix.
223
- file-version = "6.31.0"
219
+ file-version = "7.0.0"
224
220
  include-data-dir = [
225
221
  "repomatic/data/awesome_template=repomatic/data/awesome_template",
226
222
  ]
@@ -238,7 +234,7 @@ include-package-data = [ "click_extra" ]
238
234
  linux-icon = "docs/assets/icon.png"
239
235
  macos-app-icon = "docs/assets/icon.icns"
240
236
  product-name = "Repomatic"
241
- product-version = "6.31.0"
237
+ product-version = "7.0.0"
242
238
  windows-icon-from-ico = "docs/assets/icon.ico"
243
239
 
244
240
  [tool.ruff]
@@ -249,6 +245,13 @@ show-fixes = true
249
245
  # Enable reformatting of code snippets in docstrings.
250
246
  # https://docs.astral.sh/ruff/formatter/#docstring-formatting
251
247
  format.docstring-code-format = true
248
+ # PLW1514: `open` and friends called without an explicit `encoding` argument.
249
+ # Windows defaults text I/O to cp1252, so a bare `open()`, `read_text()` or
250
+ # `write_text()` breaks on non-ASCII content, and only on Windows runners.
251
+ # Preview rule; its type inference misses unannotated `Path` locals, so
252
+ # PEP 597's `PYTHONWARNDEFAULTENCODING=1` remains the complete runtime net.
253
+ # See: https://docs.astral.sh/ruff/rules/unspecified-encoding/
254
+ lint.extend-select = [ "PLW1514" ]
252
255
  # D400: First line should end with a period.
253
256
  # Allows docstrings to end up with any punctuation, not just a period.
254
257
  # See: https://github.com/astral-sh/ruff/issues/1858#issuecomment-1382640623
@@ -311,10 +314,7 @@ pretty = true
311
314
  warn_unused_configs = true
312
315
  overrides = [
313
316
  { module = [
314
- "bumpversion.*",
315
- "gitdb.*",
316
317
  "py_walk.*",
317
- "pydriller.*",
318
318
  "vt",
319
319
  ], ignore_missing_imports = true },
320
320
  ]
@@ -325,7 +325,6 @@ addopts = [
325
325
  "--cov",
326
326
  "--cov-report=term",
327
327
  "--numprocesses=auto",
328
- "--dist=loadgroup",
329
328
  ]
330
329
  # https://docs.pytest.org/en/latest/customize.html#pyproject-toml
331
330
  markers = [
@@ -341,7 +340,7 @@ run.source = [ "repomatic" ]
341
340
  report.precision = 2
342
341
 
343
342
  [tool.bumpversion]
344
- current_version = "6.31.0"
343
+ current_version = "7.0.0"
345
344
  # Parse versions with an optional .devN suffix (PEP 440).
346
345
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\.dev(?P<dev>\\d+))?"
347
346
  serialize = [
@@ -425,6 +424,14 @@ exclude = [
425
424
  "^https://www\\.npmjs\\.com/package/.*$",
426
425
  # star-history.com fragments are JS-rendered and invisible to lychee.
427
426
  "^https://star-history\\.com/.*$",
427
+ # githubstatus.com returns 405 to HEAD requests from bots.
428
+ "githubstatus\\.com",
429
+ # Local intra-docs heading fragments are Sphinx cross-references, validated
430
+ # at doc build time via `myst_heading_anchors`. Lychee's GitHub-style slugger
431
+ # strips dots (`cache.dir` → `cachedir`) and cannot see MyST `(target)=`
432
+ # anchors, so it would false-positive links that resolve fine in the rendered
433
+ # docs. Anchored to `file://` so external `.../docs/*.md#` URLs stay checked.
434
+ "^file://.*/docs/[\\w.-]+\\.md#",
428
435
  ]
429
436
  exclude_path = [
430
437
  # Template files contain $variable placeholders that are not real URLs.
@@ -441,5 +448,6 @@ abandoned-versions = [
441
448
  "6.0.0",
442
449
  "6.18.0",
443
450
  ]
451
+ changelog.archive-location = "./docs/changelog-archive.md"
444
452
  exclude = [ "workflows" ]
445
453
  pypi-package-history = [ "gha-utils", "repokit" ]
@@ -21,7 +21,8 @@ A Python CLI and `pyproject.toml` configuration that let you **release Python pa
21
21
  - Cross-platform binary compilation (Linux / macOS / Windows, x86_64 / arm64)
22
22
  - Formatting autofix for Python, Markdown, JSON, Shell, and typos
23
23
  - Linting: Python types with mypy, YAML, GitHub Actions, workflow security, URLs, secrets, and Awesome lists
24
- - Synchronization of `uv.lock`, `.gitignore`, `.mailmap`, and Mermaid dependency graph
24
+ - Synchronization of `uv.lock`, GitHub Action pins, workflow version literals, and `repomatic run` tool versions with configurable stabilization cooldowns
25
+ - Synchronization of `.gitignore`, `.mailmap`, and Mermaid dependency graph
25
26
  - Label management with file-based and content-based rules
26
27
  - Inactive issue locking
27
28
  - Static image optimization
@@ -33,7 +34,7 @@ A Python CLI and `pyproject.toml` configuration that let you **release Python pa
33
34
  - [18 third-party GitHub Actions replaced](https://kdeldycke.github.io/repomatic/security.html#third-party-action-minimization) by internal CLI commands and SHA-256-verified binary downloads, keeping the supply chain attack surface minimal
34
35
  - [8 Python linters and formatters](https://kdeldycke.github.io/repomatic/security.html#ruff-consolidation) (pylint, black, isort, pyupgrade, pydocstyle, pycln, docformatter, blacken-docs) consolidated into ruff
35
36
  - [5 packaging and install tools](https://kdeldycke.github.io/repomatic/security.html#uv-consolidation) (poetry, build, twine, check-wheel-contents, pip-audit) consolidated into uv
36
- - All `uses:` references [pinned to full commit SHAs](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) via Renovate, with stabilization windows before adopting new versions
37
+ - All `uses:` references [pinned to full commit SHAs](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) with stabilization windows before adopting new versions, managed entirely by self-hosted sync jobs
37
38
  - [SLSA provenance attestations](https://kdeldycke.github.io/repomatic/security.html#supply-chain-security) on every release artifact (wheels and compiled binaries)
38
39
  - [VirusTotal scanning](https://kdeldycke.github.io/repomatic/security.html#av-false-positive-submissions) of compiled binaries to seed AV vendor databases and reduce false positives
39
40
  - [Trusted Publishing](https://kdeldycke.github.io/repomatic/workflows.html#github-workflows-release-yaml-jobs) for PyPI uploads: no long-lived tokens stored as secrets
@@ -17,5 +17,5 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = "6.31.0"
21
- __git_tag_sha__ = "3a04e66e0f653c320bf6e93a8d584f4bf9605a50"
20
+ __version__ = "7.0.0"
21
+ __git_tag_sha__ = "36523e5a56f287e814210042ca7b852147a95498"
@@ -812,6 +812,7 @@ def lint_changelog_dates(
812
812
  changelog_path: Path,
813
813
  package: str | None = None,
814
814
  *,
815
+ archive_path: Path | None = None,
815
816
  fix: bool = False,
816
817
  pypi_package_history: Sequence[str] = (),
817
818
  abandoned_versions: Sequence[str] = (),
@@ -853,6 +854,10 @@ def lint_changelog_dates(
853
854
  linking to adjacent versions.
854
855
 
855
856
  :param changelog_path: Path to the changelog file.
857
+ :param archive_path: Optional path to a frozen changelog archive. Versions
858
+ documented there are treated as present, suppressing false-positive
859
+ orphan detection (and re-insertion under `fix`) for entries split out
860
+ of the live changelog. Archived dates are not re-validated.
856
861
  :param package: PyPI package name. If `None`, auto-detected from
857
862
  `pyproject.toml`. If detection fails, falls back to git tags.
858
863
  :param fix: If True, fix dates and add admonitions to the file.
@@ -955,8 +960,16 @@ def lint_changelog_dates(
955
960
  # from the changelog.
956
961
  tag_versions = get_all_version_tags()
957
962
  changelog_headings = changelog.extract_all_version_headings()
963
+ # Versions documented in the frozen archive count as present, so entries
964
+ # split out of the live changelog are neither flagged nor re-inserted as
965
+ # orphans.
966
+ archive_headings: set[str] = set()
967
+ if archive_path and archive_path.exists():
968
+ archive_headings = Changelog(
969
+ archive_path.read_text(encoding="UTF-8")
970
+ ).extract_all_version_headings()
958
971
  all_known = set(pypi_data) | set(github_releases) | set(tag_versions)
959
- orphans = all_known - changelog_headings
972
+ orphans = all_known - changelog_headings - archive_headings
960
973
  if orphans:
961
974
  for orphan in sorted(orphans, key=Version):
962
975
  logging.warning(
@@ -0,0 +1,127 @@
1
+ # Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
2
+ #
3
+ # This program is Free Software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU General Public License
5
+ # as published by the Free Software Foundation; either version 2
6
+ # of the License, or (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program; if not, write to the Free Software
15
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
+
17
+ """Recompute SHA-256 checksums for the binary tool registry.
18
+
19
+ Iterates every `TOOL_REGISTRY` entry with a `binary` spec, downloads each
20
+ platform's release artifact, and rewrites stale hashes in-place in
21
+ `tool_runner.py` (alongside the `VERSIONS` stamps). Driven by
22
+ `repomatic update-checksums` and, with a version override, by
23
+ `sync-tool-versions` so a version bump and its matching checksums land in one
24
+ pass.
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import hashlib
30
+ import logging
31
+ import re
32
+ import sys
33
+ from pathlib import Path
34
+ from urllib.request import Request, urlopen
35
+
36
+ from click_extra import progressbar
37
+
38
+ from .tool_runner import TOOL_REGISTRY
39
+
40
+
41
+ def _download_sha256(url: str) -> str:
42
+ """Download a URL and return its SHA-256 hex digest.
43
+
44
+ :param url: The URL to download.
45
+ :return: Lowercase hex SHA-256 digest of the response body.
46
+ """
47
+ request = Request(url)
48
+ with urlopen(request) as response:
49
+ digest = hashlib.sha256(response.read()).hexdigest()
50
+ logging.debug(f"SHA-256 of {url}: {digest}")
51
+ return digest
52
+
53
+
54
+ def update_registry_checksums(
55
+ tool_runner_path: Path,
56
+ version_overrides: dict[str, str] | None = None,
57
+ ) -> list[tuple[str, str, str]]:
58
+ """Recompute binary checksums and version stamps in `tool_runner.py`.
59
+
60
+ Iterates every `TOOL_REGISTRY` entry with a `binary` spec, downloads each
61
+ platform URL, computes its SHA-256, and replaces stale hashes in-place.
62
+ Also reconciles each tool's `VERSIONS` stamp with the version the checksums
63
+ were computed for, the basis of the offline staleness test.
64
+
65
+ :param tool_runner_path: Path to `tool_runner.py`.
66
+ :param version_overrides: Optional mapping of tool name to a version to
67
+ download instead of the in-memory `ToolSpec.version`. `sync-tool-versions`
68
+ passes this so it can bump the version in the source and refresh the
69
+ checksums in a single process: the in-memory registry still holds the
70
+ pre-bump version because the file was edited, not reimported.
71
+ :return: List of `(url, old_hash, new_hash)` for each updated checksum.
72
+ Empty if all checksums are already correct.
73
+ """
74
+ overrides = version_overrides or {}
75
+ original = tool_runner_path.read_text(encoding="UTF-8")
76
+ content = original
77
+ updated: list[tuple[str, str, str]] = []
78
+
79
+ # Flatten all binary platform entries for progress tracking, resolving each
80
+ # download URL against the override version when one is supplied.
81
+ entries = [
82
+ (
83
+ spec,
84
+ pk,
85
+ tmpl.format(version=overrides.get(spec.name, spec.version)),
86
+ spec.binary.checksums[pk],
87
+ )
88
+ for spec in TOOL_REGISTRY.values()
89
+ if spec.binary is not None
90
+ for pk, tmpl in spec.binary.urls.items()
91
+ ]
92
+
93
+ with progressbar(
94
+ entries,
95
+ label="Verifying checksums",
96
+ file=sys.stderr,
97
+ ) as items:
98
+ for spec, platform_key, url, old_hash in items:
99
+ logging.info(
100
+ f"Verifying registry checksum for {spec.name} ({platform_key})"
101
+ )
102
+ new_hash = _download_sha256(url)
103
+
104
+ if old_hash != new_hash:
105
+ content = content.replace(old_hash, new_hash)
106
+ updated.append((url, old_hash, new_hash))
107
+ logging.info(f"Updated checksum: {old_hash} -> {new_hash}")
108
+ else:
109
+ logging.info("Checksum unchanged.")
110
+
111
+ # Reconcile each tool's VERSIONS stamp with its target version (idempotent).
112
+ # The key pattern only matches the quoted-string values in `VERSIONS`, never
113
+ # the `ToolSpec(` registry entries or the tuple-keyed `CHECKSUMS` entries.
114
+ for spec in TOOL_REGISTRY.values():
115
+ if spec.binary is None:
116
+ continue
117
+ target = overrides.get(spec.name, spec.version)
118
+ content = re.sub(
119
+ rf'("{re.escape(spec.name)}":\s*)"[^"]*"',
120
+ rf'\g<1>"{target}"',
121
+ content,
122
+ )
123
+
124
+ if content != original:
125
+ tool_runner_path.write_text(content, encoding="UTF-8")
126
+
127
+ return updated