diff --git a/scripts/check-codex-autofix-workflow.mjs b/scripts/check-codex-autofix-workflow.mjs index dd881041b..498b62c48 100644 --- a/scripts/check-codex-autofix-workflow.mjs +++ b/scripts/check-codex-autofix-workflow.mjs @@ -136,6 +136,22 @@ for (const requiredCheck of requiredTokenChecks) { } } +// When CODEX_TRIGGER_TOKEN is unset the request job must skip gracefully with a +// warning rather than hard-fail the check, so a merged-but-unconfigured workflow +// never blocks unrelated PRs. +const requiredMissingTokenHandlingChecks = [ + "CODEX_TRIGGER_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN }}", + "if: ${{ env.CODEX_TRIGGER_TOKEN == '' }}", + "if: ${{ env.CODEX_TRIGGER_TOKEN != '' }}", + "CODEX_TRIGGER_TOKEN secret is not configured", +]; + +for (const requiredCheck of requiredMissingTokenHandlingChecks) { + if (!workflow.includes(requiredCheck)) { + failures.push(`Codex auto-resolve workflow is missing graceful missing-token handling: ${requiredCheck}`); + } +} + const requiredConcurrencyChecks = [ " concurrency:", " group: codex-autoresolve-${{ github.event.pull_request.number }}", diff --git a/tests/codex-autofix-workflow.test.ts b/tests/codex-autofix-workflow.test.ts index 9a782804d..07f058103 100644 --- a/tests/codex-autofix-workflow.test.ts +++ b/tests/codex-autofix-workflow.test.ts @@ -337,6 +337,32 @@ describe("Codex auto-resolve workflow guard", () => { expect(result.output).toContain("missing trusted duplicate-marker check"); }); + it("rejects removing the missing-token warning branch", () => { + const workflow = originalWorkflow.replace( + ` - name: Warn when the trigger token is not configured + if: \${{ env.CODEX_TRIGGER_TOKEN == '' }} + run: echo "::warning title=Codex auto-resolve::CODEX_TRIGGER_TOKEN secret is not configured; skipping the Codex auto-resolve request. Codex will not be asked to resolve findings until this fine-grained PAT secret is set." +`, + "", + ); + expect(workflow).not.toBe(originalWorkflow); + + const result = runGuard(workflow); + + expect(result.status).toBe(1); + expect(result.output).toContain("graceful missing-token handling"); + }); + + it("rejects removing the graceful-skip guard on the request step", () => { + const workflow = originalWorkflow.replace(" if: ${{ env.CODEX_TRIGGER_TOKEN != '' }}\n", ""); + expect(workflow).not.toBe(originalWorkflow); + + const result = runGuard(workflow); + + expect(result.status).toBe(1); + expect(result.output).toContain("graceful missing-token handling"); + }); + it("rejects workflow-level concurrency that includes unrelated events", () => { const workflow = originalWorkflow.replace( ` concurrency: