diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cfff0003a9b..cfdbf26958d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,10 +11,10 @@ /.github/workflows/codeql.yml @openclaw/openclaw-secops /.github/workflows/codeql-android-critical-security.yml @openclaw/openclaw-secops /.github/workflows/codeql-critical-quality.yml @openclaw/openclaw-secops -/.github/workflows/dependency-change-awareness.yml @openclaw/openclaw-secops -/test/scripts/dependency-change-awareness-workflow.test.ts @openclaw/openclaw-secops -/test/scripts/dependency-change-awareness-script.test.ts @openclaw/openclaw-secops -/scripts/github/dependency-change-awareness.mjs @openclaw/openclaw-secops +/.github/workflows/dependency-guard.yml @openclaw/openclaw-secops +/test/scripts/dependency-guard-workflow.test.ts @openclaw/openclaw-secops +/test/scripts/dependency-guard-script.test.ts @openclaw/openclaw-secops +/scripts/github/dependency-guard.mjs @openclaw/openclaw-secops /package-lock.json @openclaw/openclaw-secops /npm-shrinkwrap.json @openclaw/openclaw-secops /extensions/*/package-lock.json @openclaw/openclaw-secops diff --git a/.github/workflows/dependency-change-awareness.yml b/.github/workflows/dependency-guard.yml similarity index 81% rename from .github/workflows/dependency-change-awareness.yml rename to .github/workflows/dependency-guard.yml index 9c75a5b56c9..289ee1c1fa0 100644 --- a/.github/workflows/dependency-change-awareness.yml +++ b/.github/workflows/dependency-guard.yml @@ -1,4 +1,4 @@ -name: Dependency Change Awareness +name: Dependency Guard on: pull_request_target: # zizmor: ignore[dangerous-triggers] checks trusted base script only; never checks out PR head @@ -10,11 +10,11 @@ permissions: issues: write concurrency: - group: dependency-change-awareness-${{ github.event.pull_request.number }} + group: dependency-guard-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: - dependency-change-awareness: + dependency-guard: if: ${{ !github.event.pull_request.draft }} runs-on: ubuntu-24.04 timeout-minutes: 5 @@ -30,4 +30,4 @@ jobs: GITHUB_TOKEN: ${{ github.token }} OPENCLAW_SECURITY_APPROVERS: vincentkoc,steipete,joshavant OPENCLAW_SECURITY_TEAM_SLUG: openclaw-secops - run: node scripts/github/dependency-change-awareness.mjs + run: node scripts/github/dependency-guard.mjs diff --git a/scripts/github/dependency-change-awareness.mjs b/scripts/github/dependency-guard.mjs similarity index 98% rename from scripts/github/dependency-change-awareness.mjs rename to scripts/github/dependency-guard.mjs index ae7dab19af2..a8e5fcb4d28 100644 --- a/scripts/github/dependency-change-awareness.mjs +++ b/scripts/github/dependency-guard.mjs @@ -2,7 +2,7 @@ import { appendFile, readFile } from "node:fs/promises"; -export const dependencyChangeMarker = ""; +export const dependencyChangeMarker = ""; export const dependencyGraphGuardMarker = ""; export const dependencyChangedLabel = "dependencies-changed"; export const allowDependenciesCommand = "/allow-dependencies-change"; @@ -316,7 +316,7 @@ function githubApi(token) { const baseHeaders = { accept: "application/vnd.github+json", authorization: `Bearer ${token}`, - "user-agent": "openclaw-dependency-change-awareness", + "user-agent": "openclaw-dependency-guard", "x-github-api-version": "2022-11-28", }; const request = async (path, options = {}) => { @@ -521,7 +521,7 @@ async function main() { renderClearedDependencyGuardComment({ headSha: pullRequest.head?.sha }), ); } - await writeSummary("## Dependency Change Awareness\n\nNo dependency-related file changes detected."); + await writeSummary("## Dependency Guard\n\nNo dependency-related file changes detected."); console.log("No dependency-related file changes detected."); return; } @@ -533,7 +533,7 @@ async function main() { ); await writeSummary( [ - "## Dependency Change Awareness", + "## Dependency Guard", "", `Detected ${dependencyGraphFiles.length} dependency-related file change(s).`, "", diff --git a/test/scripts/dependency-change-awareness-script.test.ts b/test/scripts/dependency-guard-script.test.ts similarity index 98% rename from test/scripts/dependency-change-awareness-script.test.ts rename to test/scripts/dependency-guard-script.test.ts index bdd3899d0b2..4ab9cfd8fa3 100644 --- a/test/scripts/dependency-change-awareness-script.test.ts +++ b/test/scripts/dependency-guard-script.test.ts @@ -15,12 +15,12 @@ import { renderClearedDependencyGuardComment, sanitizeDisplayValue, securityApproverSet, -} from "../../scripts/github/dependency-change-awareness.mjs"; +} from "../../scripts/github/dependency-guard.mjs"; const headSha = "a".repeat(40); const staleSha = "b".repeat(40); -describe("dependency change awareness script", () => { +describe("dependency guard script", () => { it("detects dependency awareness file surfaces", () => { expect(isDependencyFile("pnpm-lock.yaml")).toBe(true); expect(isDependencyFile("package.json")).toBe(false); diff --git a/test/scripts/dependency-change-awareness-workflow.test.ts b/test/scripts/dependency-guard-workflow.test.ts similarity index 79% rename from test/scripts/dependency-change-awareness-workflow.test.ts rename to test/scripts/dependency-guard-workflow.test.ts index 9672df182ca..3873614589a 100644 --- a/test/scripts/dependency-change-awareness-workflow.test.ts +++ b/test/scripts/dependency-guard-workflow.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; import { parse } from "yaml"; -const WORKFLOW = ".github/workflows/dependency-change-awareness.yml"; +const WORKFLOW = ".github/workflows/dependency-guard.yml"; const CODEOWNERS = ".github/CODEOWNERS"; type WorkflowStep = { @@ -13,11 +13,13 @@ type WorkflowStep = { }; type WorkflowJob = { + name?: string; steps?: WorkflowStep[]; }; type Workflow = { jobs?: Record; + name?: string; permissions?: Record; }; @@ -25,7 +27,15 @@ function readWorkflow(): Workflow { return parse(readFileSync(WORKFLOW, "utf8")) as Workflow; } -describe("dependency change awareness workflow", () => { +describe("dependency guard workflow", () => { + it("uses the dependency guard check name", () => { + const parsed = readWorkflow(); + + expect(parsed.name).toBe("Dependency Guard"); + expect(parsed.jobs).toHaveProperty("dependency-guard"); + expect(parsed.jobs?.["dependency-guard"]?.name).toBeUndefined(); + }); + it("uses a metadata-only pull_request_target workflow with minimal write permissions", () => { const workflow = readFileSync(WORKFLOW, "utf8"); const parsed = readWorkflow(); @@ -57,29 +67,29 @@ describe("dependency change awareness workflow", () => { expect(workflow).not.toContain(snippet); } - const steps = readWorkflow().jobs?.["dependency-change-awareness"]?.steps ?? []; + const steps = readWorkflow().jobs?.["dependency-guard"]?.steps ?? []; expect(steps).toHaveLength(2); expect(steps[0].uses).toBe("actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd"); expect(steps[0].with?.ref).toBe("${{ github.event.pull_request.base.sha }}"); expect(steps[0].with?.["persist-credentials"]).toBe(false); - expect(steps[1].run).toBe("node scripts/github/dependency-change-awareness.mjs"); + expect(steps[1].run).toBe("node scripts/github/dependency-guard.mjs"); }); it("uses a dedicated checked-in script and bounded sticky comments", () => { const workflow = readFileSync(WORKFLOW, "utf8"); - const steps = readWorkflow().jobs?.["dependency-change-awareness"]?.steps ?? []; + const steps = readWorkflow().jobs?.["dependency-guard"]?.steps ?? []; const runStep = steps[1]; - const script = readFileSync("scripts/github/dependency-change-awareness.mjs", "utf8"); + const script = readFileSync("scripts/github/dependency-guard.mjs", "utf8"); expect(runStep.env?.OPENCLAW_SECURITY_TEAM_SLUG).toBe("openclaw-secops"); expect(runStep.env?.OPENCLAW_SECURITY_APPROVERS).toBe("vincentkoc,steipete,joshavant"); - expect(workflow).toContain("scripts/github/dependency-change-awareness.mjs"); + expect(workflow).toContain("scripts/github/dependency-guard.mjs"); expect(script).toContain('"dependencies-changed"'); expect(script).not.toContain('"blocked: dependencies"'); }); it("detects the intended dependency-related file surfaces", () => { - const script = readFileSync("scripts/github/dependency-change-awareness.mjs", "utf8"); + const script = readFileSync("scripts/github/dependency-guard.mjs", "utf8"); expect(script).toContain('filename.endsWith("package.json")'); expect(script).toContain('filename.endsWith("package-lock.json")'); expect(script).toContain('filename.endsWith("npm-shrinkwrap.json")'); @@ -90,7 +100,7 @@ describe("dependency change awareness workflow", () => { }); it("blocks package lockfile and manifest graph changes unless secops approves the current head sha", () => { - const script = readFileSync("scripts/github/dependency-change-awareness.mjs", "utf8"); + const script = readFileSync("scripts/github/dependency-guard.mjs", "utf8"); expect(script).toContain('filename.endsWith("pnpm-lock.yaml")'); expect(script).toContain('filename.endsWith("package-lock.json")'); expect(script).toContain('filename.endsWith("npm-shrinkwrap.json")'); @@ -110,13 +120,13 @@ describe("dependency change awareness workflow", () => { it("requires secops review for future workflow or guard changes", () => { const codeowners = readFileSync(CODEOWNERS, "utf8"); expect(codeowners).toContain( - "/.github/workflows/dependency-change-awareness.yml @openclaw/openclaw-secops", + "/.github/workflows/dependency-guard.yml @openclaw/openclaw-secops", ); expect(codeowners).toContain( - "/test/scripts/dependency-change-awareness-workflow.test.ts @openclaw/openclaw-secops", + "/test/scripts/dependency-guard-workflow.test.ts @openclaw/openclaw-secops", ); expect(codeowners).toContain( - "/scripts/github/dependency-change-awareness.mjs @openclaw/openclaw-secops", + "/scripts/github/dependency-guard.mjs @openclaw/openclaw-secops", ); expect(codeowners).toContain("/package-lock.json @openclaw/openclaw-secops"); expect(codeowners).toContain("/npm-shrinkwrap.json @openclaw/openclaw-secops");