Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 1 | /** |
| 2 | * CODEOWNERS: who owns which paths of a repository, read from the branch a | |
| 3 | * pull request merges into. Mirrors `crates/contracts/src/codeowners.rs`, | |
| 4 | * which holds the parser and the rules. | |
| 5 | */ | |
| 6 | ||
| 7 | /** Where the file is looked for, first found wins. */ | |
| 8 | export const CODEOWNERS_LOCATIONS = [ | |
| 9 | ".g1t/CODEOWNERS", | |
| 10 | ".github/CODEOWNERS", | |
| 11 | "CODEOWNERS", | |
| 12 | "docs/CODEOWNERS", | |
| 13 | ".gitlab/CODEOWNERS", | |
| 14 | ] as const; | |
| 15 | ||
| 16 | /** Whether `path` is one of the places a CODEOWNERS file is read from. */ | |
| 17 | export function isCodeownersPath(path: string): boolean { | |
| 18 | return (CODEOWNERS_LOCATIONS as readonly string[]).includes(path); | |
| 19 | } | |
| 20 | ||
| 21 | export type CodeownersErrorKind = | |
| 22 | | "too_large" | |
| 23 | | "negation" | |
| 24 | | "character_range" | |
| 25 | | "bad_pattern" | |
| 26 | | "bad_owner" | |
| 27 | | "bad_section" | |
| 28 | | "unknown_user" | |
| 29 | | "unknown_team" | |
| 30 | | "unknown_email" | |
| 31 | | "no_write_access" | |
| 32 | | "team_no_access"; | |
| 33 | ||
| 34 | /** One problem with a CODEOWNERS file, on a line (0 for the whole file). */ | |
| 35 | export type CodeownersError = { | |
| 36 | line: number; | |
| 37 | kind: CodeownersErrorKind; | |
| 38 | /** The owner or pattern at fault, as written. */ | |
| 39 | token: string | null; | |
| 40 | message: string; | |
| 41 | }; | |
| 42 | ||
| 43 | /** A CODEOWNERS file at one branch, checked like a linter. */ | |
| 44 | export type CodeownersReport = { | |
| 45 | /** Where it was found; null when there is none. */ | |
| 46 | path: string | null; | |
| 47 | ref: string; | |
| 48 | size: number; | |
| 49 | rules: number; | |
| 50 | sections: string[]; | |
| 51 | errors: CodeownersError[]; | |
| 52 | }; | |
| 53 | ||
| 54 | /** Where one rule's review stands on a pull request. */ | |
| 55 | export type OwnerReview = { | |
| 56 | /** The section's name; null for rules before any section. */ | |
| 57 | section: string | null; | |
| 58 | line: number; | |
| 59 | pattern: string; | |
| 60 | /** Owners as written: `@ana`, `@acme/backend`, `ana@example.com`. */ | |
| 61 | owners: string[]; | |
| 62 | files: string[]; | |
| 63 | optional: boolean; | |
| 64 | required: number; | |
| 65 | approved_by: string[]; | |
| 66 | changes_requested_by: string[]; | |
| 67 | satisfied: boolean; | |
| 68 | }; | |
| 69 | ||
| 70 | /** Who owns what a pull request changes, and whose approval is still needed. */ | |
| 71 | export type PullCodeOwners = { | |
| 72 | path: string; | |
| 73 | /** Whether branch protection requires code owners' approval. */ | |
| 74 | required: boolean; | |
| 75 | reviews: OwnerReview[]; | |
| 76 | /** What still stands in the way; null when nothing does. */ | |
| 77 | missing: string | null; | |
| 78 | errors: number; | |
| 79 | }; | |
| 80 | ||
| 81 | /** A short label for an error kind, for the errors view. */ | |
| 82 | export const CODEOWNERS_ERROR_LABELS: Record<CodeownersErrorKind, string> = { | |
| 83 | too_large: "Too large", | |
| 84 | negation: "Negation", | |
| 85 | character_range: "Character range", | |
| 86 | bad_pattern: "Bad pattern", | |
| 87 | bad_owner: "Bad owner", | |
| 88 | bad_section: "Bad section", | |
| 89 | unknown_user: "Unknown user", | |
| 90 | unknown_team: "Unknown team", | |
| 91 | unknown_email: "Unknown email", | |
| 92 | no_write_access: "No write access", | |
| 93 | team_no_access: "Team without access", | |
| 94 | }; |