chore: add dependabot.yml (pip + github-actions)#57
Conversation
Adds .github/dependabot.yml covering the two relevant ecosystems for mcp-synology: - pip: runtime + dev dependencies declared in pyproject.toml. uv.lock is co-located at the repo root, so Dependabot will keep that in sync as well. Runtime deps: mcp, httpx, keyring, pydantic, PyYAML, click. Dev extras: pytest, pytest-cov, pytest-asyncio, respx, ruff, mypy, types-PyYAML. - github-actions: every workflow file under .github/workflows/ (ci.yml, vdsm.yml, publish.yml, test-publish.yml, qa-gate.yml, pr-labels.yml, pr-labels-ci.yml) plus any composite/local action under .github/actions/. Schedule is weekly Monday 06:00 America/Chicago. Each ecosystem groups its updates into a single PR per week so notification noise stays low. Labels `dependencies` + ecosystem-tag (`python` / `github-actions`) — both already exist on the repo per `gh label list`. Commit prefix `chore(deps)`. No `docker` ecosystem because mcp-synology has no Dockerfile (it's a stdio-launched MCP server, not a deployed web service). If a future PR adds a containerized example, the docker block from cmeans/pypi-winnow-downloads#21 is the template to copy. Pattern ported from cmeans/pypi-winnow-downloads#21.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Preemptive doc-drift fix to avoid the same class of finding that QA flagged on PR #56: - Python comment now lists the [vdsm] extra (testcontainers, playwright) alongside runtime + dev. Dependabot already picks these up automatically because pyproject.toml is the source of truth, but the comment was incomplete and would mis-set expectations for a reader scanning the file. - GitHub Actions comment now names the local composite action at .github/actions/install-mcp-publisher rather than vague "any composite/local actions" wording. No functional change — Dependabot's behavior is unchanged.
# Conflicts: # CHANGELOG.md
After PR #58 merged, .github/workflows/dependabot-changelog.yml joined the workflow set Dependabot watches via the github-actions ecosystem. Updated the comment so the listed workflows match the actual contents of .github/workflows/. No functional change — Dependabot already tracks the new workflow because it's matched by the ecosystem-wide directory glob.
cmeans
left a comment
There was a problem hiding this comment.
QA Round 1 — PR #57
(Dev's third internal round, my first as QA.) Most of the config is solid and verified against the codebase. One substantive finding caught by checking the source pattern's live Dependabot output, plus a few notes.
Verification on 32ebb54
| Check | Result |
|---|---|
Dependabot server-side validation (.github/dependabot.yml check) |
SUCCESS |
python3 yaml.safe_load(...) |
parses (version=2, two updates) |
uv run pytest |
499 passed, 94 deselected, 96.04% coverage |
uv run ruff check src/ tests/ scripts/ |
clean |
uv run ruff format --check |
69 files clean |
uv run mypy src/ scripts/ |
clean |
| Required CI rollup | all green (lint, typecheck, test 3.11/3.12/3.13, version-sync, validate-server-json, vdsm) |
| Workflow comment listing 8 files | matches ls .github/workflows/ exactly: ci.yml, dependabot-changelog.yml, pr-labels-ci.yml, pr-labels.yml, publish.yml, qa-gate.yml, test-publish.yml, vdsm.yml |
| Composite action reference | .github/actions/install-mcp-publisher/ exists |
Runtime-deps comment vs pyproject.toml |
matches: mcp, httpx, pyyaml, keyring, pydantic, click |
[dev] extras comment vs pyproject.toml |
matches set: pytest, pytest-asyncio, pytest-cov, respx, ruff, mypy, types-PyYAML |
[vdsm] extras comment vs pyproject.toml |
matches: testcontainers, playwright |
Labels dependencies / python / github-actions exist on repo |
all three present (plus pre-existing python:uv) |
Findings
1. [substantive] commit-message.prefix: "chore(deps)" combined with include: "scope" produces double-scope commit subjects like chore(deps)(deps): bump foo.
include: "scope" auto-appends (deps) (or (deps-dev)) to the prefix. With a prefix that already contains (deps), the scope is doubled. This isn't speculative — confirmed by checking the source-pattern repo this config was ported from:
$ gh api search/issues -f q='repo:cmeans/pypi-winnow-downloads is:pr author:app/dependabot'
- #24: "chore(deps)(deps): bump python from 3.13-slim to 3.14-slim in /deploy/docker"
- #23: "chore(deps)(deps): bump codecov/codecov-action from 5 to 6 in the github-actions group"
cmeans/pypi-winnow-downloads has the same prefix: "chore(deps)" + include: "scope" config and is producing the doubled prefix on every Dependabot PR right now.
Two equivalent fixes — pick whichever fits intent:
# Option A — drop include, keep explicit prefix:
commit-message:
prefix: "chore(deps)"
# (no include: scope)
# Option B — let Dependabot auto-append the scope:
commit-message:
prefix: "chore"
include: "scope"
# Optional: prefix-development: "chore" to also tag dev-depsBoth produce chore(deps): bump foo. B is the canonical pattern from Dependabot's docs and lets you later add prefix-development to distinguish prod vs dev dep bumps without touching the prefix.
Worth filing the same fix as a follow-up PR on cmeans/pypi-winnow-downloads, since the bug originates there.
Observations
2. [observation] First Dependabot PR after merge will exercise the auto-CHANGELOG workflow from #58. With this PR's groups.python and groups.github-actions, the first auto-CHANGELOG entry should land as "Bump python group: ..." or "Bump github-actions group: ..." (the dependency-group output). Worth keeping the post-merge test-plan item to confirm both the dependabot-changelog workflow runs end-to-end and the commit-message prefix is well-formed (after F1 fix lands).
Verdict
QA Failed pending finding 1.
Round-3 deltas (Dev-side latent label bug + cross-PR drift) verified clean — all three labels exist on the repo, workflow comment now correctly includes dependabot-changelog.yml, and 5 of 6 test-plan checkboxes are ticked (the 6th is correctly post-merge).
QA audit — round 1 (Dev's round 3)Branch / SHA: `chore/dependabot-config` @ `32ebb54` Live-state verification of the source pattern (caught F1): ``` {"number":24,"state":"open","title":"chore(deps)(deps): bump python from 3.13-slim to 3.14-slim in /deploy/docker"}{"number":23,"state":"open","title":"chore(deps)(deps): bump codecov/codecov-action from 5 to 6 in the github-actions group"}``` The source pattern's dependabot.yml uses the same `prefix: "chore(deps)"` + `include: "scope"` combo and is producing doubled `(deps)` on every PR right now. Per `feedback_anchor_on_live_deployment.md`, anchoring on the live deployment surfaced this where reading the config alone wouldn't have been definitive. Local stack: Cross-checks:
Outcome: QA Failed — see review comment for F1 (substantive: doubled `(deps)` scope from `prefix` + `include` combo). |
QA round-3 finding: `prefix: "chore(deps)"` combined with `include: "scope"` produces double-scope commit subjects like `chore(deps)(deps): bump foo` because Dependabot auto-appends `(deps)` (or `(deps-dev)`) to the prefix when scope-include is on. Confirmed in cmeans/pypi-winnow-downloads, where the same config is producing doubled prefixes on every live Dependabot PR (e.g. PR #23 "chore(deps)(deps): bump codecov/codecov-action ..."). Canonical Dependabot pattern: `prefix: "chore"` + `include: "scope"` yields `chore(deps): bump foo`. This also leaves room to add `prefix-development: "chore"` later if we want to distinguish prod vs dev dep bumps in commit subjects without touching the core prefix. Same fix should be cascaded to cmeans/pypi-winnow-downloads as a follow-up — the bug originates from that pattern repo.
cmeans
left a comment
There was a problem hiding this comment.
QA Round 2 — PR #57
Round-1 finding — verified closed on abf9a34
| Finding | Status | Evidence |
|---|---|---|
F1 (doubled (deps) from prefix: "chore(deps)" + include: "scope") |
✅ closed | Both ecosystems now use prefix: "chore" + include: "scope" (canonical Dependabot pattern). Auto-appended scope will produce chore(deps): bump foo. Sets up future room for prefix-development if dev/prod scope distinction is added later. |
Verification on abf9a34
| Check | Result |
|---|---|
| Dependabot server-side validation | SUCCESS |
| YAML structural re-parse | both ecosystems: prefix='chore' include='scope' |
uv run pytest |
499 passed, 94 deselected, 96.04% coverage |
uv run ruff check src/ tests/ scripts/ |
clean |
uv run mypy src/ scripts/ |
clean (29 source files) |
| Required CI rollup | all green (lint, typecheck, test 3.11/3.12/3.13, version-sync, validate-server-json, vdsm) |
Verdict
Ready for QA Signoff. F1 closed; no new findings. QA Approved remains the maintainer's call.
Post-merge confirmation items (already in test plan):
- Settings → Code security → Dependabot shows both ecosystems Active.
- First Dependabot PR's commit subject is
chore(deps): bump foo(no doubled scope). - The
dependabot-changelogworkflow from #58 fires end-to-end and produces "Bump python group: ..." or "Bump github-actions group: ..." entries.
Side note: the same fix is worth porting to cmeans/pypi-winnow-downloads (PRs #23/#24 there currently have chore(deps)(deps): ... titles). Out of scope for this PR.
QA audit — round 2Branch / SHA: `chore/dependabot-config` @ `abf9a34` ``` Both pip and github-actions blocks: prefix changed from "chore(deps)" → "chore"; include: scope retained.Will produce canonical "chore(deps): bump foo" subjects.uv run pytest # 499 passed, 94 deselected, 96.04% Outcome: Ready for QA Signoff. F1 closed, no new findings. `QA Approved` remains the maintainer's call. |
Closes the auto-CHANGELOG empty-versions bug surfaced by live Dependabot PR #59. Root cause: dependabot/fetch-metadata@v2.5.0 returns empty-string prevVersion / newVersion for every package in a grouped update. The workflow's inline Python used d.get('prevVersion', '?'), which only falls back on missing keys — empty strings render as nothing. Upstream PR dependabot/fetch-metadata#632 (shipped v3.0.0, refined v3.1.0) added body-metadata parsing for multi-dependency PRs, so the durable fix is just the SHA bump: dependabot/fetch-metadata 21025c705c08248db411dc16f3619e6b5f9ea21a (v2.5.0) → 25dd0e34f4fe68f24cc83900b1fe3fe149efef98 (v3.1.0) No inline-Python changes needed. v3 also requires Node.js 24 as the Actions runtime, clearing the Node.js-20 deprecation warning the v2 line was emitting on every run. Verification gate (per don't-propagate-unverified-fixes rule): 1. ✅ Land this fix on main 2. @dependabot recreate PR #59 3. Confirm the recreated PR's CHANGELOG entry reads correctly 4. ONLY THEN consider cascading the broader Dependabot-PR-hygiene work + the doubled-prefix fix from #57 to cmeans/pypi-winnow-downloads Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds
.github/dependabot.ymlso Dependabot can open weekly PRs for outdated dependencies. Two ecosystems are tracked:pyproject.toml;uv.lockis at the repo root so Dependabot will keep it in sync. Runtime:mcp,httpx,keyring,pydantic,PyYAML,click. Dev:pytest,pytest-cov,pytest-asyncio,respx,ruff,mypy,types-PyYAML. vdsm extra:testcontainers,playwright..github/workflows/(ci.yml,vdsm.yml,publish.yml,test-publish.yml,qa-gate.yml,pr-labels.yml,pr-labels-ci.yml,dependabot-changelog.yml) plus the local composite action at.github/actions/install-mcp-publisher.Schedule weekly Monday 06:00 America/Chicago, single grouped PR per ecosystem, labels
dependencies+ ecosystem-tag (python/github-actions), commit subjects render aschore(deps): bump <pkg>viaprefix: "chore"+include: "scope"(Dependabot auto-appends the(deps)scope).No
dockerecosystem because mcp-synology has no Dockerfile. Pattern ported from cmeans/pypi-winnow-downloads#21 (with the doubled-scope commit-prefix bug fixed — see round 3 deltas).Round 3 → Round 4 deltas
prefix: "chore(deps)"+include: "scope"produceschore(deps)(deps): bump foobecause Dependabot auto-appends(deps)to the prefix. QA verified the bug live on cmeans/pypi-winnow-downloads (PR Fix all 5 remaining vdsm test failures (42/47 → 47/47) #23:chore(deps)(deps): bump codecov/codecov-action ...). Switched toprefix: "chore"+include: "scope"(canonical Dependabot pattern) on both update blocks.Round 2 → Round 3 deltas
pythonandgithub-actionslabels on the repo (Dependabot silently skips labels it can't find).mainto pick up chore: community health files (CONTRIBUTING, CoC, SECURITY) #56 + chore: dependabot PR hygiene (PR template + auto-CHANGELOG workflow) #58; updated the github-actions comment to includedependabot-changelog.yml.Follow-up out of scope here
The doubled-scope bug also lives in
cmeans/pypi-winnow-downloads/.github/dependabot.yml. Worth opening a one-line follow-up PR there to apply the same fix. Not in scope for this PR — that's the upstream pattern repo, not this one.Test plan
python -c "import yaml; yaml.safe_load(open('.github/dependabot.yml'))"— YAML parsesdependencies,python, andgithub-actionslabels all exist on the repo## Unreleased→### Addedreferences this PR (chore: add dependabot.yml (pip + github-actions) #57).github/workflows/(8 files: ci, vdsm, publish, test-publish, qa-gate, pr-labels, pr-labels-ci, dependabot-changelog)pyproject.toml(runtime +[dev]+[vdsm])prefix: "chore"+include: "scope"renderschore(deps): bump <pkg>, notchore(deps)(deps): ...chore(deps): bump <pkg>) and the auto-CHANGELOG workflow from chore: dependabot PR hygiene (PR template + auto-CHANGELOG workflow) #58 prepends an entry referencing the named group ("python" or "github-actions")