CODEOWNERS: add @glennsong09 to src and test #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Review Checklist | ||
| # Posts a per-area sign-off checklist on every PR and auto-checks each item | ||
| # when one of that area's designated owners submits an approval. | ||
| # | ||
| # Reviewer lists are derived entirely from .github/CODEOWNERS — no duplication. | ||
| # To add an area or change owners, edit only CODEOWNERS. | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| pull_request_review: | ||
| types: [submitted] | ||
| permissions: | ||
| pull-requests: write | ||
| contents: read | ||
| jobs: | ||
| checklist: | ||
| runs-on: ubuntu-latest | ||
| # For review events only run on approvals; all PR events always run | ||
| if: | | ||
| github.event_name == 'pull_request' || | ||
| (github.event_name == 'pull_request_review' && | ||
| github.event.review.state == 'approved') | ||
| steps: | ||
| - uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const MARKER = '<!-- hdf5-review-checklist-v1 -->'; | ||
| const { owner, repo } = context.repo; | ||
| const pr_number = context.payload.pull_request.number; | ||
| // ---------------------------------------------------------------- | ||
| // Configuration | ||
| // | ||
| // LINE_THRESHOLD: lines changed (additions + deletions) within a | ||
| // single area below which a reviewer is auto-assigned using the | ||
| // fewest-open-PRs algorithm. Above this threshold the assignment | ||
| // is left to the maintainers — complex changes deserve a | ||
| // deliberate choice of who reviews them. | ||
| // ---------------------------------------------------------------- | ||
| const LINE_THRESHOLD = 50; | ||
| // ---------------------------------------------------------------- | ||
| // 1. Parse CODEOWNERS into a list of { pattern, label, owners } | ||
| // | ||
| // Rules: | ||
| // - Skip blank lines and lines starting with # | ||
| // - Skip the global wildcard (*) — it covers everything and | ||
| // would make every PR require every reviewer | ||
| // - Owners are the @-prefixed tokens after the pattern | ||
| // - Label is derived from the pattern path for display | ||
| // ---------------------------------------------------------------- | ||
| const { data: coData } = await github.rest.repos.getContent({ | ||
| owner, repo, path: '.github/CODEOWNERS', | ||
| }); | ||
| const coText = Buffer.from(coData.content, 'base64').toString('utf-8'); | ||
| function labelFromPattern(pattern) { | ||
| // /fortran/ → "fortran", /.github/.well-known → ".github/.well-known" | ||
| return pattern.replace(/^\//, '').replace(/\/$/, '') || pattern; | ||
| } | ||
| // Returns true if `file` (repo-relative, no leading slash) matches | ||
| // a CODEOWNERS-style gitignore pattern. | ||
| function matchesPattern(file, pattern) { | ||
| let p = pattern; | ||
| // Strip leading slash — CODEOWNERS anchors to root with it, | ||
| // but GitHub API paths have no leading slash | ||
| if (p.startsWith('/')) p = p.slice(1); | ||
| // Directory pattern: /fortran/ → matches fortran/<anything> | ||
| if (p.endsWith('/')) return file.startsWith(p); | ||
| // Glob pattern: convert * and ** to regex equivalents | ||
| if (p.includes('*')) { | ||
| const re = new RegExp( | ||
| '^' + | ||
| p.replace(/\./g, '\\.').replace(/\*\*/g, ' | ||