From 6d6e84f8c2d64315e8e5807756a8e1848d36dc64 Mon Sep 17 00:00:00 2001 From: James Mineau Date: Tue, 27 Oct 2026 14:27:04 -0600 Subject: [PATCH] fix(ci): leave uv.lock to the Upgrade lock workflow, not Dependabot Remove the uv ecosystem from the Dependabot config. Since v1.3.0 the monthly Upgrade lock workflow runs uv lock --upgrade, which covers everything Dependabot's uv update does plus the newest release for each supported Python, and the two pull requests conflict. Dependabot keeps GitHub Actions and pre-commit hooks. The README, the generated CONTRIBUTING.md and the comments that said Dependabot updates uv.lock now say the workflow does. --- README.md | 2 +- template/.github/dependabot.yml | 16 ++-------------- .../.github/workflows/lock-upgrade.yml.jinja | 11 ++++++----- template/.pre-commit-config.yaml | 2 +- template/CONTRIBUTING.md.jinja | 17 +++++++++-------- 5 files changed, 19 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 33ccbc0..56616d6 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ first time is by hand; `copier update` takes over from then on. | pre-commit | pre-commit-hooks, rST checks, validate-pyproject, [zizmor](https://docs.zizmor.sh); `uv lock`, ruff and pyrefly run from `.venv`, so `uv.lock` pins their versions | | Changelog | Keep a Changelog, written at release (pull requests leave it alone): `just changelog` drafts the entries from Conventional Commits ([git-cliff](https://git-cliff.org)) | | CI | Tests (the chosen operating systems × all supported Pythons), Code Quality, Documentation, Publish (tag push → PyPI trusted publishing with attestations → GitHub Release from CHANGELOG → Zenodo) | -| Upkeep | Dependabot for actions, pre-commit hooks and `uv.lock` (monthly, grouped, 7-day cooldown; never raises minimum versions); a monthly workflow runs `uv lock --upgrade` and opens a pull request when the lock changes, so the newest release for each supported Python gets tested | +| Upkeep | Dependabot for actions and pre-commit hooks (monthly, grouped, 7-day cooldown); a monthly workflow runs `uv lock --upgrade` and opens a pull request when `uv.lock` changes, so the newest release for each supported Python gets tested (never raises minimum versions) | | Project files | AGENTS.md, CONTRIBUTING.md, CHANGELOG.md, CITATION.cff, `.zenodo.json`, issue forms, PR template | Generated projects score clean on the Scientific Python diff --git a/template/.github/dependabot.yml b/template/.github/dependabot.yml index 1a16699..4ac9c52 100644 --- a/template/.github/dependabot.yml +++ b/template/.github/dependabot.yml @@ -1,6 +1,7 @@ # Dependabot opens pull requests that update pinned versions. Each ecosystem # gets one grouped PR a month, and skips releases younger than a week -# (supply-chain safety). CI runs on each PR; merge it or close it. +# (supply-chain safety). CI runs on each PR; merge it or close it. uv.lock is +# not here: the Upgrade lock workflow (.github/workflows/lock-upgrade.yml) does it. version: 2 updates: # Actions used by the workflows (actions/checkout@v7, ...) @@ -24,16 +25,3 @@ updates: groups: pre-commit: patterns: ["*"] - - # uv.lock: the dev tools CI and contributors run. lockfile-only never raises - # the minimum versions in pyproject.toml, which would force them on users. - - package-ecosystem: uv - directory: / - schedule: - interval: monthly - cooldown: - default-days: 7 - versioning-strategy: lockfile-only - groups: - uv: - patterns: ["*"] diff --git a/template/.github/workflows/lock-upgrade.yml.jinja b/template/.github/workflows/lock-upgrade.yml.jinja index c9b288f..1b18a0a 100644 --- a/template/.github/workflows/lock-upgrade.yml.jinja +++ b/template/.github/workflows/lock-upgrade.yml.jinja @@ -1,11 +1,12 @@ name: Upgrade lock # Once a month, re-lock every dependency to its newest release and open one pull -# request when uv.lock changes (`uv lock --upgrade`). Dependabot's uv updates do -# not do this on their own: a package whose newest release needs a newer Python -# than the oldest one this project supports stays at its old version, so CI would -# test a release that users on a newer Python no longer get. `uv lock --upgrade` -# locks the newest release for each Python (a fork in uv.lock). +# request when uv.lock changes (`uv lock --upgrade`). It is the only thing that +# updates uv.lock (Dependabot does actions and pre-commit hooks). Dependabot's uv +# updates would leave a package whose newest release needs a newer Python than the +# oldest one this project supports at its old version, so CI would test a release +# that users on a newer Python no longer get. `uv lock --upgrade` locks the newest +# release for each Python (a fork in uv.lock). # # Setup, once: Settings > Actions > General > Workflow permissions > tick "Allow # GitHub Actions to create and approve pull requests". diff --git a/template/.pre-commit-config.yaml b/template/.pre-commit-config.yaml index 9ed47c3..5e54235 100644 --- a/template/.pre-commit-config.yaml +++ b/template/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: - id: zizmor # These run the tools in .venv, so their versions are the ones in uv.lock (one - # place to update; Dependabot does it) and pyrefly sees the project's + # place to update; the Upgrade lock workflow does it) and pyrefly sees the project's # dependencies. --no-sync: a hook never re-syncs .venv; run `just sync` after # changing dependencies. - repo: local diff --git a/template/CONTRIBUTING.md.jinja b/template/CONTRIBUTING.md.jinja index eb59211..7c7ee22 100644 --- a/template/CONTRIBUTING.md.jinja +++ b/template/CONTRIBUTING.md.jinja @@ -74,14 +74,15 @@ docs dropdown until the final release replaces them (see `DOCS_PRERELEASES` in ## Dependency updates -Dependabot opens one pull request a month per kind of pin: GitHub Actions, -pre-commit hooks, and `uv.lock` (the dev tools; it never raises the minimum -versions in `pyproject.toml`). Merge it when CI passes. - -Dependabot leaves a package at its old version when the newest release needs a -newer Python than the oldest one this project supports. So on the 1st of each -month the Upgrade lock workflow runs `uv lock --upgrade` (`uv.lock` then holds -the newest release for each Python) and, when the lock changes, opens the pull +Dependabot opens one pull request a month for each of GitHub Actions and +pre-commit hooks. Merge it when CI passes. + +`uv.lock` (the dev tools and every dependency) is updated by the Upgrade lock +workflow alone, not by Dependabot, which would leave a package at its old +version when the newest release needs a newer Python than the oldest one this +project supports. On the 1st of each month the workflow runs `uv lock --upgrade` +(`uv.lock` then holds the newest release for each Python; it never raises the +minimum versions in `pyproject.toml`) and, when the lock changes, opens the pull request `chore/lock-upgrade` (or updates it). GitHub does not start workflows on a pull request that its own token opened, so the workflow starts Tests, Code Quality and Documentation on the branch itself; their results show on the pull