summaryrefslogtreecommitdiff
path: root/ci/github-script/get-pr-commit-details.js
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-04 19:47:58 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-04 19:47:58 +0300
commit8d0d919fbf43230148da7533519ed0ffdfaa4197 (patch)
tree27e352d6ca09910e577ec27a10659814e88b15b9 /ci/github-script/get-pr-commit-details.js
parentfce202465d4fede9e19d4d057eebbaa702291652 (diff)
downloadProject-Tick-8d0d919fbf43230148da7533519ed0ffdfaa4197.tar.gz
Project-Tick-8d0d919fbf43230148da7533519ed0ffdfaa4197.zip
NOISSUE add GitHub Actions scripts for PR preparation and review management
- Introduced `prepare.js` to validate PR mergeability and branch targeting. - Added `reviews.js` for automated review dismissal and posting. - Created `run` script to execute actions with GitHub context. - Implemented rate limiting in `withRateLimit.js` to manage API requests. - Added `supportedBranches.js` for branch classification logic. - Created `update-pinned.sh` for updating pinned dependencies. - Added `pinned.json` to manage pinned Nix dependencies. - Updated `libnbtplusplus` version from 2.3 to 3.0 and adjusted README accordingly. Signed-off-by: Mehmet Samet Duman <yongdohyun@projecttick.org>
Diffstat (limited to 'ci/github-script/get-pr-commit-details.js')
-rw-r--r--ci/github-script/get-pr-commit-details.js101
1 files changed, 101 insertions, 0 deletions
diff --git a/ci/github-script/get-pr-commit-details.js b/ci/github-script/get-pr-commit-details.js
new file mode 100644
index 0000000000..fcccfeacd7
--- /dev/null
+++ b/ci/github-script/get-pr-commit-details.js
@@ -0,0 +1,101 @@
+// @ts-check
+const { promisify } = require('node:util')
+const execFile = promisify(require('node:child_process').execFile)
+
+/**
+ * @param {{
+ * args: string[]
+ * core: import('@actions/core'),
+ * quiet?: boolean,
+ * repoPath?: string,
+ * }} RunGitProps
+ */
+async function runGit({ args, repoPath, core, quiet }) {
+ if (repoPath) {
+ args = ['-C', repoPath, ...args]
+ }
+
+ if (!quiet) {
+ core.info(`About to run \`git ${args.map((s) => `'${s}'`).join(' ')}\``)
+ }
+
+ return await execFile('git', args)
+}
+
+/**
+ * Gets the SHA, subject and changed files for each commit in the given PR.
+ *
+ * Don't use GitHub API at all: the "list commits on PR" endpoint has a limit
+ * of 250 commits and doesn't return the changed files.
+ *
+ * @param {{
+ * core: import('@actions/core'),
+ * pr: Awaited<ReturnType<InstanceType<import('@actions/github/lib/utils').GitHub>["rest"]["pulls"]["get"]>>["data"]
+ * repoPath?: string,
+ * }} GetCommitMessagesForPRProps
+ *
+ * @returns {Promise<{
+ * subject: string,
+ * sha: string,
+ * changedPaths: string[],
+ * changedPathSegments: Set<string>,
+ * }[]>}
+ */
+async function getCommitDetailsForPR({ core, pr, repoPath }) {
+ await runGit({
+ args: ['fetch', `--depth=1`, 'origin', pr.base.sha],
+ repoPath,
+ core,
+ })
+ await runGit({
+ args: ['fetch', `--depth=${pr.commits + 1}`, 'origin', pr.head.sha],
+ repoPath,
+ core,
+ })
+
+ const shas = (
+ await runGit({
+ args: [
+ 'rev-list',
+ `--max-count=${pr.commits}`,
+ `${pr.base.sha}..${pr.head.sha}`,
+ ],
+ repoPath,
+ core,
+ })
+ ).stdout
+ .split('\n')
+ .map((s) => s.trim())
+ .filter(Boolean)
+
+ return Promise.all(
+ shas.map(async (sha) => {
+ // Subject first, then a blank line, then filenames.
+ const result = (
+ await runGit({
+ args: ['log', '--format=%s', '--name-only', '-1', sha],
+ repoPath,
+ core,
+ quiet: true,
+ })
+ ).stdout.split('\n')
+
+ const subject = result[0]
+
+ const changedPaths = result.slice(2, -1)
+
+ const changedPathSegments = new Set(
+ changedPaths.flatMap((path) => path.split('/')),
+ )
+
+ return {
+ sha,
+ subject,
+ changedPaths,
+ changedPathSegments,
+ }
+ }),
+ )
+}
+
+module.exports = { getCommitDetailsForPR }