From 7bc479921a54730be60d1bce4caa4260c1e23097 Mon Sep 17 00:00:00 2001 From: Gabriel Vinhaes Date: Fri, 13 Mar 2026 13:46:04 -0300 Subject: [PATCH 1/2] ci: add admin override for Codex review --- .github/workflows/codex-pr-review.yml | 100 ++++++++- .github/workflows/codex-review-override.yml | 212 ++++++++++++++++++++ 2 files changed, 306 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/codex-review-override.yml diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml index c4dc6c7..b31d707 100644 --- a/.github/workflows/codex-pr-review.yml +++ b/.github/workflows/codex-pr-review.yml @@ -7,6 +7,8 @@ on: - synchronize - reopened - ready_for_review + - labeled + - unlabeled concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -145,6 +147,57 @@ jobs: echo "parse_inconclusive=$parse_inconclusive" >> "$GITHUB_OUTPUT" echo "parse_failed=$parse_failed" >> "$GITHUB_OUTPUT" + - name: Resolve admin override state + id: override + if: ${{ always() }} + uses: actions/github-script@v7 + env: + OVERRIDE_LABEL: codex-override-approved + PULL_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + with: + script: | + const marker = ""; + const labelName = process.env.OVERRIDE_LABEL; + const headSha = process.env.PULL_HEAD_SHA || ""; + const labels = context.payload.pull_request?.labels || []; + const labelPresent = labels.some((label) => label.name === labelName); + + const { owner, repo } = context.repo; + const issue_number = context.issue.number; + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }); + + const audit = comments + .filter((comment) => comment.user?.type === "Bot" && comment.body?.includes(marker)) + .sort( + (a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(), + )[0]; + + const body = audit?.body || ""; + const statusMatch = body.match(/^Status:\s*([^\n\r]+)/m); + const approvedByMatch = body.match(/^Approved by:\s*@([^\s]+)/m); + const approvedShaMatch = body.match(/^Head SHA:\s*`?([0-9a-f]{7,40})`?/m); + + const recordedStatus = (statusMatch?.[1] || "").trim().toLowerCase(); + const approvedBy = approvedByMatch?.[1] || ""; + const approvedSha = approvedShaMatch?.[1] || ""; + const active = labelPresent && recordedStatus === "active" && approvedSha === headSha; + const stale = + labelPresent && + recordedStatus === "active" && + approvedSha !== "" && + approvedSha !== headSha; + + core.setOutput("label_present", labelPresent ? "1" : "0"); + core.setOutput("active", active ? "1" : "0"); + core.setOutput("stale", stale ? "1" : "0"); + core.setOutput("approved_by", approvedBy); + core.setOutput("approved_sha", approvedSha); + - name: Upload Codex review artifact if: ${{ always() }} uses: actions/upload-artifact@v4 @@ -167,6 +220,10 @@ jobs: P3_COUNT: ${{ steps.parse.outputs.p3_count }} PARSE_INCONCLUSIVE: ${{ steps.parse.outputs.parse_inconclusive }} PARSE_FAILED: ${{ steps.parse.outputs.parse_failed }} + OVERRIDE_ACTIVE: ${{ steps.override.outputs.active }} + OVERRIDE_STALE: ${{ steps.override.outputs.stale }} + OVERRIDE_APPROVED_BY: ${{ steps.override.outputs.approved_by }} + OVERRIDE_APPROVED_SHA: ${{ steps.override.outputs.approved_sha }} with: script: | const fs = require("fs"); @@ -186,11 +243,33 @@ jobs: const p3 = Number(process.env.P3_COUNT || "0"); const parseInconclusive = process.env.PARSE_INCONCLUSIVE === "1"; const parseFailed = process.env.PARSE_FAILED === "1"; + const overrideActive = process.env.OVERRIDE_ACTIVE === "1"; + const overrideStale = process.env.OVERRIDE_STALE === "1"; + const overrideApprovedBy = process.env.OVERRIDE_APPROVED_BY || ""; + const overrideApprovedSha = process.env.OVERRIDE_APPROVED_SHA || ""; const timedOut = exitCode === "124" || exitCode === "137"; const totalFindings = p0 + p1 + p2 + p3; - const isBlocking = exitCode !== "0" || p0 > 0 || p1 > 0 || parseInconclusive || parseFailed; - const status = isBlocking ? "❌ blocking" : "✅ non-blocking"; - const shouldComment = exitCode !== "0" || totalFindings > 0 || parseInconclusive || parseFailed; + const isBlocking = + exitCode !== "0" || + p0 > 0 || + parseInconclusive || + parseFailed || + (p1 > 0 && !overrideActive); + const status = isBlocking + ? "❌ blocking" + : overrideActive && p1 > 0 + ? "⚠️ admin override applied" + : "✅ non-blocking"; + const overrideStatus = overrideActive ? "active" : overrideStale ? "stale" : "none"; + const overrideSummary = overrideApprovedBy + ? `\`${overrideStatus}\` by @${overrideApprovedBy}` + : `\`${overrideStatus}\``; + const shouldComment = + exitCode !== "0" || + totalFindings > 0 || + parseInconclusive || + parseFailed || + overrideStatus !== "none"; const findings = output .split(/\r?\n/) @@ -214,6 +293,8 @@ jobs: `Other findings: P2 \`${p2}\` | P3 \`${p3}\``, `Parser status: \`${parseFailed ? "failed" : "ok"}\``, `Parser fallback used: \`${parseInconclusive ? "yes" : "no"}\``, + `Admin override: ${overrideSummary}`, + `Override SHA: \`${overrideApprovedSha || "n/a"}\``, "", "**Top findings**", findingsSection, @@ -276,9 +357,16 @@ jobs: echo "::error::Codex review output parsing failed." exit 1 - - name: Fail on P0 or P1 findings - if: ${{ steps.parse.outputs.p0_count != '0' || steps.parse.outputs.p1_count != '0' || steps.parse.outputs.parse_inconclusive == '1' }} + - name: Fail on P0 findings or inconclusive parse + if: ${{ steps.parse.outputs.p0_count != '0' || steps.parse.outputs.parse_inconclusive == '1' }} + shell: bash + run: | + echo "::error::Codex review reported blocking P0 findings or an inconclusive parse." + exit 1 + + - name: Fail on P1 findings without admin override + if: ${{ steps.parse.outputs.p1_count != '0' && steps.override.outputs.active != '1' }} shell: bash run: | - echo "::error::Codex review reported blocking findings." + echo "::error::Blocking Codex P1 findings detected without an active admin override." exit 1 diff --git a/.github/workflows/codex-review-override.yml b/.github/workflows/codex-review-override.yml new file mode 100644 index 0000000..b7069e8 --- /dev/null +++ b/.github/workflows/codex-review-override.yml @@ -0,0 +1,212 @@ +name: codex-review-override + +on: + issue_comment: + types: + - created + - edited + +permissions: + actions: write + contents: read + issues: write + pull-requests: write + +jobs: + override: + if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/codex-override') }} + runs-on: ubuntu-latest + steps: + - name: Apply or clear Codex review override + uses: actions/github-script@v7 + env: + COMMAND_BODY: ${{ github.event.comment.body }} + OVERRIDE_LABEL: codex-override-approved + with: + script: | + const marker = ""; + const commandBody = (process.env.COMMAND_BODY || "").trim(); + const labelName = process.env.OVERRIDE_LABEL || "codex-override-approved"; + const match = commandBody.match(/^\/codex-override(?:\s+([\s\S]+))?$/); + + if (!match) { + core.setFailed("Unsupported codex override command."); + return; + } + + const argument = (match[1] || "").trim(); + const clearRequested = /^clear$/i.test(argument); + + if (!clearRequested && argument.length === 0) { + core.setFailed("Usage: /codex-override or /codex-override clear"); + return; + } + + const actor = context.actor; + const { owner, repo } = context.repo; + const issue_number = context.issue.number; + + const permissionResponse = await github.rest.repos.getCollaboratorPermissionLevel({ + owner, + repo, + username: actor, + }); + const permission = permissionResponse.data.permission || "none"; + + if (permission !== "admin") { + core.setFailed(`Only admins can manage Codex overrides. Current permission: ${permission}.`); + return; + } + + const pull = await github.rest.pulls.get({ + owner, + repo, + pull_number: issue_number, + }); + const headSha = pull.data.head.sha; + const headRef = pull.data.head.ref; + + try { + await github.rest.issues.getLabel({ + owner, + repo, + name: labelName, + }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + await github.rest.issues.createLabel({ + owner, + repo, + name: labelName, + color: "B60205", + description: "Admin-approved override for Codex P1 findings on the current PR head", + }); + } + + if (clearRequested) { + try { + await github.rest.issues.removeLabel({ + owner, + repo, + issue_number, + name: labelName, + }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + } + } else { + await github.rest.issues.addLabels({ + owner, + repo, + issue_number, + labels: [labelName], + }); + } + + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }); + const existing = comments.find( + (comment) => comment.user?.type === "Bot" && comment.body?.includes(marker), + ); + + const timestamp = new Date().toISOString(); + const quotedReason = + argument.length > 0 + ? argument.split(/\r?\n/).map((line) => `> ${line}`).join("\n") + : "> clear"; + + const body = clearRequested + ? [ + marker, + "### Codex review override", + "", + "Status: cleared", + `Cleared by: @${actor}`, + `Cleared at: ${timestamp}`, + `Head SHA: \`${headSha}\``, + `Head ref: \`${headRef}\``, + "", + "Reason:", + quotedReason, + ].join("\n") + : [ + marker, + "### Codex review override", + "", + "Status: active", + `Approved by: @${actor}`, + `Approved at: ${timestamp}`, + `Head SHA: \`${headSha}\``, + `Head ref: \`${headRef}\``, + "Scope: P1 findings only", + "", + "Reason:", + quotedReason, + ].join("\n"); + + if (existing) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body, + }); + } + + const runsResponse = await github.request( + "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", + { + owner, + repo, + workflow_id: "codex-pr-review.yml", + event: "pull_request", + per_page: 50, + }, + ); + const runs = runsResponse.data.workflow_runs || []; + const targetRun = runs + .filter( + (run) => + run.head_sha === headSha && + (run.pull_requests || []).some((pullRequest) => pullRequest.number === issue_number), + ) + .sort( + (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(), + )[0]; + + if (!targetRun) { + core.warning(`No codex-pr-review run found for PR #${issue_number} at ${headSha}.`); + return; + } + + if (targetRun.status !== "completed") { + core.notice( + `codex-pr-review run ${targetRun.id} is currently ${targetRun.status}; no rerun needed.`, + ); + return; + } + + await github.request("POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun", { + owner, + repo, + run_id: targetRun.id, + }); + + core.notice( + `${clearRequested ? "Cleared" : "Applied"} Codex override and re-ran workflow run ${targetRun.id}.`, + ); From 59ad980a8481815cc1fcc08a6de0a3c6fa1f6397 Mon Sep 17 00:00:00 2001 From: Gabriel Vinhaes Date: Fri, 13 Mar 2026 13:52:25 -0300 Subject: [PATCH 2/2] ci: support manual admin override bootstrap --- .github/workflows/codex-pr-review.yml | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml index b31d707..87e5ab3 100644 --- a/.github/workflows/codex-pr-review.yml +++ b/.github/workflows/codex-pr-review.yml @@ -161,6 +161,8 @@ jobs: const headSha = process.env.PULL_HEAD_SHA || ""; const labels = context.payload.pull_request?.labels || []; const labelPresent = labels.some((label) => label.name === labelName); + const eventAction = context.payload.action || ""; + const eventLabelName = context.payload.label?.name || ""; const { owner, repo } = context.repo; const issue_number = context.issue.number; @@ -185,18 +187,44 @@ jobs: const recordedStatus = (statusMatch?.[1] || "").trim().toLowerCase(); const approvedBy = approvedByMatch?.[1] || ""; const approvedSha = approvedShaMatch?.[1] || ""; - const active = labelPresent && recordedStatus === "active" && approvedSha === headSha; + const auditActive = + labelPresent && recordedStatus === "active" && approvedSha === headSha; const stale = labelPresent && recordedStatus === "active" && approvedSha !== "" && approvedSha !== headSha; + let manualEventActive = false; + let manualEventApprovedBy = ""; + + if (!auditActive && eventAction === "labeled" && eventLabelName === labelName) { + const sender = context.payload.sender?.login || ""; + if (sender) { + const permissionResponse = await github.rest.repos.getCollaboratorPermissionLevel({ + owner, + repo, + username: sender, + }); + if (permissionResponse.data.permission === "admin") { + manualEventActive = true; + manualEventApprovedBy = sender; + } + } + } + + const active = auditActive || manualEventActive; + const overrideSource = auditActive + ? "audit-comment" + : manualEventActive + ? "manual-label-event" + : "none"; core.setOutput("label_present", labelPresent ? "1" : "0"); core.setOutput("active", active ? "1" : "0"); core.setOutput("stale", stale ? "1" : "0"); - core.setOutput("approved_by", approvedBy); - core.setOutput("approved_sha", approvedSha); + core.setOutput("approved_by", approvedBy || manualEventApprovedBy); + core.setOutput("approved_sha", approvedSha || (manualEventActive ? headSha : "")); + core.setOutput("source", overrideSource); - name: Upload Codex review artifact if: ${{ always() }} @@ -224,6 +252,7 @@ jobs: OVERRIDE_STALE: ${{ steps.override.outputs.stale }} OVERRIDE_APPROVED_BY: ${{ steps.override.outputs.approved_by }} OVERRIDE_APPROVED_SHA: ${{ steps.override.outputs.approved_sha }} + OVERRIDE_SOURCE: ${{ steps.override.outputs.source }} with: script: | const fs = require("fs"); @@ -247,6 +276,7 @@ jobs: const overrideStale = process.env.OVERRIDE_STALE === "1"; const overrideApprovedBy = process.env.OVERRIDE_APPROVED_BY || ""; const overrideApprovedSha = process.env.OVERRIDE_APPROVED_SHA || ""; + const overrideSource = process.env.OVERRIDE_SOURCE || "none"; const timedOut = exitCode === "124" || exitCode === "137"; const totalFindings = p0 + p1 + p2 + p3; const isBlocking = @@ -294,6 +324,7 @@ jobs: `Parser status: \`${parseFailed ? "failed" : "ok"}\``, `Parser fallback used: \`${parseInconclusive ? "yes" : "no"}\``, `Admin override: ${overrideSummary}`, + `Override source: \`${overrideSource}\``, `Override SHA: \`${overrideApprovedSha || "n/a"}\``, "", "**Top findings**",