reduce api calls

This commit is contained in:
J. Nick Koston
2026-03-02 16:01:23 -10:00
parent d9b5f54cf6
commit 769031b724
3 changed files with 30 additions and 27 deletions
+23 -4
View File
@@ -13,8 +13,9 @@
function globToRegex(pattern) {
let regexStr = pattern
.replace(/([.+^=!:${}()|[\]\\])/g, '\\$1')
.replace(/\*\*/g, '.*')
.replace(/\*/g, '[^/]*')
.replace(/\*\*/g, '\x00GLOBSTAR\x00') // protect ** from next replace
.replace(/\*/g, '[^/]*') // single star
.replace(/\x00GLOBSTAR\x00/g, '.*') // restore globstar
.replace(/\?/g, '.');
return new RegExp('^' + regexStr + '$');
}
@@ -91,11 +92,12 @@ function classifyOwners(rawOwners) {
*
* @param {string[]} files - list of file paths
* @param {Array} codeownersPatterns - from parseCodeowners / fetchCodeowners
* @returns {{ users: Set<string>, teams: Set<string> }}
* @returns {{ users: Set<string>, teams: Set<string>, matchedFileCount: number }}
*/
function getEffectiveOwners(files, codeownersPatterns) {
const users = new Set();
const teams = new Set();
let matchedFileCount = 0;
for (const file of files) {
// Last matching pattern wins for each file
@@ -106,19 +108,36 @@ function getEffectiveOwners(files, codeownersPatterns) {
}
}
if (effectiveOwners) {
matchedFileCount++;
const classified = classifyOwners(effectiveOwners);
for (const u of classified.users) users.add(u);
for (const t of classified.teams) teams.add(t);
}
}
return { users, teams };
return { users, teams, matchedFileCount };
}
/**
* Read and parse the CODEOWNERS file from disk.
*
* Use this when the repo is already checked out (avoids an API call).
*
* @param {string} [repoRoot='.'] - path to the repo root
* @returns {Array<{pattern: string, regex: RegExp, owners: string[]}>}
*/
function loadCodeowners(repoRoot = '.') {
const fs = require('fs');
const path = require('path');
const content = fs.readFileSync(path.join(repoRoot, 'CODEOWNERS'), 'utf8');
return parseCodeowners(content);
}
module.exports = {
globToRegex,
parseCodeowners,
fetchCodeowners,
loadCodeowners,
classifyOwners,
getEffectiveOwners
};
@@ -30,7 +30,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const { fetchCodeowners, getEffectiveOwners } = require('./.github/scripts/codeowners.js');
const { loadCodeowners, getEffectiveOwners } = require('./.github/scripts/codeowners.js');
const owner = context.repo.owner;
const repo = context.repo.repo;
@@ -58,11 +58,8 @@ jobs:
return;
}
// Fetch and parse CODEOWNERS from base branch
const codeownersPatterns = await fetchCodeowners(
github, owner, repo,
context.payload.pull_request.base.sha
);
// Parse CODEOWNERS from the checked-out base branch
const codeownersPatterns = loadCodeowners();
// Get effective owners using last-match-wins semantics
const effective = getEffectiveOwners(changedFiles, codeownersPatterns);
+4 -17
View File
@@ -33,7 +33,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const { fetchCodeowners, getEffectiveOwners } = require('./.github/scripts/codeowners.js');
const { loadCodeowners, getEffectiveOwners } = require('./.github/scripts/codeowners.js');
const owner = context.repo.owner;
const repo = context.repo.repo;
@@ -60,11 +60,8 @@ jobs:
return;
}
// Fetch and parse CODEOWNERS file from base branch
const codeownersPatterns = await fetchCodeowners(
github, owner, repo,
context.payload.pull_request.base.sha
);
// Parse CODEOWNERS from the checked-out base branch
const codeownersPatterns = loadCodeowners();
console.log(`Parsed ${codeownersPatterns.length} codeowner patterns`);
@@ -85,17 +82,7 @@ jobs:
const effective = getEffectiveOwners(changedFiles, codeownersPatterns);
const matchedOwners = effective.users;
const matchedTeams = effective.teams;
// Count matched files for the comment
let matchedFileCount = 0;
for (const file of changedFiles) {
for (const { regex } of codeownersPatterns) {
if (regex.test(file)) {
matchedFileCount++;
break;
}
}
}
const matchedFileCount = effective.matchedFileCount;
if (matchedOwners.size === 0 && matchedTeams.size === 0) {
console.log('No codeowners found for any changed files');