(rootDir: string)
| 343 | * normal PR detection used by `ci check`. |
| 344 | */ |
| 345 | export function resolveTargetPrNumber(rootDir: string): string | null { |
| 346 | if (process.env.GITHUB_EVENT_NAME === 'workflow_run') { |
| 347 | const event = readGitHubEventPayload(); |
| 348 | const headSha = event?.workflow_run?.head_sha; |
| 349 | const repo = process.env.GITHUB_REPOSITORY; |
| 350 | // Sanitize both before they reach the gh api path: a 40-hex SHA and an owner/repo slug. |
| 351 | if (headSha && /^[0-9a-f]{40}$/i.test(headSha) && repo && /^[\w.-]+\/[\w.-]+$/.test(repo)) { |
| 352 | return findOpenPrByHeadSha(repo, headSha, rootDir); |
| 353 | } |
| 354 | return null; |
| 355 | } |
| 356 | return detectPrNumber(); |
| 357 | } |
| 358 | |
| 359 | /** |
| 360 | * Find the open PR whose head commit is `headSha`. |
| 361 | * |
| 362 | * `GET commits/{sha}/pulls` is the cheap lookup, but it only knows about commits that |
| 363 | * live in the base repo's own branches — for a PR opened from a fork the head commit |
| 364 | * isn't there, so it returns `[]`. Fall back to scanning the repo's open PRs and matching |
| 365 | * on `head.sha`. Both derive the target purely from the trusted SHA, so the security |
| 366 | * model (never trust the artifact, never trust `workflow_run.pull_requests[]`, which |
| 367 | * GitHub leaves empty for forks) is preserved. |
| 368 | */ |
| 369 | function findOpenPrByHeadSha(repo: string, headSha: string, rootDir: string): string | null { |
no test coverage detected
searching dependent graphs…