From d655b902e9b7ce033509a99a3b6c375dc7f27a0f Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:07:48 -0700 Subject: [PATCH 1/6] test change --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5abb6ec..951a55c 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# ruleset-test \ No newline at end of file +# ruleset-test +edit for test From dbad84e9d42ba24dbb44376473b8b7e8332c3e5c Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:09:55 -0700 Subject: [PATCH 2/6] defensive rewrite --- .github/workflows/review-score.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/review-score.yml b/.github/workflows/review-score.yml index 262a951..f993a03 100644 --- a/.github/workflows/review-score.yml +++ b/.github/workflows/review-score.yml @@ -1,5 +1,5 @@ name: Review Score Gate -on: +"on": pull_request: types: [opened, reopened, synchronize] pull_request_review: From 8324c74442f98a44b0ac4c77ae323c8df3751f5f Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:12:32 -0700 Subject: [PATCH 3/6] retrigger From 85b547a50830c00e5dffc1846f905d8c4604dc3f Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:15:20 -0700 Subject: [PATCH 4/6] instrumented probe --- .github/workflows/review-score.yml | 43 +++++++++++++----------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/.github/workflows/review-score.yml b/.github/workflows/review-score.yml index f993a03..1602d46 100644 --- a/.github/workflows/review-score.yml +++ b/.github/workflows/review-score.yml @@ -12,32 +12,25 @@ jobs: score: runs-on: ubuntu-latest steps: - - name: Compute review score - uses: actions/github-script@v7 + - uses: actions/github-script@v7 with: script: | - const REQUIRED_SCORE = 1; - const TIE_GOES_TO_APPROVE = true; const pr = context.payload.pull_request; - if (!pr) { core.info('no pr'); return; } - const author = pr.user.login; - const reviews = await github.paginate(github.rest.pulls.listReviews, - { owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, per_page: 100 }); - const latest = new Map(); - for (const r of reviews) { - const l = r.user && r.user.login; - if (!l || l === author) continue; - if (r.state !== 'APPROVED' && r.state !== 'CHANGES_REQUESTED') continue; - latest.set(l, r.state); + const post = (state, description) => github.rest.repos.createCommitStatus( + { owner: context.repo.owner, repo: context.repo.repo, sha: pr.head.sha, state, context: 'review-score', description }); + try { + const reviews = await github.paginate(github.rest.pulls.listReviews, + { owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, per_page: 100 }); + const latest = new Map(); + for (const r of reviews) { const l = r.user && r.user.login; + if (!l || l === pr.user.login) continue; + if (r.state !== 'APPROVED' && r.state !== 'CHANGES_REQUESTED') continue; latest.set(l, r.state); } + let a=0,b=0; for (const s of latest.values()){ if(s==='APPROVED')a++; else b++; } + const score=a-b; let pass = score>=1 || (a>=1 && score===0); + await post(pass?'success':'failure', `score ${score} (${a} approve, ${b} block)`); + if(!pass) core.setFailed('below threshold'); + } catch (e) { + const msg = String(e && e.message || e).slice(0,120); + try { await post('error', 'ERR: '+msg); } catch(_) { core.setFailed('POST-DENIED: '+msg); } + core.setFailed(msg); } - let a = 0, b = 0; - for (const s of latest.values()) { if (s === 'APPROVED') a++; else b++; } - const score = a - b; - let pass = score >= REQUIRED_SCORE; - if (!pass && TIE_GOES_TO_APPROVE && a >= 1 && score === 0) pass = true; - const desc = `score ${score} (${a} approve, ${b} block), need >= ${REQUIRED_SCORE}`; - core.info(desc); - await github.rest.repos.createCommitStatus({ - owner: context.repo.owner, repo: context.repo.repo, sha: pr.head.sha, - state: pass ? 'success' : 'failure', context: 'review-score', description: desc }); - if (!pass) core.setFailed(desc); From 8e7d42df8fe7f1fe3e046f0a004f7d2f33dadc80 Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:17:47 -0700 Subject: [PATCH 5/6] job-as-check design --- .github/workflows/review-score.yml | 39 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/.github/workflows/review-score.yml b/.github/workflows/review-score.yml index 1602d46..4edace7 100644 --- a/.github/workflows/review-score.yml +++ b/.github/workflows/review-score.yml @@ -6,31 +6,30 @@ name: Review Score Gate types: [submitted, edited, dismissed] permissions: pull-requests: read - statuses: write - contents: read jobs: - score: + review-score-gate: runs-on: ubuntu-latest steps: - uses: actions/github-script@v7 with: script: | + const REQUIRED_SCORE = 1; + const TIE_GOES_TO_APPROVE = true; const pr = context.payload.pull_request; - const post = (state, description) => github.rest.repos.createCommitStatus( - { owner: context.repo.owner, repo: context.repo.repo, sha: pr.head.sha, state, context: 'review-score', description }); - try { - const reviews = await github.paginate(github.rest.pulls.listReviews, - { owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, per_page: 100 }); - const latest = new Map(); - for (const r of reviews) { const l = r.user && r.user.login; - if (!l || l === pr.user.login) continue; - if (r.state !== 'APPROVED' && r.state !== 'CHANGES_REQUESTED') continue; latest.set(l, r.state); } - let a=0,b=0; for (const s of latest.values()){ if(s==='APPROVED')a++; else b++; } - const score=a-b; let pass = score>=1 || (a>=1 && score===0); - await post(pass?'success':'failure', `score ${score} (${a} approve, ${b} block)`); - if(!pass) core.setFailed('below threshold'); - } catch (e) { - const msg = String(e && e.message || e).slice(0,120); - try { await post('error', 'ERR: '+msg); } catch(_) { core.setFailed('POST-DENIED: '+msg); } - core.setFailed(msg); + if (!pr) { core.info('no pr context'); return; } + const reviews = await github.paginate(github.rest.pulls.listReviews, + { owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number, per_page: 100 }); + const latest = new Map(); + for (const r of reviews) { + const l = r.user && r.user.login; + if (!l || l === pr.user.login) continue; + if (r.state !== 'APPROVED' && r.state !== 'CHANGES_REQUESTED') continue; + latest.set(l, r.state); } + let a = 0, b = 0; + for (const s of latest.values()) { if (s === 'APPROVED') a++; else b++; } + const score = a - b; + let pass = score >= REQUIRED_SCORE || (TIE_GOES_TO_APPROVE && a >= 1 && score === 0); + const msg = `score ${score} (${a} approve, ${b} block), need >= ${REQUIRED_SCORE}`; + core.info(msg); + if (!pass) core.setFailed(msg); From ae745f9c4eaa0a29f12e7000f4a192bc26a4b56a Mon Sep 17 00:00:00 2001 From: Sanjay Rai Date: Mon, 20 Jul 2026 16:20:22 -0700 Subject: [PATCH 6/6] trigger re-eval with approval present