From e052d30e1c0bdf27cd806b01ca3b393f47b50c62 Mon Sep 17 00:00:00 2001 From: Tonye Jack Date: Wed, 17 Apr 2024 10:24:26 -0600 Subject: [PATCH] feat: add option to exclude submodules when detecting changes (#2047) Co-authored-by: GitHub Action --- .github/workflows/test.yml | 21 +++ action.yml | 4 + dist/index.js | Bin 2208750 -> 2209079 bytes dist/index.js.map | Bin 2587506 -> 2587901 bytes package.json | 1 + .../__snapshots__/inputs.test.ts.snap | 138 ++++++++++-------- src/__tests__/inputs.test.ts | 4 +- src/__tests__/utils.test.ts | 3 +- src/changedFiles.ts | 12 +- src/commitSha.ts | 16 +- src/constant.ts | 3 +- src/inputs.ts | 6 + src/main.ts | 22 ++- src/utils.ts | 6 +- 14 files changed, 143 insertions(+), 93 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a8b44fc..d2f7e8a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -682,6 +682,27 @@ jobs: echo "${{ toJSON(steps.changed-files.outputs) }}" shell: bash + + - name: Run changed-files excluding submodule + id: changed-files-exclude-submodule + uses: ./ + with: + base_sha: "85bd869" + sha: "adde7bb" + fetch_depth: 60000 + exclude_submodules: true + + - name: Verify no added files + if: steps.changed-files-exclude-submodule.outputs.added_files != '' + run: | + echo "Expected: ('') got ${{ steps.changed-files-exclude-submodule.outputs.added_files }}" + exit 1 + + - name: Show output + run: | + echo "${{ toJSON(steps.changed-files-exclude-submodule.outputs) }}" + shell: + bash test-yaml: name: Test changed-files with yaml runs-on: ubuntu-latest diff --git a/action.yml b/action.yml index b3fb919f..50b7d351 100644 --- a/action.yml +++ b/action.yml @@ -223,6 +223,10 @@ inputs: description: "Output changed files in a format that can be used for matrix jobs. Alias for setting inputs `json` to `true` and `escape_json` to `false`." required: false default: "false" + exclude_submodules: + description: "Exclude changes to submodules." + required: false + default: "false" outputs: added_files: diff --git a/dist/index.js b/dist/index.js index 7194c61448c72746cadb3bd1b3908cd07a29bacc..f628f953cd28fafb11899809fa26a46127effe0c 100644 GIT binary patch delta 726 zcmZwEKWGzC7yxj-TykkIX`3d!M=keXvmlY806?nR# zd5h&zi8r+=a8CH@KB)L^S2V!Y(P+Sl*-dSn&y7F)PsY5&&569_HfhwO{!WuPvQr*~ zH`e9>n;)bxH>J>e47j@Pk@35pl(}#HMZ_J^s3-a7joba*dYeu5;qrr&&#tc>vX>uu z?R)R{*}0Eto_Z5^pTY~RW}4{=qtCc}*0hSooVBpHRJ2T^dW4nEm{mi$g4ch7%EMdF z(}TT9_*;QQcsq8w+Ns3G03>j~A0pyy7%q52y=A5$CSwpBikn7_{oP(?CYy0*;++i4 zs^!W>t5(hR79%?VBlv9^?4_aLP3 znhr8rhvB9j3@PH%6ePMGV)!c$nxMSn&)f-DH{pic;+E6~;vo|85+9L?pY)M_qL2Uy nk^wSEhDeAElQ4;p5u%bPi4l#&$tW2k39^GENlHj<_ORj^(d)ErK({Oi^W2i4H7I8QiQ=G5d(=ydd0OghDv=5 zTHbJD=zv7iP7))7K{U~*O~mBim->j|m)w(c|L5E*UN)$Z+n{91rJtExQZHRSq??)K zXFKHJ(WqilooE@3kip*~B?JSXQWlHRUT^tYb z?Ok$mP5h`7e6YD;ec_By!^)qYo zsGh=Yo0zcCtR$YCL{;+ie0XVD!Gn0xOQUS;MB+v-_5J+k)kjtl>Y(7yKg6n!rgX&x zd@(>a@!m-*+CHu1C_UWorxuavq64iVaPL|Fn+S*K?oXmWL=Ai|Ko-6hA}d?yk@(vH znOS#@Bo2G2{=AqJH#u6@W^4}U33Q+b3Ch3#G0s00gCK{Z&R25e9Zc5r|b VTu=vYsD}n#iF{V-#+M)|yM1)GsrUud^m_)=& z4j!s_ks5dx3l+p1q>%VEQ4!jU;7Jt0gSJg8c+yKn!9&64PE_o|4|Zn$@6F8a#*aB+ z^XHsUyX}GIUC{=IUQ12LFGv>fxTW5@wns8XtTrYMh;{9ycq^i`3o(egq}7L!aK>KO zDxwj&T8+(AV*(P9iB)6L=M5>DPNmq*J~Alq*XR(rVPdDF#B4Su0M~--T8!NL7ie7J z*)NaDVVS4ytPn3Oek2}PULgUPe^0^?StUV8ERzZhEs}9aJfbd8-pUd$E;q>o0kr1< zD_mM9pWvL2npt^?40rO5*xbw3-jNq=JdZnkXdMAdhlAaHXR|6k`sMSPQc^!vnw-uh zOBtOt2>sq;-#T3Y#ZTR~*7QVy$6?+__p^n)bXHQfRf+S)Fo7u3|n+_YM}pc_p?ur?U-@e9Y} zRD=8L)WV1OBf4N}gxc9R+>75FjLBEBY-L)4PKrEva)cgaUysm<*5|>onJ=+3$LOZ% zZ^{KmX?c{sY4yXX3*w{HZL9#UI6&(s66Bh+18T>q#GZ~*{fW_n`Au?#cbjQY8JSTV zYDX5-fvjj7vLOZ8(RS2{9LR~fP&aZRH}aqzXeZi*yvT=CSYZYdRF`e Du~!;> delta 607 zcmZwCKTK0`5C`zQzIXRtDFyjgwT1E!Di|De(%P6>ieW**$YzWSVNeueq7Dv58H~n% z;TD^)II*;%Tr?r6lY@(iaZt3hn7B1*7)Tt5e)-jg#4vo4_kMTx&E3xLoVB%`v+^&Z zlD{7a$>wWkL-G|nw6YjWIp)opC|vti|9tlH>(t8Q!EAeBax`Gt?v|1ZrKAM`u(gzQ zer?&)m*ymwq=Z(FQK){V%i@G$Yt=-E5&4&Lq@lt`6w!VSei9u@k)A61;r%%G|uads;2clafwzsKTO$-wV{MW85jV3+zbsJo|cmlrR1}woy { }) test('should return default values when no inputs are provided', () => { - ;(core.getBooleanInput as jest.Mock).mockImplementation(name => { + ;(core.getInput as jest.Mock).mockImplementation(name => { const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => { return g[1].toUpperCase() }) as keyof Inputs @@ -30,7 +30,7 @@ describe('getInputs', () => { }) test('should correctly parse boolean inputs', () => { - ;(core.getBooleanInput as jest.Mock).mockImplementation(name => { + ;(core.getInput as jest.Mock).mockImplementation(name => { const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => { return g[1].toUpperCase() }) as keyof Inputs diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index 84f7297d..476bde7d 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -635,7 +635,8 @@ describe('utils test', () => { failOnInitialDiffError: false, failOnSubmoduleDiffError: false, negationPatternsFirst: false, - useRestApi: false + useRestApi: false, + excludeSubmodules: false } const coreWarningSpy = jest.spyOn(core, 'warning') diff --git a/src/changedFiles.ts b/src/changedFiles.ts index 12f07deb..0635d957 100644 --- a/src/changedFiles.ts +++ b/src/changedFiles.ts @@ -121,13 +121,13 @@ export const processChangedFiles = async ({ export const getRenamedFiles = async ({ inputs, workingDirectory, - hasSubmodule, + diffSubmodule, diffResult, submodulePaths }: { inputs: Inputs workingDirectory: string - hasSubmodule: boolean + diffSubmodule: boolean diffResult: DiffResult submodulePaths: string[] }): Promise<{paths: string; count: string}> => { @@ -139,7 +139,7 @@ export const getRenamedFiles = async ({ oldNewSeparator: inputs.oldNewSeparator }) - if (hasSubmodule) { + if (diffSubmodule) { for (const submodulePath of submodulePaths) { const submoduleShaResult = await gitSubmoduleDiffSHA({ cwd: workingDirectory, @@ -217,7 +217,7 @@ export type ChangedFiles = { export const getAllDiffFiles = async ({ workingDirectory, - hasSubmodule, + diffSubmodule, diffResult, submodulePaths, outputRenamedFilesAsDeletedAndAdded, @@ -226,7 +226,7 @@ export const getAllDiffFiles = async ({ failOnSubmoduleDiffError }: { workingDirectory: string - hasSubmodule: boolean + diffSubmodule: boolean diffResult: DiffResult submodulePaths: string[] outputRenamedFilesAsDeletedAndAdded: boolean @@ -243,7 +243,7 @@ export const getAllDiffFiles = async ({ failOnInitialDiffError }) - if (hasSubmodule) { + if (diffSubmodule) { for (const submodulePath of submodulePaths) { const submoduleShaResult = await gitSubmoduleDiffSHA({ cwd: workingDirectory, diff --git a/src/commitSha.ts b/src/commitSha.ts index e3e23c2c..fd9dd98b 100644 --- a/src/commitSha.ts +++ b/src/commitSha.ts @@ -91,7 +91,7 @@ interface SHAForNonPullRequestEvent { env: Env workingDirectory: string isShallow: boolean - hasSubmodule: boolean + diffSubmodule: boolean gitFetchExtraArgs: string[] isTag: boolean remoteName: string @@ -102,7 +102,7 @@ export const getSHAForNonPullRequestEvent = async ({ env, workingDirectory, isShallow, - hasSubmodule, + diffSubmodule, gitFetchExtraArgs, isTag, remoteName @@ -152,7 +152,7 @@ export const getSHAForNonPullRequestEvent = async ({ }) } - if (hasSubmodule) { + if (diffSubmodule) { await gitFetchSubmodules({ cwd: workingDirectory, args: [ @@ -164,7 +164,7 @@ export const getSHAForNonPullRequestEvent = async ({ }) } } else { - if (hasSubmodule && inputs.fetchAdditionalSubmoduleHistory) { + if (diffSubmodule && inputs.fetchAdditionalSubmoduleHistory) { await gitFetchSubmodules({ cwd: workingDirectory, args: [ @@ -323,7 +323,7 @@ interface SHAForPullRequestEvent { inputs: Inputs workingDirectory: string isShallow: boolean - hasSubmodule: boolean + diffSubmodule: boolean gitFetchExtraArgs: string[] remoteName: string } @@ -332,7 +332,7 @@ export const getSHAForPullRequestEvent = async ({ inputs, workingDirectory, isShallow, - hasSubmodule, + diffSubmodule, gitFetchExtraArgs, remoteName }: SHAForPullRequestEvent): Promise => { @@ -390,7 +390,7 @@ export const getSHAForPullRequestEvent = async ({ ] }) - if (hasSubmodule) { + if (diffSubmodule) { await gitFetchSubmodules({ cwd: workingDirectory, args: [ @@ -403,7 +403,7 @@ export const getSHAForPullRequestEvent = async ({ } } } else { - if (hasSubmodule && inputs.fetchAdditionalSubmoduleHistory) { + if (diffSubmodule && inputs.fetchAdditionalSubmoduleHistory) { await gitFetchSubmodules({ cwd: workingDirectory, args: [ diff --git a/src/constant.ts b/src/constant.ts index 51ab7fe1..8063ba6f 100644 --- a/src/constant.ts +++ b/src/constant.ts @@ -20,5 +20,6 @@ export const DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS: Partial = { oldNewFilesSeparator: ' ', skipInitialFetch: false, fetchAdditionalSubmoduleHistory: false, - dirNamesDeletedFilesIncludeOnlyDeletedDirs: false + dirNamesDeletedFilesIncludeOnlyDeletedDirs: false, + excludeSubmodules: false } diff --git a/src/inputs.ts b/src/inputs.ts index 1c5edef4..ee96a4e9 100644 --- a/src/inputs.ts +++ b/src/inputs.ts @@ -54,6 +54,7 @@ export type Inputs = { failOnSubmoduleDiffError: boolean negationPatternsFirst: boolean useRestApi: boolean + excludeSubmodules: boolean } export const getInputs = (): Inputs => { @@ -240,6 +241,10 @@ export const getInputs = (): Inputs => { required: false }) + const excludeSubmodules = core.getBooleanInput('exclude_submodules', { + required: false + }) + const inputs: Inputs = { files, filesSeparator, @@ -279,6 +284,7 @@ export const getInputs = (): Inputs => { skipInitialFetch, fetchAdditionalSubmoduleHistory, dirNamesDeletedFilesIncludeOnlyDeletedDirs, + excludeSubmodules, // End Not Supported via REST API dirNames, dirNamesExcludeCurrentDir, diff --git a/src/main.ts b/src/main.ts index 4159b4f1..d2f4148e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -64,10 +64,16 @@ const getChangedFilesFromLocalGitHistory = async ({ } const isShallow = await isRepoShallow({cwd: workingDirectory}) - const hasSubmodule = await submoduleExists({cwd: workingDirectory}) + let diffSubmodule = false let gitFetchExtraArgs = ['--no-tags', '--prune'] - if (hasSubmodule) { + if (inputs.excludeSubmodules) { + core.info('Excluding submodules from the diff') + } else { + diffSubmodule = await submoduleExists({cwd: workingDirectory}) + } + + if (diffSubmodule) { gitFetchExtraArgs.push('--recurse-submodules') } @@ -77,7 +83,7 @@ const getChangedFilesFromLocalGitHistory = async ({ inputs.outputRenamedFilesAsDeletedAndAdded let submodulePaths: string[] = [] - if (hasSubmodule) { + if (diffSubmodule) { submodulePaths = await getSubmodulePath({cwd: workingDirectory}) } @@ -94,7 +100,7 @@ const getChangedFilesFromLocalGitHistory = async ({ env, workingDirectory, isShallow, - hasSubmodule, + diffSubmodule, gitFetchExtraArgs, isTag, remoteName @@ -109,7 +115,7 @@ const getChangedFilesFromLocalGitHistory = async ({ inputs, workingDirectory, isShallow, - hasSubmodule, + diffSubmodule, gitFetchExtraArgs, remoteName }) @@ -127,7 +133,7 @@ const getChangedFilesFromLocalGitHistory = async ({ const allDiffFiles = await getAllDiffFiles({ workingDirectory, - hasSubmodule, + diffSubmodule, diffResult, submodulePaths, outputRenamedFilesAsDeletedAndAdded, @@ -153,7 +159,7 @@ const getChangedFilesFromLocalGitHistory = async ({ deletedFiles: allDiffFiles[ChangeTypeEnum.Deleted], recoverPatterns, diffResult, - hasSubmodule, + diffSubmodule, submodulePaths }) } @@ -171,7 +177,7 @@ const getChangedFilesFromLocalGitHistory = async ({ const allOldNewRenamedFiles = await getRenamedFiles({ inputs, workingDirectory, - hasSubmodule, + diffSubmodule, diffResult, submodulePaths }) diff --git a/src/utils.ts b/src/utils.ts index a73efaf1..0349954a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1413,7 +1413,7 @@ export const recoverDeletedFiles = async ({ deletedFiles, recoverPatterns, diffResult, - hasSubmodule, + diffSubmodule, submodulePaths }: { inputs: Inputs @@ -1421,7 +1421,7 @@ export const recoverDeletedFiles = async ({ deletedFiles: string[] recoverPatterns: string[] diffResult: DiffResult - hasSubmodule: boolean + diffSubmodule: boolean submodulePaths: string[] }): Promise => { let recoverableDeletedFiles = deletedFiles @@ -1451,7 +1451,7 @@ export const recoverDeletedFiles = async ({ const submodulePath = submodulePaths.find(p => deletedFile.startsWith(p)) - if (hasSubmodule && submodulePath) { + if (diffSubmodule && submodulePath) { const submoduleShaResult = await gitSubmoduleDiffSHA({ cwd: workingDirectory, parentSha1: diffResult.previousSha,