ci(dependabot): move config to canonical path GitHub reads (closes #235)#240
ci(dependabot): move config to canonical path GitHub reads (closes #235)#240cagataycali wants to merge 4 commits into
Conversation
…rands-labs#235) .github/workflows/dependabot.yml is in the wrong directory and is silently ignored by Dependabot. The canonical path that Dependabot actually reads is .github/dependabot.yml. The file in workflows/ is valid YAML, parses fine, ships on main -- but Dependabot never sees it. Net effect of the misplacement (window: strands-labs#92 onward): * pip ecosystem grouping for torch / lerobot / transformers / huggingface-hub never fired; the ML stack updates surface only via manual sweep (PR strands-labs#153 was the manual catch-up). * github-actions ecosystem entry that's supposed to keep workflow SHA pins fresh after strands-labs#92 / strands-labs#234 was inactive; every action pin became manual maintenance. * dev-tools group (ruff / mypy / pytest*) similarly never fired. This commit is a verbatim git mv -- the config content (version 2, pip + github-actions ecosystems, weekly Monday schedule, three grouped pip patterns) is correct as-written and unchanged. Docs reference: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file Pin test (tests/test_dependabot_config_path.py, 5 cases): 1. test_dependabot_yml_at_canonical_path -- canonical file exists. 2. test_dependabot_yml_not_at_historical_wrong_path -- the workflows/-shaped placement bug is blocked from coming back. 3. test_dependabot_yml_minimum_viable_schema -- top-level is a mapping with version: 2 + non-empty updates list, every entry declares package-ecosystem. Catches typos that pass YAML parsing but Dependabot silently ignores (version: 1, updates: {}, update: singular, missing package-ecosystem on an entry). 4-5. test_dependabot_covers_expected_ecosystems[pip|github-actions] -- pin that the two ecosystems the repo actually depends on stay in scope. Either going missing silently regresses dependency hygiene; the ML stack and the workflow SHA pinner are both load-bearing per strands-labs#92 review learnings. Verification: pin discipline (AGENTS.md > Review Learnings strands-labs#85): * Pre-fix state (config at workflows/dependabot.yml): all 5 fail with diagnostic messages naming the canonical path. * Post-fix state (config at .github/dependabot.yml): all 5 pass. Lint: ruff check + ruff format --check -- clean. Non-ASCII sweep: grep -nP '[^\\x00-\\x7F]' tests/test_dependabot_config_path.py -- empty. Refs: strands-labs#235, strands-labs#234, strands-labs#92, strands-labs#153.
yinsong1986
left a comment
There was a problem hiding this comment.
Summary
Pure config-placement fix: git mv of .github/workflows/dependabot.yml to the canonical .github/dependabot.yml path, plus a 5-case pin test (tests/test_dependabot_config_path.py) that asserts canonical placement, blocks the historical wrong path, and pins minimum-viable v2 schema (version: 2, non-empty updates, every entry declares package-ecosystem). Content of the YAML is byte-identical to the old file (verified locally via diff); no behavioural change beyond Dependabot now actually reading the config.
Directly aligned with AGENTS.md > Review Learnings (#92) > Action Pinning: "Dependabot keeps these fresh via the github-actions ecosystem entry." Without this PR, that line in the conventions doc is aspirational rather than enforced. The pin test follows the "Pin regression tests for reviewed fixes" pattern (Review Learnings #85).
What's good
- Smallest possible diff that closes #235 — pure rename + pin test, no scope creep into the surrounding workflow files.
test_dependabot_yml_not_at_historical_wrong_pathblocks the regression both ways (canonical present and wrong path absent), which is the correct shape for a placement-bug fix.- The verification trail in the PR description (pre-fix: 5 failed → post-fix: 5 passed; lint clean; non-ASCII sweep empty) follows the pin-discipline pattern from Review Learnings #85.
- Schema test catches the silent-failure modes Dependabot is notorious for (
version: 1,updates: {},update:singular, missingpackage-ecosystem).
Concerns
- Acceptance criteria are post-merge-only for two of four checkboxes (Settings panel showing "Active"; first weekly Monday PR firing). Worth flagging in the merge comment so the maintainer remembers to verify after squash-merge — otherwise we land this and assume it works without confirming Dependabot actually picked it up server-side.
- Schema test is narrower than "minimum-viable" — it pins
package-ecosystemper entry but notdirectoryorschedule.interval, both of which are also required by Dependabot v2 and silently disable an entry if missing. See inline on the schema test. - Missing trailing newline on the new
.github/dependabot.yml(carried over from the pre-rename file; the diff shows\ No newline at end of file). Cannot anchor an inline since the file is a pure rename with zero hunk lines, but it's a one-byte cleanup that belongs in the same PR — a future edit toopen-pull-requests-limitwill otherwise show a churn line for it. dev-toolsgroup inactivity not in the test surface. The PR description calls out that thedev-toolsgroup (ruff/mypy/pytest*) also never fired, but the parametrized ecosystem test only pinspipandgithub-actionsat the ecosystem level — group-level configuration regression isn't caught. Lower priority since group-missing is a softer failure than ecosystem-missing, but worth noting.
Verification suggestions
Post-merge, the maintainer should confirm:
# 1. After the next Monday cycle, at least one Dependabot PR should have fired
gh pr list --author 'app/dependabot' --state all --limit 5
# 2. If nothing fires by the *second* Monday post-merge, check the Dependabot logs
# in Settings -> Code security & analysis -> Dependabot version updates -> "Last
# checked" — server-side schema rejection won't surface elsewhere.If no PR fires by the second Monday post-merge, the config is being rejected server-side (most likely a schema issue Dependabot validated but the local YAML loader didn't), and the schema test in this PR didn't catch it — which is the gap the inline on directory / schedule.interval is about.
…ddresses thread line 99) Adds the two remaining required-field assertions (directory, schedule.interval) to test_dependabot_yml_minimum_viable_schema so the test covers all three fields Dependabot v2 requires per entry. A future edit that drops either field now fails the test rather than silently disabling the entry server-side. Also tightens the module docstring at item 2 per review feedback (line 22): replaces the confusing parenthetical self-Q&A with a direct statement.
yinsong1986
left a comment
There was a problem hiding this comment.
Summary
Moves dependabot.yml from .github/workflows/ (where Dependabot ignores it) to .github/ (where Dependabot reads it), and adds a 5-case pin test that locks the canonical placement plus the v2 schema required-field set. Verbatim rename of the config; no behaviour change other than "Dependabot now sees this file."
The diagnosis in the PR description is correct and well-cited. The fix is the smallest possible diff that closes #235. R1 strengthened the schema test from package-ecosystem-only to all three Dependabot v2 required fields (package-ecosystem, directory, schedule.interval), which is exactly the right tightening — a future edit that drops schedule: from any entry now fails locally instead of silently disabling that entry server-side.
What's good
- Pin discipline is on-point: pre-fix state has all 5 tests failing with diagnostics that name the canonical path; post-fix state has all 5 passing. Maps directly to AGENTS.md > Review Learnings (#85) > "Pin regression tests for reviewed fixes."
- Scope is tight — config rename + one new test file, no production code touched, no unrelated drive-bys.
- Error messages on the assertions are diagnostic, not just
assert False— a future contributor who hits these gets a pointer to the GitHub docs and the canonical path. - ASCII-clean (verified with
grep -nP '[^\x00-\x7F]'), per AGENTS.local.md / Review Learnings (#86).
Concerns
- R1 changelog claim doesn't fully match the head. The R1 commit message says it "tightens the module docstring at item 2... replaces the confusing parenthetical self-Q&A with a direct statement," but the rewrite left an unbalanced paren (see inline). The schema-test half of R1 landed correctly; the docstring half regressed.
- Regression scope is narrower than the PR's stated thesis. The PR argues "any path other than
.github/dependabot.ymlis silently ignored," but the negative-path test only blocks.github/workflows/dependabot.yml. Other plausible copy-paste destinations (.github/dependabot.yaml, repo-rootdependabot.yml,.github/configs/dependabot.yml) would re-create the same harm and silently pass this test. See inline. - The actual harm the PR cites is dropped
groups, not droppedecosystems. The PR description's lead bullet ispipecosystem grouping fortorch/lerobot/transformersnever fired. The pin test assertspackage-ecosystem: pipis present but does not assert theml-stack/sim-stack/dev-toolsgroups exist or contain those packages. A future edit that dropsgroups:from thepipentry silently regresses exactly the harm this PR cites. See inline. - Acceptance criteria items 3 and 4 are post-merge-only ("Active" status in repo settings + first Monday Dependabot PR fires). Worth a maintainer reminder to verify these on the next weekly cycle so #235 actually closes — pinning the file path doesn't pin GitHub's server-side parse success.
Verification suggestions
# Sanity-check that no other dependabot.* file slipped in:
find .github -iname 'dependabot*' -o -iname 'dependabot*' | head
# Run the new test locally:
hatch run pytest tests/test_dependabot_config_path.py -v
# Post-merge (maintainer): confirm Settings -> Code security & analysis ->
# Dependabot version updates is "Active" and check the Insights ->
# Dependency graph -> Dependabot tab the next Monday for the first PR cycle.The test_dependabot_config_path.py imports PyYAML which has no bundled type stubs. mypy with ignore_missing_imports=false rejects it. Adding yaml.* to the existing third-party-without-stubs override unblocks CI using the same pattern as every other untyped dep in the list.
…-depth (addresses threads line 19, 67, 116, 137) Addresses four review concerns in one commit (same file, same test suite): 1. Fix unbalanced paren in module docstring item 2 (line 19). 2. Replace single-wrong-path assert with glob-based check that verifies the canonical path is the ONLY dependabot.y*ml in the tree (line 67). 3. Add test_dependabot_pip_groups_pin_ml_stack to pin that the pip entry has groups covering torch* and lerobot* patterns (line 116). 4. Tighten entry.get() to entry["package-ecosystem"] so malformed entries surface a KeyError instead of being silently skipped (line 137). Test count: 5 -> 6 (replaced test_not_at_historical_wrong_path with stricter test_unique_in_tree + added new groups pin test).
Closes #235.
Problem
.github/workflows/dependabot.ymllives in the wrong directory. Dependabot reads only.github/dependabot.yml; anything else is silently ignored. The current file is valid YAML, parses fine, ships onmain-- but Dependabot itself never sees it.GitHub docs: the config file must live at
.github/dependabot.yml.Net effect of the misplacement (window: #92 onward)
pipecosystem grouping fortorch/lerobot/transformers/huggingface-hubnever fired. ML-stack updates surfaced only via manual sweep (fix(deps): resolve 19 dependabot security vulnerabilities #153 was the manual catch-up).github-actionsecosystem entry that was supposed to keep workflow SHA pins fresh after improve: enforce STRANDS_TRUST_REMOTE_CODE gate in policy factory #92 / ci: pin codeql-advanced.yml action SHAs and align CodeQL major (closes #217) #234 was inactive. Every action pin became manual maintenance.dev-toolsgroup (ruff/mypy/pytest*) similarly never fired.Diff shape
Verbatim
git mvof the config; content unchanged (version 2,pip+github-actionsecosystems, weekly Monday schedule, three groupedpippatterns). Plus a 6-case pin test and a 1-line mypy override.Pin test (
tests/test_dependabot_config_path.py)test_dependabot_yml_at_canonical_path.github/dependabot.ymlexists; the canonical path is a hard contract.test_dependabot_yml_unique_in_treedependabot.y*mlin the tree (glob-based); blocks any re-creation at alternative paths.test_dependabot_yml_minimum_viable_schemaversion: 2;updatesis a non-empty list; every entry declarespackage-ecosystem,directory, andschedule.interval.test_dependabot_covers_expected_ecosystems[pip]pipecosystem stays in scope (ML-stack hygiene).test_dependabot_covers_expected_ecosystems[github-actions]github-actionsecosystem stays in scope (#92 / #234 SHA-pin freshness).test_dependabot_pip_groups_pin_ml_stackgroups.ml-stackexists and itspatternsincludetorch*+lerobot*. Pins the exact harm this PR cites.Verification (pin discipline -- AGENTS.md > Review Learnings #85)
Why a separate, single-file PR
Acceptance criteria (from #235)
.github/dependabot.ymlexists with current content from.github/workflows/dependabot.yml.github/workflows/dependabot.ymlremovedSection 13 R-round changelog
(Round budget: 3/3 reached.)
1a3f702tests/test_dependabot_config_path.py(5 cases)94539dedirectory+schedule.intervalassertions) + docstring nittest_dependabot_yml_minimum_viable_schemaf90cb18yamlimport-untyped error (addyaml.*to mypy ignore overrides)12f9d4atest_dependabot_yml_unique_in_tree,test_dependabot_pip_groups_pin_ml_stack