Skip to content
Merged
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
159 changes: 159 additions & 0 deletions .github/workflows/squad-repo-health.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Repo Health

on:
pull_request_target:
branches: [dev]
types: [opened, synchronize, reopened]

# pull_request_target gives write token even for fork PRs.
# SAFETY: We check out the BASE branch (trusted scripts) and fetch the PR
# head only as a git ref for analysis — no PR-supplied code is executed.
permissions:
contents: read
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
# ─── Bootstrap Protection (BLOCKING) ────────────────────────────────
bootstrap-protection:
name: Bootstrap Protection
runs-on: ubuntu-latest
timeout-minutes: 3
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: |
scripts/check-bootstrap-deps.mjs
sparse-checkout-cone-mode: false
Comment thread
diberry marked this conversation as resolved.
- name: Fetch PR head (data only — not executed)
run: git fetch origin ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Check bootstrap dependencies
id: bootstrap
run: |
set +e
OUTPUT=$(node scripts/check-bootstrap-deps.mjs --ref ${{ github.event.pull_request.head.sha }} 2>&1)
EXIT_CODE=$?
echo "$OUTPUT"
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
exit $EXIT_CODE

# ─── Squad File Leakage (WARNING) ───────────────────────────────────
squad-leakage:
name: Squad File Leakage
runs-on: ubuntu-latest
timeout-minutes: 3
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR head (data only — not executed)
run: git fetch origin ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Detect .squad/ leakage
id: leakage
run: |
git fetch origin dev --quiet
OUTPUT=$(node scripts/check-squad-leakage.mjs origin/dev ${{ github.event.pull_request.head.sha }} 2>&1)
echo "$OUTPUT"
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment on leakage
if: always()
uses: actions/github-script@v7
with:
script: |
const { run } = await import(`${process.env.GITHUB_WORKSPACE}/scripts/repo-health-comment.mjs`);
await run({
github,
context,
output: `${{ steps.leakage.outputs.result }}`,
job: 'leakage',
});

# ─── Architectural Review (INFORMATIONAL) ───────────────────────────
architectural-review:
name: Architectural Review
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR head (data only — not executed)
run: git fetch origin ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Run architectural review
id: arch
run: |
git fetch origin dev --quiet
OUTPUT=$(node scripts/architectural-review.mjs origin/dev ${{ github.event.pull_request.head.sha }} 2>&1)
echo "$OUTPUT"
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment on findings
if: always()
uses: actions/github-script@v7
with:
script: |
const { run } = await import(`${process.env.GITHUB_WORKSPACE}/scripts/repo-health-comment.mjs`);
await run({
github,
context,
output: `${{ steps.arch.outputs.result }}`,
job: 'architectural',
});

# ─── Security Review (INFORMATIONAL) ────────────────────────────────
security-review:
name: Security Review
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR head (data only — not executed)
run: git fetch origin ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Run security review
id: security
run: |
git fetch origin dev --quiet
OUTPUT=$(node scripts/security-review.mjs origin/dev ${{ github.event.pull_request.head.sha }} 2>&1)
echo "$OUTPUT"
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment on findings
if: always()
uses: actions/github-script@v7
with:
script: |
const { run } = await import(`${process.env.GITHUB_WORKSPACE}/scripts/repo-health-comment.mjs`);
await run({
github,
context,
output: `${{ steps.security.outputs.result }}`,
job: 'security',
});
Loading
Loading