From 7739b9ba2efcda9dde65ad1e3c2dbe65b41dfba7 Mon Sep 17 00:00:00 2001 From: Robert Wieczoreck <1175008+RobertWieczoreck@users.noreply.github.com> Date: Wed, 16 Aug 2023 22:34:54 +0200 Subject: [PATCH] Add option to fetch tags even if fetch-depth > 0 (#579) * Add option to fetch tags even if fetch-depth > 0 * Add jest tests for fetchDepth and fetchTags options --- README.md | 4 + __test__/git-auth-helper.test.ts | 1 + __test__/git-command-manager.test.ts | 176 +++++++++++++++++++++++++++ __test__/input-helper.test.ts | 1 + action.yml | 3 + dist/index.js | 11 +- src/git-command-manager.ts | 9 +- src/git-source-provider.ts | 7 +- src/git-source-settings.ts | 5 + src/input-helper.ts | 5 + 10 files changed, 214 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5427a50..9df4ae0 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,10 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl # Default: 1 fetch-depth: '' + # Whether to fetch tags, even if fetch-depth > 0. + # Default: false + fetch-tags: '' + # Whether to download Git-LFS files # Default: false lfs: '' diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts index fec6573..8e580c1 100644 --- a/__test__/git-auth-helper.test.ts +++ b/__test__/git-auth-helper.test.ts @@ -805,6 +805,7 @@ async function setup(testName: string): Promise { sparseCheckout: [], sparseCheckoutConeMode: true, fetchDepth: 1, + fetchTags: false, lfs: false, submodules: false, nestedSubmodules: false, diff --git a/__test__/git-command-manager.test.ts b/__test__/git-command-manager.test.ts index 1c31ef9..16c348f 100644 --- a/__test__/git-command-manager.test.ts +++ b/__test__/git-command-manager.test.ts @@ -88,3 +88,179 @@ describe('git-auth-helper tests', () => { expect(branches.sort()).toEqual(['foo'].sort()) }) }) + +describe('Test fetchDepth and fetchTags options', () => { + beforeEach(async () => { + jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn()) + jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn()) + mockExec.mockImplementation((path, args, options) => { + console.log(args, options.listeners.stdout) + + if (args.includes('version')) { + options.listeners.stdout(Buffer.from('2.18')) + } + + return 0 + }) + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + + it('should call execGit with the correct arguments when fetchDepth is 0 and fetchTags is true', async () => { + jest.spyOn(exec, 'exec').mockImplementation(mockExec) + const workingDirectory = 'test' + const lfs = false + const doSparseCheckout = false + git = await commandManager.createCommandManager( + workingDirectory, + lfs, + doSparseCheckout + ) + + const refSpec = ['refspec1', 'refspec2'] + const options = { + filter: 'filterValue', + fetchDepth: 0, + fetchTags: true + } + + await git.fetch(refSpec, options) + + expect(mockExec).toHaveBeenCalledWith( + expect.any(String), + [ + '-c', + 'protocol.version=2', + 'fetch', + '--prune', + '--progress', + '--no-recurse-submodules', + '--filter=filterValue', + 'origin', + 'refspec1', + 'refspec2' + ], + expect.any(Object) + ) + }) + + it('should call execGit with the correct arguments when fetchDepth is 0 and fetchTags is false', async () => { + jest.spyOn(exec, 'exec').mockImplementation(mockExec) + + const workingDirectory = 'test' + const lfs = false + const doSparseCheckout = false + git = await commandManager.createCommandManager( + workingDirectory, + lfs, + doSparseCheckout + ) + const refSpec = ['refspec1', 'refspec2'] + const options = { + filter: 'filterValue', + fetchDepth: 0, + fetchTags: false + } + + await git.fetch(refSpec, options) + + expect(mockExec).toHaveBeenCalledWith( + expect.any(String), + [ + '-c', + 'protocol.version=2', + 'fetch', + '--no-tags', + '--prune', + '--progress', + '--no-recurse-submodules', + '--filter=filterValue', + 'origin', + 'refspec1', + 'refspec2' + ], + expect.any(Object) + ) + }) + + it('should call execGit with the correct arguments when fetchDepth is 1 and fetchTags is false', async () => { + jest.spyOn(exec, 'exec').mockImplementation(mockExec) + + const workingDirectory = 'test' + const lfs = false + const doSparseCheckout = false + git = await commandManager.createCommandManager( + workingDirectory, + lfs, + doSparseCheckout + ) + const refSpec = ['refspec1', 'refspec2'] + const options = { + filter: 'filterValue', + fetchDepth: 1, + fetchTags: false + } + + await git.fetch(refSpec, options) + + expect(mockExec).toHaveBeenCalledWith( + expect.any(String), + [ + '-c', + 'protocol.version=2', + 'fetch', + '--no-tags', + '--prune', + '--progress', + '--no-recurse-submodules', + '--filter=filterValue', + '--depth=1', + 'origin', + 'refspec1', + 'refspec2' + ], + expect.any(Object) + ) + }) + + it('should call execGit with the correct arguments when fetchDepth is 1 and fetchTags is true', async () => { + jest.spyOn(exec, 'exec').mockImplementation(mockExec) + + const workingDirectory = 'test' + const lfs = false + const doSparseCheckout = false + git = await commandManager.createCommandManager( + workingDirectory, + lfs, + doSparseCheckout + ) + const refSpec = ['refspec1', 'refspec2'] + const options = { + filter: 'filterValue', + fetchDepth: 1, + fetchTags: true + } + + await git.fetch(refSpec, options) + + expect(mockExec).toHaveBeenCalledWith( + expect.any(String), + [ + '-c', + 'protocol.version=2', + 'fetch', + '--prune', + '--progress', + '--no-recurse-submodules', + '--filter=filterValue', + '--depth=1', + 'origin', + 'refspec1', + 'refspec2' + ], + expect.any(Object) + ) + }) +}) diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts index 069fda4..aa58415 100644 --- a/__test__/input-helper.test.ts +++ b/__test__/input-helper.test.ts @@ -82,6 +82,7 @@ describe('input-helper tests', () => { expect(settings.sparseCheckout).toBe(undefined) expect(settings.sparseCheckoutConeMode).toBe(true) expect(settings.fetchDepth).toBe(1) + expect(settings.fetchTags).toBe(false) expect(settings.lfs).toBe(false) expect(settings.ref).toBe('refs/heads/some-ref') expect(settings.repositoryName).toBe('some-repo') diff --git a/action.yml b/action.yml index e562b56..58f07d7 100644 --- a/action.yml +++ b/action.yml @@ -65,6 +65,9 @@ inputs: fetch-depth: description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' default: 1 + fetch-tags: + description: 'Whether to fetch tags, even if fetch-depth > 0.' + default: false lfs: description: 'Whether to download Git-LFS files' default: false diff --git a/dist/index.js b/dist/index.js index 4556295..9e38490 100644 --- a/dist/index.js +++ b/dist/index.js @@ -637,7 +637,7 @@ class GitCommandManager { fetch(refSpec, options) { return __awaiter(this, void 0, void 0, function* () { const args = ['-c', 'protocol.version=2', 'fetch']; - if (!refSpec.some(x => x === refHelper.tagsRefSpec)) { + if (!refSpec.some(x => x === refHelper.tagsRefSpec) && !options.fetchTags) { args.push('--no-tags'); } args.push('--prune', '--progress', '--no-recurse-submodules'); @@ -718,8 +718,8 @@ class GitCommandManager { } log1(format) { return __awaiter(this, void 0, void 0, function* () { - var args = format ? ['log', '-1', format] : ['log', '-1']; - var silent = format ? false : true; + const args = format ? ['log', '-1', format] : ['log', '-1']; + const silent = format ? false : true; const output = yield this.execGit(args, false, silent); return output.stdout; }); @@ -1256,6 +1256,7 @@ function getSource(settings) { } else { fetchOptions.fetchDepth = settings.fetchDepth; + fetchOptions.fetchTags = settings.fetchTags; const refSpec = refHelper.getRefSpec(settings.ref, settings.commit); yield git.fetch(refSpec, fetchOptions); } @@ -1734,6 +1735,10 @@ function getInputs() { result.fetchDepth = 0; } core.debug(`fetch depth = ${result.fetchDepth}`); + // Fetch tags + result.fetchTags = + (core.getInput('fetch-tags') || 'false').toUpperCase() === 'TRUE'; + core.debug(`fetch tags = ${result.fetchTags}`); // LFS result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE'; core.debug(`lfs = ${result.lfs}`); diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index e684dba..6ab807b 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -33,6 +33,7 @@ export interface IGitCommandManager { options: { filter?: string fetchDepth?: number + fetchTags?: boolean } ): Promise getDefaultBranch(repositoryUrl: string): Promise @@ -240,10 +241,10 @@ class GitCommandManager { async fetch( refSpec: string[], - options: {filter?: string; fetchDepth?: number} + options: {filter?: string; fetchDepth?: number; fetchTags?: boolean} ): Promise { const args = ['-c', 'protocol.version=2', 'fetch'] - if (!refSpec.some(x => x === refHelper.tagsRefSpec)) { + if (!refSpec.some(x => x === refHelper.tagsRefSpec) && !options.fetchTags) { args.push('--no-tags') } @@ -333,8 +334,8 @@ class GitCommandManager { } async log1(format?: string): Promise { - var args = format ? ['log', '-1', format] : ['log', '-1'] - var silent = format ? false : true + const args = format ? ['log', '-1', format] : ['log', '-1'] + const silent = format ? false : true const output = await this.execGit(args, false, silent) return output.stdout } diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts index 8f9d63f..042563e 100644 --- a/src/git-source-provider.ts +++ b/src/git-source-provider.ts @@ -153,7 +153,11 @@ export async function getSource(settings: IGitSourceSettings): Promise { // Fetch core.startGroup('Fetching the repository') - const fetchOptions: {filter?: string; fetchDepth?: number} = {} + const fetchOptions: { + filter?: string + fetchDepth?: number + fetchTags?: boolean + } = {} if (settings.sparseCheckout) fetchOptions.filter = 'blob:none' if (settings.fetchDepth <= 0) { // Fetch all branches and tags @@ -171,6 +175,7 @@ export async function getSource(settings: IGitSourceSettings): Promise { } } else { fetchOptions.fetchDepth = settings.fetchDepth + fetchOptions.fetchTags = settings.fetchTags const refSpec = refHelper.getRefSpec(settings.ref, settings.commit) await git.fetch(refSpec, fetchOptions) } diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index 3272e63..9875d8d 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -44,6 +44,11 @@ export interface IGitSourceSettings { */ fetchDepth: number + /** + * Fetch tags, even if fetchDepth > 0 (default: false) + */ + fetchTags: boolean + /** * Indicates whether to fetch LFS objects */ diff --git a/src/input-helper.ts b/src/input-helper.ts index 410e480..631fbdb 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -100,6 +100,11 @@ export async function getInputs(): Promise { } core.debug(`fetch depth = ${result.fetchDepth}`) + // Fetch tags + result.fetchTags = + (core.getInput('fetch-tags') || 'false').toUpperCase() === 'TRUE' + core.debug(`fetch tags = ${result.fetchTags}`) + // LFS result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE' core.debug(`lfs = ${result.lfs}`)