Skip to content

Validate PR #757

Validate PR #757 #1234

name: Slash Command Sweep
run-name: "Validate PR #${{ github.event.issue.number }}"
on:
issue_comment:
types: [created]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
get-jobs:
# Only run for PR comments that start with /sweep
if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/sweep') }}
runs-on: ubuntu-latest
outputs:
pr-number: ${{ steps.parse.outputs.pr-number }}
generator-args: ${{ steps.parse.outputs.generator-args }}
author-can-bypass: ${{ steps.auth.outputs.can-bypass }}
# Immutable ref (commit SHA) to prevent TOCTOU on refs/pull/<n>/head
ref: ${{ steps.ref_comment.outputs.ref }}
steps:
- name: Parse PR comment (/sweep ...)
id: parse
if: ${{ github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/sweep') }}
shell: bash
env:
BODY: ${{ github.event.comment.body }}
PR_NUMBER: ${{ github.event.issue.number }}
run: |
set -euo pipefail
# Require /sweep at the start of the line
cmd_line=$(printf "%s" "$BODY" | awk '/^\/sweep/{print; exit}')
if [[ -z "$cmd_line" ]]; then
echo "No /sweep command found at comment start" >&2
exit 1
fi
if [[ "$cmd_line" == "/sweep" ]]; then
cmd_args=""
else
cmd_args=${cmd_line#/sweep}
fi
cmd_args=$(echo "$cmd_args" | xargs || true)
echo "generator-args=$cmd_args" >> "$GITHUB_OUTPUT"
echo "pr-number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
- name: Check author permissions
id: auth
if: ${{ github.event_name == 'issue_comment' && github.event.issue.pull_request }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const username = context.payload.comment?.user?.login;
let permission = 'none';
try {
const res = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username });
permission = res.data?.permission || 'none';
} catch (e) {
permission = 'none';
}
const canBypass = ['admin','maintain','write'].includes(permission);
core.info(`Author ${username} permission: ${permission}; bypass=${canBypass}`);
core.setOutput('can-bypass', canBypass ? 'true' : 'false');
# ---- PR SHA pinning ----
- name: Resolve immutable PR ref (pin to head SHA)
id: ref_comment
if: ${{ github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/sweep') }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const pr = context.issue.number;
const res = await github.rest.pulls.get({ owner, repo, pull_number: pr });
const sha = res.data.head.sha;
core.info(`Resolved PR #${pr} head SHA: ${sha}`);
core.setOutput('ref', sha);
- name: Reply with run link
if: ${{ github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/sweep') && github.repository_owner == 'SemiAnalysisAI' }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
continue-on-error: true
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
AUTHOR: ${{ github.event.comment.user.login }}
GEN_CMD: ${{ steps.parse.outputs.generator-args }}
CAN_BYPASS: ${{ steps.auth.outputs.can-bypass }}
PINNED_REF: ${{ steps.ref_comment.outputs.ref }}
with:
github-token: ${{ github.token }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = context.issue.number;
const runUrl = process.env.RUN_URL;
const author = process.env.AUTHOR;
const genCmd = process.env.GEN_CMD || '';
const canBypass = (process.env.CAN_BYPASS || '').toLowerCase() === 'true';
const pinned = process.env.PINNED_REF || '';
const shortSha = pinned ? pinned.slice(0, 7) : '';
const approvalMsg = canBypass ? 'Approval: not required (trusted collaborator).' : "Approval: required in environment 'Outside Collaborator E2E Test'.";
const body = `@${author} Kicking off a sweep.\n\nRun: ${runUrl}\nCommand: \`${genCmd}\`\nPinned ref: \`${shortSha}\`\n${approvalMsg}`;
await github.rest.issues.createComment({ owner, repo, issue_number, body });
approval:
needs: get-jobs
if: ${{ github.event_name == 'issue_comment' && needs.get-jobs.outputs.pr-number != '' && needs.get-jobs.outputs.generator-args != '' && needs.get-jobs.outputs.author-can-bypass != 'true' }}
runs-on: ubuntu-latest
name: approval
environment: Outside Collaborator E2E Test
steps:
- run: echo "approved"
validate:
needs: [get-jobs, approval]
# always() is required to evaluate this condition when 'approval' is skipped (trusted author)
if: ${{ always() && needs.get-jobs.result == 'success' && needs.get-jobs.outputs.pr-number != '' && needs.get-jobs.outputs.generator-args != '' && (needs.get-jobs.outputs.author-can-bypass == 'true' || needs.approval.result == 'success') }}
# Concurrency at job level so non-/sweep comments don't cancel active runs
concurrency:
group: "sweep-PR#${{ needs.get-jobs.outputs.pr-number }}"
cancel-in-progress: true
uses: ./.github/workflows/e2e-tests.yml
name: validate
secrets: inherit
with:
generate-cli-command: ${{ needs.get-jobs.outputs.generator-args }}
test-name: PR #${{ needs.get-jobs.outputs.pr-number }} sweep
# Use pinned SHA to prevent TOCTOU on refs/pull/<n>/head
ref: ${{ needs.get-jobs.outputs.ref }}