diff --git a/dist/helpers/add-pr-approval-label.js b/dist/helpers/add-pr-approval-label.js index 2d8b17fa..eb1c8765 100644 --- a/dist/helpers/add-pr-approval-label.js +++ b/dist/helpers/add-pr-approval-label.js @@ -4,8 +4,8 @@ import { } from "../main-9c2herm2.js"; import { getCoreMemberLogins -} from "../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +} from "../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import { diff --git a/dist/helpers/approvals-satisfied.js b/dist/helpers/approvals-satisfied.js index 013f3262..e1cd3bbb 100644 --- a/dist/helpers/approvals-satisfied.js +++ b/dist/helpers/approvals-satisfied.js @@ -1,10 +1,10 @@ import { ApprovalsSatisfied, approvalsSatisfied -} from "../main-bbwgztca.js"; +} from "../main-w4p22k5w.js"; import"../main-5k5vz4h5.js"; -import"../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +import"../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import"../main-8h70j5cy.js"; diff --git a/dist/helpers/are-reviewers-required.js b/dist/helpers/are-reviewers-required.js index e85c7152..f028b3b6 100644 --- a/dist/helpers/are-reviewers-required.js +++ b/dist/helpers/are-reviewers-required.js @@ -1,7 +1,7 @@ import { getRequiredCodeOwnersEntries -} from "../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +} from "../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import { diff --git a/dist/helpers/assign-pr-reviewers.js b/dist/helpers/assign-pr-reviewers.js index 8b11cadd..c4203dd9 100644 --- a/dist/helpers/assign-pr-reviewers.js +++ b/dist/helpers/assign-pr-reviewers.js @@ -8,8 +8,8 @@ import { } from "../main-9c2herm2.js"; import { getCoreMemberLogins -} from "../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +} from "../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import { require_lodash } from "../main-pet5htdh.js"; diff --git a/dist/helpers/generate-path-matrix.js b/dist/helpers/generate-path-matrix.js index be07a554..b7e14b2d 100644 --- a/dist/helpers/generate-path-matrix.js +++ b/dist/helpers/generate-path-matrix.js @@ -3,7 +3,7 @@ import { } from "../main-v9jqraeg.js"; import { getChangedFilepaths -} from "../main-mycz0558.js"; +} from "../main-4w5gdxv5.js"; import { require_lodash } from "../main-pet5htdh.js"; diff --git a/dist/helpers/get-changed-files.js b/dist/helpers/get-changed-files.js index 45a262b1..6b9417b6 100644 --- a/dist/helpers/get-changed-files.js +++ b/dist/helpers/get-changed-files.js @@ -3,8 +3,9 @@ import { } from "../main-kqx5tf9g.js"; import"../main-qxfdnkb5.js"; import { - getChangedFilepaths -} from "../main-mycz0558.js"; + getChangedFilepaths, + getChangedFilepathsFromShas +} from "../main-4w5gdxv5.js"; import { HelperInputs } from "../main-8h70j5cy.js"; @@ -20,8 +21,24 @@ import"../main-wckvcay0.js"; class GetChangedFiles extends HelperInputs { } var getChangedFiles = async ({ pattern, delimiter = ",", ignore_deleted, pull_number }) => { - const pullNumber = pull_number ? Number(pull_number) : context.eventName === "merge_group" ? getPrNumberFromMergeQueueRef() : context.issue.number; - const filePaths = await getChangedFilepaths(pullNumber, Boolean(ignore_deleted)); + const ignoreDeleted = Boolean(ignore_deleted); + let filePaths; + switch (context.eventName) { + case "push": { + const { before, after } = context.payload; + filePaths = await getChangedFilepathsFromShas(before, after, ignoreDeleted); + break; + } + case "merge_group": { + const pullNumber = pull_number ? Number(pull_number) : getPrNumberFromMergeQueueRef(); + filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted); + break; + } + default: { + const pullNumber = pull_number ? Number(pull_number) : context.issue.number; + filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted); + } + } const filteredFilePaths = pattern ? filePaths.filter((fileName) => fileName.match(pattern)) : filePaths; return filteredFilePaths.join(delimiter); }; @@ -30,4 +47,4 @@ export { GetChangedFiles }; -//# debugId=F2CE773BF74E848A64756E2164756E21 +//# debugId=821E26535A99EF0864756E2164756E21 diff --git a/dist/helpers/get-changed-files.js.map b/dist/helpers/get-changed-files.js.map index ae50391f..391c1bf3 100644 --- a/dist/helpers/get-changed-files.js.map +++ b/dist/helpers/get-changed-files.js.map @@ -2,9 +2,9 @@ "version": 3, "sources": ["../src/helpers/get-changed-files.ts"], "sourcesContent": [ - "/*\nCopyright 2021 Expedia, Inc.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n https://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { HelperInputs } from '../types/generated';\nimport { context } from '@actions/github';\nimport { getChangedFilepaths } from '../utils/get-changed-filepaths';\nimport { getPrNumberFromMergeQueueRef } from '../utils/merge-queue';\n\nexport class GetChangedFiles extends HelperInputs {\n declare pattern?: string;\n declare delimiter?: string;\n declare ignore_deleted?: string;\n declare pull_number?: string;\n}\n\nexport const getChangedFiles = async ({ pattern, delimiter = ',', ignore_deleted, pull_number }: GetChangedFiles) => {\n const pullNumber = pull_number\n ? Number(pull_number)\n : context.eventName === 'merge_group'\n ? getPrNumberFromMergeQueueRef()\n : context.issue.number;\n\n const filePaths = await getChangedFilepaths(pullNumber, Boolean(ignore_deleted));\n const filteredFilePaths = pattern ? filePaths.filter(fileName => fileName.match(pattern)) : filePaths;\n\n return filteredFilePaths.join(delimiter);\n};\n" + "/*\nCopyright 2021 Expedia, Inc.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n https://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { HelperInputs } from '../types/generated';\nimport { context } from '@actions/github';\nimport { getChangedFilepaths, getChangedFilepathsFromShas } from '../utils/get-changed-filepaths';\nimport { getPrNumberFromMergeQueueRef } from '../utils/merge-queue';\n\nexport class GetChangedFiles extends HelperInputs {\n declare pattern?: string;\n declare delimiter?: string;\n declare ignore_deleted?: string;\n declare pull_number?: string;\n}\n\nexport const getChangedFiles = async ({ pattern, delimiter = ',', ignore_deleted, pull_number }: GetChangedFiles) => {\n const ignoreDeleted = Boolean(ignore_deleted);\n let filePaths: string[];\n\n switch (context.eventName) {\n case 'push': {\n const { before, after } = context.payload as { before: string; after: string };\n filePaths = await getChangedFilepathsFromShas(before, after, ignoreDeleted);\n break;\n }\n case 'merge_group': {\n const pullNumber = pull_number ? Number(pull_number) : getPrNumberFromMergeQueueRef();\n filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted);\n break;\n }\n default: {\n const pullNumber = pull_number ? Number(pull_number) : context.issue.number;\n filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted);\n }\n }\n\n const filteredFilePaths = pattern ? filePaths.filter(fileName => fileName.match(pattern)) : filePaths;\n return filteredFilePaths.join(delimiter);\n};\n" ], - "mappings": ";;;;;;;;;;;;;;;;;;;AAkBO,MAAM,wBAAwB,aAAa;AAKlD;AAEO,IAAM,kBAAkB,SAAS,SAAS,YAAY,KAAK,gBAAgB,kBAAmC;AAAA,EACnH,MAAM,aAAa,cACf,OAAO,WAAW,IAClB,QAAQ,cAAc,gBACpB,6BAA6B,IAC7B,QAAQ,MAAM;AAAA,EAEpB,MAAM,YAAY,MAAM,oBAAoB,YAAY,QAAQ,cAAc,CAAC;AAAA,EAC/E,MAAM,oBAAoB,UAAU,UAAU,OAAO,cAAY,SAAS,MAAM,OAAO,CAAC,IAAI;AAAA,EAE5F,OAAO,kBAAkB,KAAK,SAAS;AAAA;", - "debugId": "F2CE773BF74E848A64756E2164756E21", + "mappings": ";;;;;;;;;;;;;;;;;;;;AAkBO,MAAM,wBAAwB,aAAa;AAKlD;AAEO,IAAM,kBAAkB,SAAS,SAAS,YAAY,KAAK,gBAAgB,kBAAmC;AAAA,EACnH,MAAM,gBAAgB,QAAQ,cAAc;AAAA,EAC5C,IAAI;AAAA,EAEJ,QAAQ,QAAQ;AAAA,SACT,QAAQ;AAAA,MACX,QAAQ,QAAQ,UAAU,QAAQ;AAAA,MAClC,YAAY,MAAM,4BAA4B,QAAQ,OAAO,aAAa;AAAA,MAC1E;AAAA,IACF;AAAA,SACK,eAAe;AAAA,MAClB,MAAM,aAAa,cAAc,OAAO,WAAW,IAAI,6BAA6B;AAAA,MACpF,YAAY,MAAM,oBAAoB,YAAY,aAAa;AAAA,MAC/D;AAAA,IACF;AAAA,aACS;AAAA,MACP,MAAM,aAAa,cAAc,OAAO,WAAW,IAAI,QAAQ,MAAM;AAAA,MACrE,YAAY,MAAM,oBAAoB,YAAY,aAAa;AAAA,IACjE;AAAA;AAAA,EAGF,MAAM,oBAAoB,UAAU,UAAU,OAAO,cAAY,SAAS,MAAM,OAAO,CAAC,IAAI;AAAA,EAC5F,OAAO,kBAAkB,KAAK,SAAS;AAAA;", + "debugId": "821E26535A99EF0864756E2164756E21", "names": [] } \ No newline at end of file diff --git a/dist/helpers/is-user-core-member.js b/dist/helpers/is-user-core-member.js index 706034ff..0adf359e 100644 --- a/dist/helpers/is-user-core-member.js +++ b/dist/helpers/is-user-core-member.js @@ -1,7 +1,7 @@ import { getCoreMemberLogins -} from "../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +} from "../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import { diff --git a/dist/helpers/manage-merge-queue.js b/dist/helpers/manage-merge-queue.js index 84836798..a636ca91 100644 --- a/dist/helpers/manage-merge-queue.js +++ b/dist/helpers/manage-merge-queue.js @@ -3,19 +3,19 @@ import { enableAutoMerge, manageMergeQueue, removePrFromQueue -} from "../main-9q5g3xsk.js"; +} from "../main-wsarb98q.js"; import"../main-f57sjs6g.js"; import"../main-fk67p72v.js"; import"../main-3vz73ekb.js"; import"../main-zd3p3dtn.js"; -import"../main-bbwgztca.js"; +import"../main-w4p22k5w.js"; import"../main-5k5vz4h5.js"; import"../main-y5e7hxq8.js"; import"../main-bd6vw39p.js"; import"../main-dkdfy8cx.js"; import"../main-9c2herm2.js"; -import"../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +import"../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import"../main-8h70j5cy.js"; diff --git a/dist/helpers/prepare-queued-pr-for-merge.js b/dist/helpers/prepare-queued-pr-for-merge.js index ed194305..15e6ded3 100644 --- a/dist/helpers/prepare-queued-pr-for-merge.js +++ b/dist/helpers/prepare-queued-pr-for-merge.js @@ -1,19 +1,19 @@ import { prepareQueuedPrForMerge, updatePrWithDefaultBranch -} from "../main-9q5g3xsk.js"; +} from "../main-wsarb98q.js"; import"../main-f57sjs6g.js"; import"../main-fk67p72v.js"; import"../main-3vz73ekb.js"; import"../main-zd3p3dtn.js"; -import"../main-bbwgztca.js"; +import"../main-w4p22k5w.js"; import"../main-5k5vz4h5.js"; import"../main-y5e7hxq8.js"; import"../main-bd6vw39p.js"; import"../main-dkdfy8cx.js"; import"../main-9c2herm2.js"; -import"../main-fb6evf2x.js"; -import"../main-mycz0558.js"; +import"../main-ndk0jd70.js"; +import"../main-4w5gdxv5.js"; import"../main-pet5htdh.js"; import"../main-ttmzs6m5.js"; import"../main-8h70j5cy.js"; diff --git a/dist/main-4w5gdxv5.js b/dist/main-4w5gdxv5.js new file mode 100644 index 00000000..ff0b5d91 --- /dev/null +++ b/dist/main-4w5gdxv5.js @@ -0,0 +1,59 @@ +import { + octokit +} from "./main-4c5nddsb.js"; +import { + context +} from "./main-6avxv4a6.js"; + +// src/utils/get-changed-filepaths.ts +var getChangedFilepaths = async (pull_number, ignore_deleted) => { + const changedFiles = await paginateAllChangedFilepaths(pull_number); + return extractFilepaths(changedFiles, ignore_deleted); +}; +var getChangedFilepathsFromShas = async (before, after, ignore_deleted) => { + const commits = await paginateAllCommitsInRange(before, after); + const commitFiles = await Promise.all(commits.map(async ({ sha }) => { + const { data } = await octokit.repos.getCommit({ ref: sha, ...context.repo }); + return data.files ?? []; + })); + const fileMap = new Map; + for (const files of commitFiles) { + for (const file of files) { + fileMap.set(file.filename, file); + } + } + return extractFilepaths(Array.from(fileMap.values()), ignore_deleted); +}; +var extractFilepaths = (changedFiles, ignore_deleted) => { + const renamedPreviousFilenames = changedFiles.filter(({ status }) => status === "renamed").map(({ previous_filename }) => previous_filename).filter(Boolean); + const processedFilenames = (ignore_deleted ? changedFiles.filter(({ status }) => status !== "removed") : changedFiles).map(({ filename }) => filename); + return processedFilenames.concat(renamedPreviousFilenames); +}; +var paginateAllCommitsInRange = async (before, after, page = 1) => { + const response = await octokit.repos.compareCommitsWithBasehead({ + basehead: `${before}...${after}`, + per_page: 100, + page, + ...context.repo + }); + if (!response.data.commits.length) { + return []; + } + return [...response.data.commits, ...await paginateAllCommitsInRange(before, after, page + 1)]; +}; +var paginateAllChangedFilepaths = async (pull_number, page = 1) => { + const response = await octokit.pulls.listFiles({ + pull_number, + per_page: 100, + page, + ...context.repo + }); + if (!response.data.length) { + return []; + } + return response.data.concat(await paginateAllChangedFilepaths(pull_number, page + 1)); +}; + +export { getChangedFilepaths, getChangedFilepathsFromShas }; + +//# debugId=2E0A7BCC27CA034E64756E2164756E21 diff --git a/dist/main-4w5gdxv5.js.map b/dist/main-4w5gdxv5.js.map new file mode 100644 index 00000000..f81d87a7 --- /dev/null +++ b/dist/main-4w5gdxv5.js.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "sources": ["../src/utils/get-changed-filepaths.ts"], + "sourcesContent": [ + "/*\nCopyright 2021 Expedia, Inc.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n https://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ChangedFilesList } from '../types/github';\nimport { context } from '@actions/github';\nimport { octokit } from '../octokit';\n\nexport const getChangedFilepaths = async (pull_number: number, ignore_deleted?: boolean) => {\n const changedFiles = await paginateAllChangedFilepaths(pull_number);\n return extractFilepaths(changedFiles, ignore_deleted);\n};\n\nexport const getChangedFilepathsFromShas = async (before: string, after: string, ignore_deleted?: boolean) => {\n const commits = await paginateAllCommitsInRange(before, after);\n const commitFiles = await Promise.all(\n commits.map(async ({ sha }) => {\n const { data } = await octokit.repos.getCommit({ ref: sha, ...context.repo });\n return (data.files ?? []) as ChangedFilesList;\n })\n );\n const fileMap = new Map();\n for (const files of commitFiles) {\n for (const file of files) {\n fileMap.set(file.filename, file);\n }\n }\n return extractFilepaths(Array.from(fileMap.values()), ignore_deleted);\n};\n\nconst extractFilepaths = (changedFiles: ChangedFilesList, ignore_deleted?: boolean) => {\n const renamedPreviousFilenames = changedFiles\n .filter(({ status }) => status === 'renamed')\n .map(({ previous_filename }) => previous_filename)\n .filter(Boolean); // GitHub should always include previous_filename for renamed files, but just in case\n const processedFilenames = (ignore_deleted ? changedFiles.filter(({ status }) => status !== 'removed') : changedFiles).map(\n ({ filename }) => filename\n );\n return processedFilenames.concat(renamedPreviousFilenames);\n};\n\nconst paginateAllCommitsInRange = async (before: string, after: string, page = 1): Promise> => {\n const response = await octokit.repos.compareCommitsWithBasehead({\n basehead: `${before}...${after}`,\n per_page: 100,\n page,\n ...context.repo\n });\n if (!response.data.commits.length) {\n return [];\n }\n return [...response.data.commits, ...(await paginateAllCommitsInRange(before, after, page + 1))];\n};\n\nconst paginateAllChangedFilepaths = async (pull_number: number, page = 1): Promise => {\n const response = await octokit.pulls.listFiles({\n pull_number,\n per_page: 100,\n page,\n ...context.repo\n });\n if (!response.data.length) {\n return [];\n }\n return response.data.concat(await paginateAllChangedFilepaths(pull_number, page + 1));\n};\n" + ], + "mappings": ";;;;;;;;AAiBO,IAAM,sBAAsB,OAAO,aAAqB,mBAA6B;AAAA,EAC1F,MAAM,eAAe,MAAM,4BAA4B,WAAW;AAAA,EAClE,OAAO,iBAAiB,cAAc,cAAc;AAAA;AAG/C,IAAM,8BAA8B,OAAO,QAAgB,OAAe,mBAA6B;AAAA,EAC5G,MAAM,UAAU,MAAM,0BAA0B,QAAQ,KAAK;AAAA,EAC7D,MAAM,cAAc,MAAM,QAAQ,IAChC,QAAQ,IAAI,SAAS,UAAU;AAAA,IAC7B,QAAQ,SAAS,MAAM,QAAQ,MAAM,UAAU,EAAE,KAAK,QAAQ,QAAQ,KAAK,CAAC;AAAA,IAC5E,OAAQ,KAAK,SAAS,CAAC;AAAA,GACxB,CACH;AAAA,EACA,MAAM,UAAU,IAAI;AAAA,EACpB,WAAW,SAAS,aAAa;AAAA,IAC/B,WAAW,QAAQ,OAAO;AAAA,MACxB,QAAQ,IAAI,KAAK,UAAU,IAAI;AAAA,IACjC;AAAA,EACF;AAAA,EACA,OAAO,iBAAiB,MAAM,KAAK,QAAQ,OAAO,CAAC,GAAG,cAAc;AAAA;AAGtE,IAAM,mBAAmB,CAAC,cAAgC,mBAA6B;AAAA,EACrF,MAAM,2BAA2B,aAC9B,OAAO,GAAG,aAAa,WAAW,SAAS,EAC3C,IAAI,GAAG,wBAAwB,iBAAiB,EAChD,OAAO,OAAO;AAAA,EACjB,MAAM,sBAAsB,iBAAiB,aAAa,OAAO,GAAG,aAAa,WAAW,SAAS,IAAI,cAAc,IACrH,GAAG,eAAe,QACpB;AAAA,EACA,OAAO,mBAAmB,OAAO,wBAAwB;AAAA;AAG3D,IAAM,4BAA4B,OAAO,QAAgB,OAAe,OAAO,MAAuC;AAAA,EACpH,MAAM,WAAW,MAAM,QAAQ,MAAM,2BAA2B;AAAA,IAC9D,UAAU,GAAG,YAAY;AAAA,IACzB,UAAU;AAAA,IACV;AAAA,OACG,QAAQ;AAAA,EACb,CAAC;AAAA,EACD,IAAI,CAAC,SAAS,KAAK,QAAQ,QAAQ;AAAA,IACjC,OAAO,CAAC;AAAA,EACV;AAAA,EACA,OAAO,CAAC,GAAG,SAAS,KAAK,SAAS,GAAI,MAAM,0BAA0B,QAAQ,OAAO,OAAO,CAAC,CAAE;AAAA;AAGjG,IAAM,8BAA8B,OAAO,aAAqB,OAAO,MAAiC;AAAA,EACtG,MAAM,WAAW,MAAM,QAAQ,MAAM,UAAU;AAAA,IAC7C;AAAA,IACA,UAAU;AAAA,IACV;AAAA,OACG,QAAQ;AAAA,EACb,CAAC;AAAA,EACD,IAAI,CAAC,SAAS,KAAK,QAAQ;AAAA,IACzB,OAAO,CAAC;AAAA,EACV;AAAA,EACA,OAAO,SAAS,KAAK,OAAO,MAAM,4BAA4B,aAAa,OAAO,CAAC,CAAC;AAAA;", + "debugId": "2E0A7BCC27CA034E64756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/dist/main-mycz0558.js b/dist/main-mycz0558.js deleted file mode 100644 index f830172d..00000000 --- a/dist/main-mycz0558.js +++ /dev/null @@ -1,30 +0,0 @@ -import { - octokit -} from "./main-4c5nddsb.js"; -import { - context -} from "./main-6avxv4a6.js"; - -// src/utils/get-changed-filepaths.ts -var getChangedFilepaths = async (pull_number, ignore_deleted) => { - const changedFiles = await paginateAllChangedFilepaths(pull_number); - const renamedPreviousFilenames = changedFiles.filter(({ status }) => status === "renamed").map(({ previous_filename }) => previous_filename).filter(Boolean); - const processedFilenames = (ignore_deleted ? changedFiles.filter(({ status }) => status !== "removed") : changedFiles).map(({ filename }) => filename); - return processedFilenames.concat(renamedPreviousFilenames); -}; -var paginateAllChangedFilepaths = async (pull_number, page = 1) => { - const response = await octokit.pulls.listFiles({ - pull_number, - per_page: 100, - page, - ...context.repo - }); - if (!response.data.length) { - return []; - } - return response.data.concat(await paginateAllChangedFilepaths(pull_number, page + 1)); -}; - -export { getChangedFilepaths }; - -//# debugId=6D348EB52520D05064756E2164756E21 diff --git a/dist/main-mycz0558.js.map b/dist/main-mycz0558.js.map deleted file mode 100644 index b0143a31..00000000 --- a/dist/main-mycz0558.js.map +++ /dev/null @@ -1,10 +0,0 @@ -{ - "version": 3, - "sources": ["../src/utils/get-changed-filepaths.ts"], - "sourcesContent": [ - "/*\nCopyright 2021 Expedia, Inc.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n https://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { ChangedFilesList } from '../types/github';\nimport { context } from '@actions/github';\nimport { octokit } from '../octokit';\n\nexport const getChangedFilepaths = async (pull_number: number, ignore_deleted?: boolean) => {\n const changedFiles = await paginateAllChangedFilepaths(pull_number);\n const renamedPreviousFilenames = changedFiles\n .filter(({ status }) => status === 'renamed')\n .map(({ previous_filename }) => previous_filename)\n .filter(Boolean); // GitHub should always include previous_filename for renamed files, but just in case\n const processedFilenames = (ignore_deleted ? changedFiles.filter(({ status }) => status !== 'removed') : changedFiles).map(\n ({ filename }) => filename\n );\n return processedFilenames.concat(renamedPreviousFilenames);\n};\n\nconst paginateAllChangedFilepaths = async (pull_number: number, page = 1): Promise => {\n const response = await octokit.pulls.listFiles({\n pull_number,\n per_page: 100,\n page,\n ...context.repo\n });\n if (!response.data.length) {\n return [];\n }\n return response.data.concat(await paginateAllChangedFilepaths(pull_number, page + 1));\n};\n" - ], - "mappings": ";;;;;;;;AAiBO,IAAM,sBAAsB,OAAO,aAAqB,mBAA6B;AAAA,EAC1F,MAAM,eAAe,MAAM,4BAA4B,WAAW;AAAA,EAClE,MAAM,2BAA2B,aAC9B,OAAO,GAAG,aAAa,WAAW,SAAS,EAC3C,IAAI,GAAG,wBAAwB,iBAAiB,EAChD,OAAO,OAAO;AAAA,EACjB,MAAM,sBAAsB,iBAAiB,aAAa,OAAO,GAAG,aAAa,WAAW,SAAS,IAAI,cAAc,IACrH,GAAG,eAAe,QACpB;AAAA,EACA,OAAO,mBAAmB,OAAO,wBAAwB;AAAA;AAG3D,IAAM,8BAA8B,OAAO,aAAqB,OAAO,MAAiC;AAAA,EACtG,MAAM,WAAW,MAAM,QAAQ,MAAM,UAAU;AAAA,IAC7C;AAAA,IACA,UAAU;AAAA,IACV;AAAA,OACG,QAAQ;AAAA,EACb,CAAC;AAAA,EACD,IAAI,CAAC,SAAS,KAAK,QAAQ;AAAA,IACzB,OAAO,CAAC;AAAA,EACV;AAAA,EACA,OAAO,SAAS,KAAK,OAAO,MAAM,4BAA4B,aAAa,OAAO,CAAC,CAAC;AAAA;", - "debugId": "6D348EB52520D05064756E2164756E21", - "names": [] -} \ No newline at end of file diff --git a/dist/main-fb6evf2x.js b/dist/main-ndk0jd70.js similarity index 99% rename from dist/main-fb6evf2x.js rename to dist/main-ndk0jd70.js index 7225a64f..7884b11d 100644 --- a/dist/main-fb6evf2x.js +++ b/dist/main-ndk0jd70.js @@ -1,6 +1,6 @@ import { getChangedFilepaths -} from "./main-mycz0558.js"; +} from "./main-4w5gdxv5.js"; import { require_lodash } from "./main-pet5htdh.js"; diff --git a/dist/main-fb6evf2x.js.map b/dist/main-ndk0jd70.js.map similarity index 100% rename from dist/main-fb6evf2x.js.map rename to dist/main-ndk0jd70.js.map diff --git a/dist/main-bbwgztca.js b/dist/main-w4p22k5w.js similarity index 99% rename from dist/main-bbwgztca.js rename to dist/main-w4p22k5w.js index 28bfbcc4..5b618ebe 100644 --- a/dist/main-bbwgztca.js +++ b/dist/main-w4p22k5w.js @@ -4,7 +4,7 @@ import { import { getRequiredCodeOwnersEntries, paginateMembersInOrg -} from "./main-fb6evf2x.js"; +} from "./main-ndk0jd70.js"; import { require_lodash } from "./main-pet5htdh.js"; diff --git a/dist/main-bbwgztca.js.map b/dist/main-w4p22k5w.js.map similarity index 100% rename from dist/main-bbwgztca.js.map rename to dist/main-w4p22k5w.js.map diff --git a/dist/main-9q5g3xsk.js b/dist/main-wsarb98q.js similarity index 99% rename from dist/main-9q5g3xsk.js rename to dist/main-wsarb98q.js index 0855331e..6429dc5e 100644 --- a/dist/main-9q5g3xsk.js +++ b/dist/main-wsarb98q.js @@ -12,7 +12,7 @@ import { } from "./main-zd3p3dtn.js"; import { approvalsSatisfied -} from "./main-bbwgztca.js"; +} from "./main-w4p22k5w.js"; import { createPrComment } from "./main-5k5vz4h5.js"; diff --git a/dist/main-9q5g3xsk.js.map b/dist/main-wsarb98q.js.map similarity index 100% rename from dist/main-9q5g3xsk.js.map rename to dist/main-wsarb98q.js.map diff --git a/src/helpers/get-changed-files.ts b/src/helpers/get-changed-files.ts index 7ff1209a..85fae7a1 100644 --- a/src/helpers/get-changed-files.ts +++ b/src/helpers/get-changed-files.ts @@ -13,7 +13,7 @@ limitations under the License. import { HelperInputs } from '../types/generated'; import { context } from '@actions/github'; -import { getChangedFilepaths } from '../utils/get-changed-filepaths'; +import { getChangedFilepaths, getChangedFilepathsFromShas } from '../utils/get-changed-filepaths'; import { getPrNumberFromMergeQueueRef } from '../utils/merge-queue'; export class GetChangedFiles extends HelperInputs { @@ -24,14 +24,26 @@ export class GetChangedFiles extends HelperInputs { } export const getChangedFiles = async ({ pattern, delimiter = ',', ignore_deleted, pull_number }: GetChangedFiles) => { - const pullNumber = pull_number - ? Number(pull_number) - : context.eventName === 'merge_group' - ? getPrNumberFromMergeQueueRef() - : context.issue.number; + const ignoreDeleted = Boolean(ignore_deleted); + let filePaths: string[]; - const filePaths = await getChangedFilepaths(pullNumber, Boolean(ignore_deleted)); - const filteredFilePaths = pattern ? filePaths.filter(fileName => fileName.match(pattern)) : filePaths; + switch (context.eventName) { + case 'push': { + const { before, after } = context.payload as { before: string; after: string }; + filePaths = await getChangedFilepathsFromShas(before, after, ignoreDeleted); + break; + } + case 'merge_group': { + const pullNumber = pull_number ? Number(pull_number) : getPrNumberFromMergeQueueRef(); + filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted); + break; + } + default: { + const pullNumber = pull_number ? Number(pull_number) : context.issue.number; + filePaths = await getChangedFilepaths(pullNumber, ignoreDeleted); + } + } + const filteredFilePaths = pattern ? filePaths.filter(fileName => fileName.match(pattern)) : filePaths; return filteredFilePaths.join(delimiter); }; diff --git a/src/utils/get-changed-filepaths.ts b/src/utils/get-changed-filepaths.ts index 33ad4642..701f3695 100644 --- a/src/utils/get-changed-filepaths.ts +++ b/src/utils/get-changed-filepaths.ts @@ -17,6 +17,27 @@ import { octokit } from '../octokit'; export const getChangedFilepaths = async (pull_number: number, ignore_deleted?: boolean) => { const changedFiles = await paginateAllChangedFilepaths(pull_number); + return extractFilepaths(changedFiles, ignore_deleted); +}; + +export const getChangedFilepathsFromShas = async (before: string, after: string, ignore_deleted?: boolean) => { + const commits = await paginateAllCommitsInRange(before, after); + const commitFiles = await Promise.all( + commits.map(async ({ sha }) => { + const { data } = await octokit.repos.getCommit({ ref: sha, ...context.repo }); + return (data.files ?? []) as ChangedFilesList; + }) + ); + const fileMap = new Map(); + for (const files of commitFiles) { + for (const file of files) { + fileMap.set(file.filename, file); + } + } + return extractFilepaths(Array.from(fileMap.values()), ignore_deleted); +}; + +const extractFilepaths = (changedFiles: ChangedFilesList, ignore_deleted?: boolean) => { const renamedPreviousFilenames = changedFiles .filter(({ status }) => status === 'renamed') .map(({ previous_filename }) => previous_filename) @@ -27,6 +48,19 @@ export const getChangedFilepaths = async (pull_number: number, ignore_deleted?: return processedFilenames.concat(renamedPreviousFilenames); }; +const paginateAllCommitsInRange = async (before: string, after: string, page = 1): Promise> => { + const response = await octokit.repos.compareCommitsWithBasehead({ + basehead: `${before}...${after}`, + per_page: 100, + page, + ...context.repo + }); + if (!response.data.commits.length) { + return []; + } + return [...response.data.commits, ...(await paginateAllCommitsInRange(before, after, page + 1))]; +}; + const paginateAllChangedFilepaths = async (pull_number: number, page = 1): Promise => { const response = await octokit.pulls.listFiles({ pull_number, diff --git a/test/helpers/get-changed-files.test.ts b/test/helpers/get-changed-files.test.ts index 56857520..e7a5a497 100644 --- a/test/helpers/get-changed-files.test.ts +++ b/test/helpers/get-changed-files.test.ts @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { describe, it, expect, Mock } from 'bun:test'; +import { describe, it, expect, Mock, beforeEach } from 'bun:test'; import { setupMocks } from '../setup'; setupMocks(); @@ -181,3 +181,127 @@ describe('getChangedFiles', () => { expect(result).toEqual(mock_data2[0].filename); }); }); + +describe('getChangedFiles (push event)', () => { + const COMMIT_1 = { sha: 'commit-sha-aaa' }; + const COMMIT_2 = { sha: 'commit-sha-bbb' }; + + const push_file_added = { + sha: 'sha1', + filename: 'src/feature/added.ts', + status: 'added', + additions: 10, + deletions: 0, + changes: 10, + blob_url: '', + raw_url: '', + contents_url: '' + }; + const push_file_modified = { + sha: 'sha2', + filename: 'src/feature/modified.ts', + status: 'modified', + additions: 5, + deletions: 2, + changes: 7, + blob_url: '', + raw_url: '', + contents_url: '' + }; + const push_file_removed = { + sha: 'sha3', + filename: 'src/old/removed.ts', + status: 'removed', + additions: 0, + deletions: 20, + changes: 20, + blob_url: '', + raw_url: '', + contents_url: '' + }; + + beforeEach(() => { + context.eventName = 'push'; + context.payload = { before: 'before-sha', after: 'after-sha' }; + }); + + it('returns files changed in a single commit', async () => { + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async () => ({ + data: { files: [push_file_added, push_file_modified] } + })); + + const result = await getChangedFiles({}); + + expect(result).toEqual([push_file_added.filename, push_file_modified.filename].join(',')); + }); + + it('aggregates files from multiple commits', async () => { + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1, COMMIT_2] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async ({ ref }: { ref: string }) => ({ + data: { files: ref === COMMIT_1.sha ? [push_file_added] : [push_file_modified] } + })); + + const result = await getChangedFiles({}); + + expect(result).toEqual([push_file_added.filename, push_file_modified.filename].join(',')); + }); + + it('paginates through commits across multiple pages', async () => { + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1] : page === 2 ? [COMMIT_2] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async ({ ref }: { ref: string }) => ({ + data: { files: ref === COMMIT_1.sha ? [push_file_added] : [push_file_modified] } + })); + + const result = await getChangedFiles({}); + + expect(result).toEqual([push_file_added.filename, push_file_modified.filename].join(',')); + }); + + it('excludes removed files when ignore_deleted is set', async () => { + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async () => ({ + data: { files: [push_file_added, push_file_removed] } + })); + + const result = await getChangedFiles({ ignore_deleted: 'true' }); + + expect(result).toEqual(push_file_added.filename); + }); + + it('filters files by pattern', async () => { + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async () => ({ + data: { files: [push_file_added, push_file_modified] } + })); + + const result = await getChangedFiles({ pattern: 'added' }); + + expect(result).toEqual(push_file_added.filename); + }); + + it('deduplicates files across commits, keeping the last seen status', async () => { + const push_file_later_removed = { ...push_file_added, status: 'removed' }; + (octokit.repos.compareCommitsWithBasehead as unknown as Mock).mockImplementation(async ({ page }: { page: number }) => ({ + data: { commits: page === 1 ? [COMMIT_1, COMMIT_2] : [] } + })); + (octokit.repos.getCommit as unknown as Mock).mockImplementation(async ({ ref }: { ref: string }) => ({ + data: { files: ref === COMMIT_1.sha ? [push_file_added] : [push_file_later_removed] } + })); + + // file was added in commit 1 then removed in commit 2 — net status is removed, so excluded + const result = await getChangedFiles({ ignore_deleted: 'true' }); + + expect(result).toEqual(''); + }); +}); diff --git a/test/setup.ts b/test/setup.ts index 40709798..fc1650bb 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -59,7 +59,8 @@ export const createMockOctokit = () => { update: mock(() => ({ data: {} })) }, repos: { - compareCommitsWithBasehead: mock(() => ({ data: {} })), + compareCommitsWithBasehead: mock(() => ({ data: { commits: [], files: [] } })), + getCommit: mock(() => ({ data: { files: [] } })), createCommitStatus: mock(() => ({ data: {} })), createDeployment: mock(() => ({ data: {} })), createDeploymentStatus: mock(() => ({ data: {} })),