chore: add dependabot version-update configuration#94
Conversation
Adds .github/dependabot.yml tracking pip and github-actions ecosystems on a weekly Monday 06:00 CT schedule, grouped per ecosystem with chore(deps) commit prefix. Mirrors the config shipped to cmeans/pypi-winnow-downloads but omits the docker ecosystem since this repo has no Docker deployment. Labels dependencies, python, and github-actions already exist on the repo so PRs will be categorized on creation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
cmeans
left a comment
There was a problem hiding this comment.
QA Review — Round 1
Verification (current session)
| Check | Result |
|---|---|
uv run ruff check src/ tests/ |
clean (CI scope) |
uv run mypy src/ |
clean (4 source files) |
uv run pytest -q |
488 passed, 6 deselected, 5 xfailed |
YAML parse (yaml.safe_load) |
clean; 2 update entries present |
Repo labels dependencies / python / github-actions |
all exist with declared colors |
/repos/.../automated-security-fixes |
enabled: true, paused: false |
| Deselected count | tests/test_integration.py opted out via addopts = "-m 'not integration'" (real-clipboard, expected) |
| xfailed count | 5 documented newline-in-cell structural limitations (pre-existing) |
Test plan items 1–3 are all post-merge spot-checks; none can be exercised pre-merge.
Findings
| # | Finding | Suggested fix |
|---|---|---|
| 1 | Substantive — commit-message.prefix: "chore(deps)" combined with include: "scope" produces double-scope PR titles (chore(deps)(deps): bump x), which contradicts the PR body's stated intent ("with a chore(deps) commit prefix"). Concrete evidence from sibling repos using the identical combo: cmeans/mcp-awareness#345 (chore(deps)(deps): bump ollama/ollama …), #346 (chore(deps)(deps): bump python …); cmeans/pypi-winnow-downloads#23 (chore(deps)(deps): bump codecov/codecov-action …), #24 (chore(deps)(deps): bump python …). The github-actions ecosystem in this PR will produce the same doubled titles. |
Pick one: (a) drop include: "scope" from both ecosystem entries — titles become chore(deps): bump x; or (b) change prefix: "chore(deps)" to prefix: "chore" and keep include: "scope" — titles become chore(deps): bump x for runtime and chore(deps-dev): bump x for dev extras (better signal, and matches the form mcp-awareness's uv-routed PRs already produce — e.g. #339 chore(deps): bump pytest …). Option (b) is the more useful long-term shape if applied house-wide. |
| 2 | Substantive (doc drift) — inline comment block for the pip ecosystem says "Covers runtime (mcp[cli]) and dev extras (pytest, pytest-asyncio)", but pyproject.toml [project.optional-dependencies] dev lists five entries: pytest, pytest-asyncio, pytest-cov, ruff, mypy. Comment undercounts. |
Either enumerate fully or shorten to "and dev extras". |
| 3 | Observation — package-ecosystem: "pip" for a uv-managed project (pyproject.toml + committed uv.lock). Per the GitHub supported-ecosystems table and the astral uv guide, uv has been a distinct ecosystem since GA 2025-03-13 and is the documented value for uv projects. Empirically, sibling-repo evidence (mcp-awareness PRs #339/#341/#342 with branch path dependabot/uv/... from a pip-only YAML) shows pip ecosystem currently auto-routes to uv handling when uv.lock is detected — which is what makes test-plan item 3 plausible — but this routing is undocumented and not guaranteed to persist. |
Switch the Python entry to package-ecosystem: "uv". Forward-compatible with docs, removes reliance on undocumented auto-routing, and (combined with finding 1 option b) gives clean chore(deps) / chore(deps-dev) differentiation. |
Verdict
QA Failed — Findings 1 and 2 are substantive (PR body and inline comment both drift from reality); finding 3 is an observation that blocks signoff per project policy. None of the test-plan items are pre-merge testable, so resolution of the three findings + a re-review pass is what unblocks signoff. Once the config is amended, I'll re-run verification and confirm.
|
Applying QA Failed as the final act of round 1: 2 substantive findings (commit-message double-scope contradicting the PR body intent; inline comment undercount of dev extras) plus 1 observation (recommend explicit |
Per the dependabot-pr-hygiene playbook (awareness logical_key dependabot-pr-hygiene-playbook): combining prefix: chore(deps) with include: scope produces commit subjects like chore(deps)(deps): bump foo because Dependabot auto-appends (deps) whenever include: scope is set. The canonical pattern is bare prefix: chore plus include: scope, which yields chore(deps): bump foo as intended. Caught before any Dependabot PR opened against this repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans
left a comment
There was a problem hiding this comment.
QA Review — Round 2
Round-2 head 23c1db9 (fix(dependabot): use bare chore prefix to avoid doubled (deps) scope).
Round-1 status
| # | Round-1 finding | Round-2 status |
|---|---|---|
| 1 | prefix: "chore(deps)" + include: "scope" produces doubled chore(deps)(deps) titles |
Fixed. Both ecosystem entries now use prefix: "chore" + include: "scope". Output will be chore(deps): bump x for runtime and chore(deps-dev): bump x for dev extras — canonical Dependabot shape and matches the dependabot-pr-hygiene playbook (mcp-synology #57). CHANGELOG entry rewritten to describe the new shape and reference the playbook. |
| 2 | Inline pip-group comment undercounts dev extras: lists pytest, pytest-asyncio but pyproject.toml has 5 (pytest, pytest-asyncio, pytest-cov, ruff, mypy) |
Not addressed. .github/dependabot.yml:24 is unchanged. Repo-wide grep confirms the drift is local to this file (CLAUDE.md mentions pytest+pytest-asyncio only in the narrower context of async test mode, not as a dev-extras enumeration). |
| 3 | package-ecosystem: "pip" for a uv-managed project |
Acceptable as-is. Sibling repos in the cascade (mcp-synology, pypi-winnow-downloads) keep pip with named groups; auto-routing to uv handling is empirically reliable. Closing as house-style consistent with the dependabot-pr-hygiene playbook. |
Verification (current session, head 23c1db9)
| Check | Result |
|---|---|
uv run pytest -q |
488 passed, 6 deselected (-m 'not integration'), 5 xfailed |
uv run ruff check src/ tests/ |
clean |
uv run mypy src/ |
clean |
yaml.safe_load(.github/dependabot.yml) |
clean; 2 update entries |
CI rollup (lint/typecheck/test 3.11–3.13/codecov-patch/qa-approved/.github/dependabot.yml validator) |
all SUCCESS |
Verdict
QA Failed — F2 remains. The fix is one line at .github/dependabot.yml:24: either enumerate the full dev-extras (pytest, pytest-asyncio, pytest-cov, ruff, mypy) or shorten to a non-enumerating phrase (e.g., # Covers runtime (mcp[cli]) and the dev extras declared in pyproject.toml). Once that lands I'll re-toggle QA Active and sign off — no other concerns.
|
Round-2 verdict: QA Failed. F1 cleanly fixed (canonical |
…mment Round-2 QA F2: the inline comment listed "pytest, pytest-asyncio" but pyproject.toml's [project.optional-dependencies] dev has five entries (pytest, pytest-asyncio, pytest-cov, ruff, mypy). Shortening to a non-enumerating phrase that points at pyproject.toml as the source of truth avoids future drift if dev extras change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans
left a comment
There was a problem hiding this comment.
QA Review — Round 3
Round-3 head f6ffdf5 (docs(dependabot): drop the dev-extras enumeration in pip ecosystem comment).
Round-2 status
| # | Round-2 finding | Round-3 status |
|---|---|---|
| 2 | Inline pip-group comment undercounts dev extras | Fixed. .github/dependabot.yml:23-24 now reads # Covers runtime (mcp[cli]) and the dev extras declared in pyproject.toml. — non-enumerating phrasing, no future drift risk. |
Verification (current session, head f6ffdf5)
| Check | Result |
|---|---|
uv run pytest -q |
488 passed, 6 deselected (-m 'not integration'), 5 xfailed |
uv run ruff check src/ tests/ |
clean |
uv run mypy src/ |
clean |
yaml.safe_load(.github/dependabot.yml) |
clean; 2 update entries |
| CI rollup | lint / typecheck / test 3.11–3.13 / on-push / qa-approved / .github/dependabot.yml validator / codecov-patch all SUCCESS |
Test plan
Items 1–3 are all post-merge spot-checks — cannot be ticked pre-merge. They remain unchecked in the PR body intentionally.
Verdict
Ready for QA Signoff. Zero open findings. F1 (canonical chore(deps) shape) and F2 (non-enumerating dev-extras comment) both clean; F3 (pip ecosystem) closed as house-style consistent with the dependabot-pr-hygiene cascade. Awaiting maintainer QA Approved.
Post-merge follow-ups (independent of this PR):
- Verify Actions tab shows a Dependabot run after merge (test plan #1)
- First-week PRs should land with
chore(deps): bump xtitles and the configured labels (test plan #2) - A pip-group PR should include uv.lock alongside pyproject.toml (test plan #3 — relies on the documented pip→uv auto-routing observed in mcp-awareness #339/#341/#342)
- Cascade context: the auto-CHANGELOG workflow + PR template + App-token mint (mcp-synology #58/#60, currently in pypi-winnow-downloads validation) is a separate piece of work, blocked here on
BOT_APP_ID/BOT_APP_PRIVATE_KEYrepo secrets being configured oncmeans/mcp-clipboardand on pypi-winnow-downloads finishing live-validation per the don't-propagate-unverified-fixes gate.
|
Applying Ready for QA Signoff as the final act of round 3: F2 cleanly addressed by non-enumerating phrasing (no future drift risk), all CI green on |
…rkflow) (#96) ## Summary Cascades the dependabot-pr-hygiene playbook from `cmeans/mcp-synology` (PR #58) and `cmeans/pypi-winnow-downloads` (PR #25) onto this repo, completing parity with the other two repos in the cascade. Builds on PR #94, which landed `.github/dependabot.yml`. ## What's added - **`.github/PULL_REQUEST_TEMPLATE.md`** — auto-fills new human-authored PR bodies with Summary, Test plan, and CHANGELOG sections. Test plan items match this repo's CI commands exactly (`uv run pytest`, `uv run ruff check src/ tests/`, `uv run ruff format --check src/ tests/`, `uv run mypy src/mcp_clipboard/`). Dependabot bypasses the template. - **`.github/workflows/dependabot-changelog.yml`** — `pull_request_target` workflow filtered to `dependabot[bot]`. Mints a GitHub App installation token (so commits attribute correctly and would re-fire required `pull_request` workflows under any future ruleset change), runs `dependabot/fetch-metadata@v3.1.0` (the v3 line fixed empty `prevVersion`/`newVersion` on grouped PRs, per the playbook's Gotcha 3), and prepends an `## [Unreleased]` → `### Changed` entry to `CHANGELOG.md`. Includes the post-#26 fix: subsection creation respects Keep-a-Changelog v1.1.0 ordering (`Added → Changed → Deprecated → Removed → Fixed → Security`) so a freshly-created `### Changed` lands in the right position. Tolerant of both `## Unreleased` and `## [Unreleased]` heading forms; defaults to brackets on creation to match this repo's existing style. - **`CLAUDE.md § Conventions`** — documents the per-PR CHANGELOG rule and the Keep-a-Changelog category set (`Added` / `Changed` / `Fixed`), mirroring mcp-synology's CLAUDE.md. ## Operator action required Before the workflow can run, configure two repo secrets on `cmeans/mcp-clipboard`: - `BOT_APP_ID` — numeric `3223881` - `BOT_APP_PRIVATE_KEY` — full PEM contents Without those secrets the App-token mint step fails fast and Dependabot PRs land without an auto-CHANGELOG entry. Dependabot's first scheduled run is Monday 06:00 America/Chicago, so there is time after merge to configure secrets. ## Notes vs the other repos in the cascade - This repo's CHANGELOG uses `## [Unreleased]` (with brackets); mcp-synology uses `## Unreleased` (no brackets). The workflow's heading matcher accepts either form (same as pypi-winnow-downloads' adapted version) and preserves whichever it found. - This repo's `main` ruleset does not currently require status checks, so the App-token mechanism is technically optional here — `secrets.GITHUB_TOKEN` would be sufficient. App-token is kept anyway for parity, correct bot attribution, and forward-compatibility with any future ruleset tightening. ## Test plan - [ ] After merge, configure `BOT_APP_ID` + `BOT_APP_PRIVATE_KEY` repo secrets - [ ] Confirm `.github/workflows/dependabot-changelog.yml` shows up in Actions tab - [ ] On the next Dependabot PR (Monday 06:00 CT or `@dependabot recreate` an earlier one once it exists), confirm the auto-CHANGELOG commit lands attributed to `cmeans-claude-dev[bot]` with subject `chore(changelog): record dep bumps from #N` - [ ] Confirm the CHANGELOG entry lands under `### Changed` with correct version arrows (e.g., `actions/checkout 4→6`) - [ ] Spot-check that opening a fresh human-authored PR auto-fills the template body Co-authored-by: cmeans-claude-dev[bot] <272174644+cmeans-claude-dev[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump pyproject.toml 2.2.1 -> 2.3.0 and convert the [Unreleased] block into [2.3.0] - 2026-05-02. A fresh empty [Unreleased] section sits above for the next cycle. 13 PRs aggregated since v2.2.1: #88, #92, #93, #94, #95, #96, #98, #99, #100, #101, #102, #103, #104. Tag-push (v2.3.0) after merge triggers .github/workflows/publish.yml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
.github/dependabot.ymltracking the pip and github-actions ecosystems on a weekly Monday 06:00 America/Chicago schedule, grouped per ecosystem with achore(deps)commit prefix.dependencies,python,github-actions) are referenced so Dependabot PRs are categorized on creation. Labels not declared here are left to the existing label-automation workflows.Notes
.github/dependabot.ymlonly takes effect once "Dependabot version updates" is enabled at the repo level (Settings -> Code security and analysis). Confirmed enabled.Test plan
chore(deps)prefixpipgroup PR includesuv.lockupdates alongsidepyproject.toml