diff --git a/CODEOWNERS b/CODEOWNERS index 7904c19..7a61d2b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # Repository CODEOWNERS -* @mdzhang +/src @mdzhang diff --git a/badges/coverage.svg b/badges/coverage.svg index 07fa16e..7c68c39 100644 --- a/badges/coverage.svg +++ b/badges/coverage.svg @@ -1 +1 @@ -Coverage: 21.1%Coverage21.1% \ No newline at end of file +Coverage: 19.49%Coverage19.49% \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 488603c..0ee2f66 100644 --- a/dist/index.js +++ b/dist/index.js @@ -32795,10 +32795,9 @@ async function getCodeowners(client, prNumber, filePath = 'CODEOWNERS') { result.data.content, // @ts-expect-error false positive result.data.encoding).toString(); - core.debug(`codeowners fileContent is:\n${fileContent}`); } catch (error) { - core.warning(`Could not find pull request #${prNumber}, skipping`); + core.warning(`Could not find pull request #${prNumber}, skipping (${error.message})`); return []; } // rm newlines & comments; convert to array of 2-tupes, @@ -32806,8 +32805,29 @@ async function getCodeowners(client, prNumber, filePath = 'CODEOWNERS') { .split(/\r?\n/) .filter(l => l.trim().length > 0) .filter(l => !l.startsWith('#')) - .map(l => l.split(' ')); - core.debug(`codeowners is ${codeowners}`); + .map(l => l.split(' ')) + .filter(([glob, team]) => { + if (team === undefined) { + core.warning(`CODEOWNERS had glob ${glob} w/o matching team`); + } + return team !== undefined; + }) + .map(([glob, team]) => { + // do some munging to support CODEOWNER format globs + let finalGlob = glob; + // convert directories like foo/ to foo/** + if (finalGlob.endsWith('/')) { + finalGlob += '**'; + } + else { + // convert directories like foo to foo/** + const last = finalGlob.split('\\').pop()?.split('/').pop(); + if (!last?.includes('.')) { + finalGlob += '/**'; + } + } + return [finalGlob, team]; + }); if (!codeowners.length) { core.warning(`Pull request #${prNumber} has no codeowners`); return []; @@ -32899,7 +32919,7 @@ async function labeler() { } core.debug(`labelsToOwner is ${labelsToOwner}`); const labelMap = flip(JSON.parse(labelsToOwner)); - core.debug(`labelMap is ${labelMap}`); + core.debug(`labelMap is ${JSON.stringify(Object.fromEntries(labelMap))}`); const preexistingLabels = pullRequest.data.labels.map((l) => l.name); const allLabels = new Set(preexistingLabels); const labels = getMatchingCodeownerLabels(pullRequest.changedFiles, codeowners, labelMap); @@ -32929,19 +32949,16 @@ async function labeler() { core.setOutput('all-labels', labelsToAdd.join(',')); } function getMatchingCodeownerLabels(changedFiles, entries, labelMap) { - // const repoUrlPrefix = `https://github.com/${github.context.repo.owner}/${github.context.repo.repo}/blob`; const allLabels = new Set(); for (const changedFile of changedFiles) { - // const refPath = changedFile.blob_url.replace(repoUrlPrefix, ''); - // const i = refPath.indexOf('/'); - // const [_, path] = [refPath.slice(0,i), refPath.slice(i+1)]; core.debug(`checking path ${changedFile}`); for (const entry of entries) { const [glob, team] = entry; - core.debug(`-- checking glob ${glob}, team ${team}`); - if ((0, minimatch_1.minimatch)(changedFile, glob)) { + if ((0, minimatch_1.minimatch)(`/${changedFile}`, glob)) { + core.debug(`-- matched glob ${glob}, team ${team}`); const label = labelMap.get(team); if (label !== undefined) { + core.debug(`-- adding label ${label}`); allLabels.add(label); } } diff --git a/src/api.ts b/src/api.ts index 3745dea..f1c730c 100644 --- a/src/api.ts +++ b/src/api.ts @@ -90,9 +90,10 @@ export async function getCodeowners( // @ts-expect-error false positive result.data.encoding ).toString() - core.debug(`codeowners fileContent is:\n${fileContent}`) } catch (error: any) { - core.warning(`Could not find pull request #${prNumber}, skipping`) + core.warning( + `Could not find pull request #${prNumber}, skipping (${error.message})` + ) return [] } @@ -102,8 +103,30 @@ export async function getCodeowners( .filter(l => l.trim().length > 0) .filter(l => !l.startsWith('#')) .map(l => l.split(' ')) + .filter(([glob, team]) => { + if (team === undefined) { + core.warning(`CODEOWNERS had glob ${glob} w/o matching team`) + } - core.debug(`codeowners is ${codeowners}`) + return team !== undefined + }) + .map(([glob, team]) => { + // do some munging to support CODEOWNER format globs + let finalGlob = glob + + // convert directories like foo/ to foo/** + if (finalGlob.endsWith('/')) { + finalGlob += '**' + } else { + // convert directories like foo to foo/** + const last = finalGlob.split('\\').pop()?.split('/').pop() + if (!last?.includes('.')) { + finalGlob += '/**' + } + } + + return [finalGlob, team] + }) if (!codeowners.length) { core.warning(`Pull request #${prNumber} has no codeowners`) diff --git a/src/main.ts b/src/main.ts index e3e96e3..63e03ec 100644 --- a/src/main.ts +++ b/src/main.ts @@ -56,7 +56,7 @@ async function labeler() { core.debug(`labelsToOwner is ${labelsToOwner}`) const labelMap: Map = flip(JSON.parse(labelsToOwner)) - core.debug(`labelMap is ${labelMap}`) + core.debug(`labelMap is ${JSON.stringify(Object.fromEntries(labelMap))}`) const preexistingLabels = pullRequest.data.labels.map( (l: { name: string }) => l.name ) @@ -109,21 +109,17 @@ export function getMatchingCodeownerLabels( entries: string[][], labelMap: Map ): Set { - // const repoUrlPrefix = `https://github.com/${github.context.repo.owner}/${github.context.repo.repo}/blob`; const allLabels: Set = new Set() for (const changedFile of changedFiles) { - // const refPath = changedFile.blob_url.replace(repoUrlPrefix, ''); - // const i = refPath.indexOf('/'); - // const [_, path] = [refPath.slice(0,i), refPath.slice(i+1)]; - core.debug(`checking path ${changedFile}`) for (const entry of entries) { const [glob, team] = entry - core.debug(`-- checking glob ${glob}, team ${team}`) - if (minimatch(changedFile, glob)) { + if (minimatch(`/${changedFile}`, glob)) { + core.debug(`-- matched glob ${glob}, team ${team}`) const label = labelMap.get(team) if (label !== undefined) { + core.debug(`-- adding label ${label}`) allLabels.add(label) } }