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
16 changes: 16 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## What this PR does

<!-- 1-2 sentences describing the change -->

## Why

<!-- The user-facing or technical reason this change is needed -->

## codegraph signals

<!--
This section is auto-populated by the codegraph CI bot below.
If your PR introduces new dead code, untested public functions, cycles,
or breaks resolver coverage, the bot will flag it as a comment on this PR.
Please address high-severity findings before requesting review.
-->
136 changes: 136 additions & 0 deletions .github/ci-templates/pr-review.workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# codegraph PR review workflow — TEMPLATE
#
# This file lives OUTSIDE .github/workflows/ on purpose: GitHub rejects
# pushes to .github/workflows/* from OAuth tokens that lack the `workflow`
# scope. By keeping the template here, the repo can be cloned + pushed-to
# with the default `repo` scope; activating the workflow is a one-time
# manual step (see README → "PR review CI").
#
# To activate:
# gh auth refresh -h github.com -s workflow
# cp .github/ci-templates/pr-review.workflow.yml .github/workflows/pr-review.yml
# git add .github/workflows/pr-review.yml
# git commit -m "ci: activate codegraph PR review"
# git push

name: codegraph PR review

on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write

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

jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout PR head
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip

- name: Install codegraph (PR head)
run: pip install -e .

- name: Build baseline graph from main
run: |
set -euxo pipefail
mkdir -p .baseline-checkout
git worktree add .baseline-checkout origin/main
(
cd .baseline-checkout
pip install -e . --quiet
codegraph build --no-incremental
codegraph baseline save --output ../.codegraph/baseline.db
)
if [ ! -f .codegraph/baseline.db ]; then
echo "BASELINE_MISSING=1" >> "$GITHUB_ENV"
echo "::warning::No baseline could be saved from main; running first-time review."
fi

- name: Build PR head graph
run: codegraph build --no-incremental

- name: Run codegraph review
run: |
set -uo pipefail
if [ -n "${BASELINE_MISSING:-}" ]; then
cat > review.md <<'EOF'
## codegraph PR review

No baseline graph from `main` was available for this run, so a
full diff review was skipped. The PR head was still parsed
successfully — codegraph review will activate from the next PR.
EOF
exit 0
fi
set +e
codegraph review \
--format markdown \
--output review.md \
--fail-on high \
--baseline .codegraph/baseline.db
rc=$?
set -e
if [ "$rc" -ne 0 ]; then
echo "REVIEW_FAILED=1" >> "$GITHUB_ENV"
fi

- name: Wrap review in comment template
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -e
{
echo "## codegraph PR review"
echo
echo "<details open>"
echo "<summary><b>Diff vs main</b> · severity ≤ <code>high</code></summary>"
echo
cat review.md
echo
echo "</details>"
echo
echo "<sub>Triggered by codegraph CI · <a href=\"${RUN_URL}\">last run</a></sub>"
} > comment.md

- name: Post or update PR comment
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
body-file: comment.md
edit-mode: replace
comment-tag: codegraph-review

- name: Upload review artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: codegraph-review
path: |
review.md
comment.md
.codegraph/graph.db
retention-days: 7

- name: Fail if findings exceed threshold
if: env.REVIEW_FAILED == '1'
run: |
echo "::error::codegraph review found high-or-critical findings. See PR comment for details."
exit 1
19 changes: 19 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "python"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 3
labels:
- "dependencies"
- "ci"
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,47 @@ node --test tests/*.js # 55 JS tests

---

## PR review CI (dogfood)

`codegraph` ships its own PR-review workflow as a template. Once activated,
every PR opened against `main` runs codegraph against itself, posts the diff
as a sticky PR comment, and fails the check on high-severity findings.

The workflow lives at
[`.github/ci-templates/pr-review.workflow.yml`](.github/ci-templates/pr-review.workflow.yml)
(outside `.github/workflows/` so the repo can be cloned and pushed-to with a
token that lacks the `workflow` OAuth scope). Activate with:

```bash
gh auth refresh -h github.com -s workflow
cp .github/ci-templates/pr-review.workflow.yml .github/workflows/pr-review.yml
git add .github/workflows/pr-review.yml
git commit -m "ci: activate codegraph PR review"
git push
```

Once active, the workflow:

1. Builds a graph from `origin/main` and saves it as a baseline.
2. Builds a graph from the PR head.
3. Runs `codegraph review --format markdown --fail-on high` against the diff.
4. Posts the result as a sticky PR comment (replaced on each push, no spam).
5. Fails the check if any high-or-critical findings appear.

**Local dry-run** before opening a PR:

```bash
git fetch origin main
./scripts/test-pr-review-locally.sh
# writes review.md + comment.md, exits non-zero if findings exceed --fail-on high
```

First-PR graceful path: if no baseline can be saved from `main` (brand-new
repo, empty default branch), the workflow posts a friendly "first-time
review" comment and passes — codegraph review activates from the next PR.

---

## Acknowledgements

`codegraph` stands on:
Expand Down
65 changes: 65 additions & 0 deletions scripts/test-pr-review-locally.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Dry-run the PR review workflow locally so you can validate it before pushing.
#
# Requires:
# - clean repo (no uncommitted changes)
# - origin/main fetched (`git fetch origin main`)
# - codegraph installed in editable mode (`pip install -e .`)
#
# Produces ./review.md and ./comment.md exactly like the CI does, but skips
# the GitHub-API steps (comment posting, artifact upload, exit code).
set -euo pipefail

REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"

if ! git diff-index --quiet HEAD --; then
echo "[WARN] working tree has uncommitted changes; review will reflect them" >&2
fi

if ! command -v codegraph >/dev/null 2>&1; then
echo "[ERROR] codegraph not on PATH — run \`pip install -e .\` first" >&2
exit 1
fi

echo "==> Building baseline from origin/main"
rm -rf /tmp/cg-baseline-checkout
git worktree add /tmp/cg-baseline-checkout origin/main
trap 'git worktree remove --force /tmp/cg-baseline-checkout 2>/dev/null || true' EXIT

(
cd /tmp/cg-baseline-checkout
codegraph build --no-incremental
codegraph baseline save --output "$REPO_ROOT/.codegraph/baseline.db"
)

echo "==> Building PR-head graph"
codegraph build --no-incremental

echo "==> Running codegraph review"
set +e
codegraph review \
--format markdown \
--output review.md \
--fail-on high \
--baseline .codegraph/baseline.db
rc=$?
set -e

echo "==> Wrapping into comment.md"
{
echo "## codegraph PR review"
echo
echo "<details open>"
echo "<summary><b>Diff vs main</b> · severity ≤ <code>high</code></summary>"
echo
cat review.md
echo
echo "</details>"
} > comment.md

echo
echo "----"
echo "review.md and comment.md written. Review exit code: $rc"
echo "(Non-zero = high/critical findings; CI would fail on this.)"
exit "$rc"
Loading