diff --git a/dist/helpers/add-pr-approval-label.js b/dist/helpers/add-pr-approval-label.js index 2d8b17fa9..eb1c87659 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 013f32624..e1cd3bbbc 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 e85c7152e..f028b3b6d 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 8b11caddb..c4203dd97 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 be07a5542..b7e14b2dc 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 45a262b18..6b9417b66 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 ae50391f6..391c1bf38 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 706034ffc..0adf359e8 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 848367980..a636ca910 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 ed1943051..15e6ded3c 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 000000000..ff0b5d91d --- /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 000000000..f81d87a70 --- /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 f830172dc..000000000 --- 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 b0143a314..000000000 --- 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 7225a64fe..7884b11d0 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 28bfbcc4f..5b618ebe1 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 0855331e1..6429dc5ef 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 7ff1209ae..85fae7a1b 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 33ad4642c..701f36954 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 568575204..e7a5a4974 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 407097984..fc1650bba 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: {} })),