nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at release-25.11 101 lines 2.3 kB view raw
1// @ts-check 2const { promisify } = require('node:util') 3const execFile = promisify(require('node:child_process').execFile) 4 5/** 6 * @param {{ 7 * args: string[] 8 * core: import('@actions/core'), 9 * quiet?: boolean, 10 * repoPath?: string, 11 * }} RunGitProps 12 */ 13async function runGit({ args, repoPath, core, quiet }) { 14 if (repoPath) { 15 args = ['-C', repoPath, ...args] 16 } 17 18 if (!quiet) { 19 core.info(`About to run \`git ${args.map((s) => `'${s}'`).join(' ')}\``) 20 } 21 22 return await execFile('git', args) 23} 24 25/** 26 * Gets the SHA, subject and changed files for each commit in the given PR. 27 * 28 * Don't use GitHub API at all: the "list commits on PR" endpoint has a limit 29 * of 250 commits and doesn't return the changed files. 30 * 31 * @param {{ 32 * core: import('@actions/core'), 33 * pr: Awaited<ReturnType<InstanceType<import('@actions/github/lib/utils').GitHub>["rest"]["pulls"]["get"]>>["data"] 34 * repoPath?: string, 35 * }} GetCommitMessagesForPRProps 36 * 37 * @returns {Promise<{ 38 * subject: string, 39 * sha: string, 40 * changedPaths: string[], 41 * changedPathSegments: Set<string>, 42 * }[]>} 43 */ 44async function getCommitDetailsForPR({ core, pr, repoPath }) { 45 await runGit({ 46 args: ['fetch', `--depth=1`, 'origin', pr.base.sha], 47 repoPath, 48 core, 49 }) 50 await runGit({ 51 args: ['fetch', `--depth=${pr.commits + 1}`, 'origin', pr.head.sha], 52 repoPath, 53 core, 54 }) 55 56 const shas = ( 57 await runGit({ 58 args: [ 59 'rev-list', 60 `--max-count=${pr.commits}`, 61 `${pr.base.sha}..${pr.head.sha}`, 62 ], 63 repoPath, 64 core, 65 }) 66 ).stdout 67 .split('\n') 68 .map((s) => s.trim()) 69 .filter(Boolean) 70 71 return Promise.all( 72 shas.map(async (sha) => { 73 // Subject first, then a blank line, then filenames. 74 const result = ( 75 await runGit({ 76 args: ['log', '--format=%s', '--name-only', '-1', sha], 77 repoPath, 78 core, 79 quiet: true, 80 }) 81 ).stdout.split('\n') 82 83 const subject = result[0] 84 85 const changedPaths = result.slice(2, -1) 86 87 const changedPathSegments = new Set( 88 changedPaths.flatMap((path) => path.split('/')), 89 ) 90 91 return { 92 sha, 93 subject, 94 changedPaths, 95 changedPathSegments, 96 } 97 }), 98 ) 99} 100 101module.exports = { getCommitDetailsForPR }