mirror of
https://github.com/wilsonfreitas/awesome-quant.git
synced 2026-08-14 12:28:05 +00:00
chore: migrate project documents to Linear
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
||||
# PR Review Agent — Design Spec
|
||||
|
||||
**Date**: 2026-03-22
|
||||
**Status**: Approved
|
||||
|
||||
## Overview
|
||||
|
||||
An automated GitHub Actions workflow that evaluates every new pull request against the rules in `CONTRIBUTING.md`. Compliant PRs are auto-merged to `main`. Non-compliant PRs are left untouched for manual review.
|
||||
|
||||
## Goals
|
||||
|
||||
- Auto-merge PRs that fully comply with all contributing rules
|
||||
- Zero false positives — only merge when every check passes
|
||||
- No action on non-compliant PRs (no comments, no closing, no labels)
|
||||
- Notifications via GitHub's built-in notification system
|
||||
|
||||
> **Note**: CONTRIBUTING.md states that certain PRs "will be closed" automatically. This agent deliberately deviates from that — non-compliant PRs are left open for manual review instead. The maintainer handles rejections personally.
|
||||
|
||||
## New Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `.github/workflows/pr-review.yml` | Workflow triggered on PR open/update |
|
||||
| `scripts/review_pr.py` | Validation script implementing all CONTRIBUTING.md rules |
|
||||
|
||||
## Component 1: GitHub Actions Workflow (`pr-review.yml`)
|
||||
|
||||
**Trigger**: `pull_request_target` events (types: `opened`, `synchronize`, `reopened`, `edited`) targeting `main`.
|
||||
|
||||
> **Why `pull_request_target`?** Most contributions come from forks. The `pull_request` event gives a read-only `GITHUB_TOKEN` for fork PRs, which cannot merge. `pull_request_target` runs in the context of the base repo and has write access. This is safe because the validation script never executes code from the PR — it only reads the diff via the GitHub API.
|
||||
|
||||
**Steps**:
|
||||
1. Checkout the base branch (not the PR branch — security measure with `pull_request_target`)
|
||||
2. Set up Python + uv
|
||||
3. Run the validation script: `uv run python scripts/review_pr.py`
|
||||
4. On exit 0: squash-merge the PR directly (no approval step needed)
|
||||
5. On non-zero exit: do nothing
|
||||
|
||||
> **Why no approval step?** The default `GITHUB_TOKEN` cannot submit an approving review on a PR triggered by the same workflow context. Since the repo does not require branch protection approvals, the workflow merges directly.
|
||||
|
||||
**Permissions**: `contents: write`, `pull-requests: write`.
|
||||
|
||||
**Concurrency**: No special concurrency controls needed — each PR runs independently.
|
||||
|
||||
## Component 2: Validation Script (`scripts/review_pr.py`)
|
||||
|
||||
A single Python script using `PyGithub` (already a project dependency) and `urllib.request` from the standard library (for URL reachability checks).
|
||||
|
||||
### Input
|
||||
|
||||
Environment variables set by the workflow:
|
||||
- `GITHUB_TOKEN` — GitHub Actions token
|
||||
- `PR_NUMBER` — the pull request number
|
||||
- `GITHUB_REPOSITORY` — `owner/repo` string
|
||||
|
||||
### Validation Pipeline
|
||||
|
||||
All checks must pass for auto-merge. The script exits 0 only if every check passes, non-zero otherwise.
|
||||
|
||||
#### 1. PR Description Check
|
||||
- Reject if the PR body is empty or whitespace-only.
|
||||
|
||||
#### 2. Files Changed Check
|
||||
- Only `README.md` should be modified.
|
||||
- Any other file changed → skip (exit non-zero).
|
||||
|
||||
#### 3. Extract Added Lines
|
||||
- From the PR diff via the GitHub API (not from a local checkout of the PR branch).
|
||||
- Extract only lines added to `README.md`.
|
||||
- Ignore blank lines, section headers (`##`, `###`), and other non-entry lines.
|
||||
|
||||
#### 4. Single Entry Check
|
||||
- Exactly one new entry line must be added.
|
||||
- Zero or more than one → skip.
|
||||
|
||||
#### 5. Format Validation
|
||||
The entry must match the regex used by `parse.py`:
|
||||
```
|
||||
^\s*- \[(.*)\]\((.*)\) - (.*)$
|
||||
```
|
||||
|
||||
Additional checks:
|
||||
- Description ends with a period (`.`) before the optional `[GitHub]` link.
|
||||
- All URLs use `https://`.
|
||||
- `[GitHub](url)` link, if present, uses the exact format `[GitHub](https://github.com/owner/repo)`.
|
||||
|
||||
#### 6. Duplicate Check
|
||||
- Search the current `README.md` (from the base branch) for the project name (case-insensitive).
|
||||
- Search for all URLs found in the entry.
|
||||
- Query the GitHub API for open and recently closed PRs that contain the same project name or URL.
|
||||
- If any match is found → skip.
|
||||
|
||||
#### 7. Section Placement Check
|
||||
- Verify the entry is placed under a valid `##` (language) and `###` (category) heading.
|
||||
- The entry must not be floating outside a recognized section.
|
||||
|
||||
#### 8. Activity Check
|
||||
For any GitHub URL found in the entry (primary URL or `[GitHub](url)` link):
|
||||
- Fetch the repo via GitHub API.
|
||||
- `archived == true` → skip.
|
||||
- Last push date older than 365 days from the workflow run date → skip.
|
||||
- No README file in the repo → skip.
|
||||
|
||||
If the entry has **no GitHub URL at all** (e.g., a CRAN-only or PyPI-only entry without a `[GitHub]` link), skip auto-merge and leave for manual review. Activity cannot be verified without a GitHub repo.
|
||||
|
||||
#### 9. URL Reachability
|
||||
- Verify the primary URL returns a non-error HTTP status (2xx or 3xx).
|
||||
- Uses `urllib.request` with a 10-second timeout.
|
||||
|
||||
### Output
|
||||
- Prints a structured summary to stdout (pass/fail per check) for workflow logs.
|
||||
- Exit code 0 = all passed, non-zero = at least one check failed.
|
||||
|
||||
## Component 3: Merge & Notification Flow
|
||||
|
||||
### On All Checks Pass (exit 0)
|
||||
1. The workflow squash-merges the PR to `main` with commit message: `Add [Project Name] (#PR_NUMBER)`.
|
||||
2. A merge comment is posted: *"All checks passed. Thanks for the contribution!"*
|
||||
3. This triggers the existing `build.yml` workflow (push to `main` with `README.md` change), so the site auto-updates.
|
||||
|
||||
### On Any Check Fails (non-zero exit)
|
||||
- The workflow does nothing.
|
||||
- The PR remains open for manual review.
|
||||
|
||||
### Notifications
|
||||
GitHub's built-in notifications cover all cases:
|
||||
- **New PR opened** → notified as repo owner.
|
||||
- **PR auto-merged** → notified via merge event.
|
||||
- **PR left open** → visible in open PR list.
|
||||
|
||||
No additional notification infrastructure required.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `PyGithub` — already in `pyproject.toml`
|
||||
- `urllib.request` — standard library, no installation needed
|
||||
- No new dependencies
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- The `GITHUB_TOKEN` provided by GitHub Actions has scoped permissions (only `contents: write` and `pull-requests: write`).
|
||||
- Uses `pull_request_target` for fork write access, but the workflow checks out the **base branch only** — never the PR branch. The validation script reads the PR diff via the GitHub API, never executing PR code locally.
|
||||
- URL reachability checks use HEAD/GET requests only via `urllib.request`.
|
||||
@@ -1,96 +0,0 @@
|
||||
# Telegram-Notified, GitHub-Gated PR Merge — Design Spec
|
||||
|
||||
**Date:** 2026-07-22
|
||||
**Status:** Approved for planning
|
||||
|
||||
## Overview
|
||||
|
||||
Replace direct automatic merging in the PR reviewer workflow with a human approval gate. When `scripts/review_pr.py` passes, the workflow sends the maintainer a Telegram notification and creates a merge job that waits for approval through a protected GitHub Environment. Approval remains inside GitHub and works from GitHub Mobile on iPhone.
|
||||
|
||||
The Telegram message is informational. It never contains credentials and cannot itself authorize a merge.
|
||||
|
||||
## Goals
|
||||
|
||||
- Never merge solely because the deterministic reviewer passed.
|
||||
- Notify the maintainer on Telegram whenever a PR becomes eligible for approval.
|
||||
- Allow approval or rejection from GitHub Mobile.
|
||||
- Bind approval to one workflow run and one PR head commit.
|
||||
- Revalidate immediately before merging and fail closed if state changed.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Approving or merging directly inside Telegram.
|
||||
- Sending Telegram messages for failed reviews.
|
||||
- Automatically commenting on or closing rejected PRs.
|
||||
- Expanding the deterministic acceptance rules in `scripts/review_pr.py`.
|
||||
|
||||
## Workflow
|
||||
|
||||
The existing workflow is split into three jobs:
|
||||
|
||||
1. **Review:** Run `scripts/review_pr.py` against the PR using the base-branch implementation. Record the PR number, title, author, URL, and exact head SHA.
|
||||
2. **Notify:** If review passes, call Telegram's `sendMessage` API using repository secrets. Include an inline URL button that opens the exact GitHub Actions run.
|
||||
3. **Approve and merge:** Reference the protected `auto-merge-approval` GitHub Environment. GitHub holds this job until a required reviewer approves or rejects it. After approval, verify the PR is open and its head SHA is unchanged, rerun the reviewer against current base state, confirm mergeability, and squash-merge using the captured SHA.
|
||||
|
||||
Any error, ambiguity, stale SHA, failed revalidation, rejected deployment, or merge conflict prevents the merge.
|
||||
|
||||
## Telegram Message
|
||||
|
||||
The message clearly distinguishes eligibility from approval:
|
||||
|
||||
> Deterministic PR checks passed. Human approval is required.
|
||||
>
|
||||
> PR #123 — Project title
|
||||
> Author: contributor
|
||||
> Commit: abc1234
|
||||
|
||||
It includes links to the PR and the exact workflow run. The workflow escapes all contributor-controlled fields for Telegram's selected parse mode, or sends plain text, so titles and usernames cannot alter message markup.
|
||||
|
||||
## GitHub Environment
|
||||
|
||||
Create a repository Environment named `auto-merge-approval` with the maintainer as a required reviewer. GitHub Mobile displays protected-environment review requests and supports approving or rejecting them on iPhone.
|
||||
|
||||
Self-review prevention remains disabled so maintainer-authored PRs can use the same mechanism. Environment approval waits expire according to GitHub's platform limit, currently 30 days.
|
||||
|
||||
## Secrets and Permissions
|
||||
|
||||
Repository Actions secrets:
|
||||
|
||||
- `TELEGRAM_BOT_TOKEN`: token issued by BotFather.
|
||||
- `TELEGRAM_CHAT_ID`: the maintainer's destination chat ID.
|
||||
|
||||
The notification job needs no GitHub write permission. The merge job receives only the GitHub permissions required to inspect and merge the PR. Telegram receives public PR metadata only; GitHub tokens and repository secrets are never placed in message text or URLs.
|
||||
|
||||
The workflow continues using `pull_request_target` while checking out only trusted base-branch code. It never executes code from the contributor branch.
|
||||
|
||||
## Race and Failure Handling
|
||||
|
||||
- Existing per-PR concurrency cancels obsolete runs after a new commit or relevant PR edit.
|
||||
- The merge call is pinned to the captured PR head SHA.
|
||||
- Final revalidation catches duplicates or conflicts introduced while approval was pending.
|
||||
- A failed Telegram request prevents the approval job from being created, ensuring the maintainer is not silently bypassed.
|
||||
- A rejected or expired Environment review leaves the PR open.
|
||||
- The workflow must inspect the merge API result and fail if GitHub declines the merge.
|
||||
|
||||
## Repository Setup
|
||||
|
||||
One-time manual configuration:
|
||||
|
||||
1. Create a Telegram bot and obtain its token.
|
||||
2. Send the bot a message and determine the destination chat ID.
|
||||
3. Add both values as repository Actions secrets.
|
||||
4. Create the `auto-merge-approval` GitHub Environment.
|
||||
5. Add the maintainer as a required reviewer.
|
||||
6. Enable protected-deployment push notifications in GitHub Mobile.
|
||||
|
||||
## Verification
|
||||
|
||||
Tests cover pass/fail reviewer outcomes, Telegram-safe message construction, stale head SHA rejection, changed base-state revalidation, merge conflicts, and unsuccessful merge API responses.
|
||||
|
||||
A controlled test PR verifies the end-to-end behavior:
|
||||
|
||||
1. Passing review sends Telegram notification.
|
||||
2. Merge job waits for Environment approval.
|
||||
3. Rejection leaves the PR open.
|
||||
4. Approval from GitHub Mobile runs final validation and merges.
|
||||
5. Updating the PR while approval is pending makes the old run incapable of merging the new head.
|
||||
Reference in New Issue
Block a user