From 1851eb28abacbcd979ce77031c1081963c32de88 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 17 Jul 2026 06:26:00 +0900 Subject: [PATCH 1/2] fix invalid root npm Dependabot job --- .github/dependabot.yml | 5 ----- backend/tests/test_release_governance.py | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 237e6bf29..e9e7df328 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -63,8 +63,3 @@ updates: directory: /connector schedule: interval: daily - - - package-ecosystem: npm - directory: / - schedule: - interval: daily diff --git a/backend/tests/test_release_governance.py b/backend/tests/test_release_governance.py index fffbde5d5..54c5c8c5d 100644 --- a/backend/tests/test_release_governance.py +++ b/backend/tests/test_release_governance.py @@ -301,6 +301,30 @@ def construct_mapping( assert duplicates == [], "\n".join(duplicates) +def test_dependabot_npm_directories_contain_package_manifests() -> None: + """Keep npm update jobs bound to directories that Dependabot can inspect.""" + dependabot_config = yaml.safe_load(read_repo_text(".github/dependabot.yml")) + + npm_directories = [ + update["directory"] + for update in dependabot_config["updates"] + if update["package-ecosystem"] == "npm" + ] + + assert npm_directories, "Dependabot must track at least one npm workspace" + missing_manifests = [ + directory + for directory in npm_directories + if not ( + REPO_ROOT / directory.removeprefix("/") / "package.json" + ).is_file() + ] + assert missing_manifests == [], ( + "Dependabot npm directories must contain package.json: " + + ", ".join(missing_manifests) + ) + + def test_stepsecurity_remediation_adds_pinned_audit_hardening() -> None: harden_runner_ref = ( "step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0" From ddf94fba9cd22d1d3d70d004f64718884abc9cf1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 17 Jul 2026 09:28:26 +0900 Subject: [PATCH 2/2] fix(deps): enforce Dependabot cooldown --- .github/dependabot.yml | 16 ++++++++++++++++ backend/tests/test_release_governance.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e9e7df328..8bd3e97b9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,8 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: github-actions: patterns: @@ -13,6 +15,8 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: docker-base-images: patterns: @@ -22,6 +26,8 @@ updates: directory: "/frontend" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: frontend-docker-base-images: patterns: @@ -31,6 +37,8 @@ updates: directory: "/backend" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: backend-python: patterns: @@ -40,6 +48,8 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: ci-python: patterns: @@ -49,6 +59,8 @@ updates: directory: "/frontend" schedule: interval: "weekly" + cooldown: + default-days: 7 groups: frontend-npm: patterns: @@ -58,8 +70,12 @@ updates: directory: /connector schedule: interval: daily + cooldown: + default-days: 7 - package-ecosystem: pip directory: /connector schedule: interval: daily + cooldown: + default-days: 7 diff --git a/backend/tests/test_release_governance.py b/backend/tests/test_release_governance.py index 54c5c8c5d..b6ba448c4 100644 --- a/backend/tests/test_release_governance.py +++ b/backend/tests/test_release_governance.py @@ -325,6 +325,22 @@ def test_dependabot_npm_directories_contain_package_manifests() -> None: ) +def test_dependabot_updates_enforce_supply_chain_cooldown() -> None: + """Hold newly published dependency versions for a review observation window.""" + updates = yaml.safe_load(read_repo_text(".github/dependabot.yml"))["updates"] + + assert len(updates) == 8 + missing_or_short = [ + f"{update['package-ecosystem']}:{update['directory']}" + for update in updates + if (update.get("cooldown") or {}).get("default-days", 0) < 7 + ] + assert missing_or_short == [], ( + "Dependabot updates require at least a seven-day cooldown: " + + ", ".join(missing_or_short) + ) + + def test_stepsecurity_remediation_adds_pinned_audit_hardening() -> None: harden_runner_ref = ( "step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0"