Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions .github/workflows/pr-risk-scan-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: PR Risk Scan — Comment

on:
workflow_run:
workflows: ["PR Risk Scan — Gate"]
types: [completed]

permissions:
issues: write
pull-requests: write
actions: read

jobs:
comment:
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request'
steps:
- name: Download scan artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: pr-risk-scan-results
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}

- name: Upsert PR comment
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const fs = require('fs');
const marker = '<!-- pr-risk-scan-results -->';
const reportPath = 'report.md';
const prNumberPath = 'pr-number.txt';
if (!fs.existsSync(reportPath)) {
core.setFailed('Risk scan report.md artifact was not found.');
return;
}
Comment thread
aaronpowell marked this conversation as resolved.
let body = fs.readFileSync(reportPath, 'utf8');
// Treat artifact content as untrusted (the gate workflow runs on PR code).
// Prevent spam/notification abuse and avoid API failures on oversized bodies.
body = body.replace(/@/g, '@\u200b');
const maxLength = 65000;
if (body.length > maxLength) {
body = `${body.slice(0, maxLength)}\n\n_...(truncated)..._`;
}
if (!body.includes(marker)) {
body = `${marker}\n${body}`;
}
let prNumber = null;
if (fs.existsSync(prNumberPath)) {
const parsed = parseInt(fs.readFileSync(prNumberPath, 'utf8').trim(), 10);
if (!Number.isNaN(parsed)) {
prNumber = parsed;
}
}
if (!prNumber) {
const fallback = context.payload.workflow_run.pull_requests?.[0]?.number;
if (fallback) {
prNumber = fallback;
}
}
if (!prNumber) {
core.setFailed('Could not determine PR number for comment upsert.');
return;
}
Comment thread
aaronpowell marked this conversation as resolved.
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100,
});
const existing = comments.find((comment) => comment.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
console.log(`Updated existing risk scan comment ${existing.id}`);
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
console.log('Created new risk scan comment');
}
51 changes: 51 additions & 0 deletions .github/workflows/pr-risk-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: PR Risk Scan — Gate

on:
pull_request:
branches: [staged]
types: [opened, synchronize, reopened]
paths:
- "skills/**"
- "agents/**"
- "workflows/**"
- "plugins/**"
- "hooks/**"
- "instructions/**"

permissions:
contents: read
actions: read

Comment on lines +15 to +18
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0

- name: Collect changed files
run: |
git diff --name-only --diff-filter=ACMR "origin/${{ github.base_ref }}...HEAD" > changed-files.txt
echo "Changed files:"
cat changed-files.txt || true

- name: Run PR risk scanner
run: |
mkdir -p pr-risk-results
node ./eng/pr-risk-scan.mjs \
--files changed-files.txt \
--output-json pr-risk-results/results.json \
--output-md pr-risk-results/report.md
Comment thread
aaronpowell marked this conversation as resolved.

- name: Save metadata
run: |
echo "${{ github.event.pull_request.number }}" > pr-risk-results/pr-number.txt

- name: Upload scan artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: pr-risk-scan-results
path: pr-risk-results/
retention-days: 1
Comment on lines +46 to +51
Loading
Loading