fix: fetch tags on repo cached by the CI
This commit is contained in:
		
							parent
							
								
									28b54800cd
								
							
						
					
					
						commit
						6b5b02ea75
					
				
							
								
								
									
										17
									
								
								lib/git.js
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								lib/git.js
									
									
									
									
									
								
							| @ -86,15 +86,22 @@ async function isRefExists(ref, execaOpts) { | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Unshallow the git repository if necessary and fetch all the tags. | ||||
|  * Fetch all the tags from a branch. Unshallow if necessary. | ||||
|  * This will update the local branch from the latest on the remote if: | ||||
|  * - The branch is not the one that triggered the CI | ||||
|  * - The CI created a detached head | ||||
|  * | ||||
|  * Otherwise it just calls `git fetch` without specifying the `refspec` option to avoid overwritting the head commit set by the CI. | ||||
|  * | ||||
|  * The goal is to retrieve the informations on all the release branches without "disturbing" the CI, leaving the trigger branch or the detached head intact. | ||||
|  * | ||||
|  * @param {String} repositoryUrl The remote repository URL. | ||||
|  * @param {String} branch The repository branch to fetch. | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  */ | ||||
| async function fetch(repositoryUrl, branch, ciBranch, execaOpts) { | ||||
|   const isLocalExists = | ||||
|     (await execa('git', ['rev-parse', '--verify', branch], {...execaOpts, reject: false})).exitCode === 0; | ||||
|   const isDetachedHead = | ||||
|     (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {...execaOpts, reject: false})).stdout === 'HEAD'; | ||||
| 
 | ||||
|   try { | ||||
|     await execa( | ||||
| @ -103,7 +110,7 @@ async function fetch(repositoryUrl, branch, ciBranch, execaOpts) { | ||||
|         'fetch', | ||||
|         '--unshallow', | ||||
|         '--tags', | ||||
|         ...(branch === ciBranch && isLocalExists | ||||
|         ...(branch === ciBranch && !isDetachedHead | ||||
|           ? [repositoryUrl] | ||||
|           : ['--update-head-ok', repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]), | ||||
|       ], | ||||
| @ -115,7 +122,7 @@ async function fetch(repositoryUrl, branch, ciBranch, execaOpts) { | ||||
|       [ | ||||
|         'fetch', | ||||
|         '--tags', | ||||
|         ...(branch === ciBranch && isLocalExists | ||||
|         ...(branch === ciBranch && !isDetachedHead | ||||
|           ? [repositoryUrl] | ||||
|           : ['--update-head-ok', repositoryUrl, `+refs/heads/${branch}:refs/heads/${branch}`]), | ||||
|       ], | ||||
|  | ||||
| @ -32,6 +32,7 @@ import { | ||||
|   gitDetachedHeadFromBranch, | ||||
|   gitAddNote, | ||||
|   gitGetNote, | ||||
|   gitFetch, | ||||
| } from './helpers/git-utils'; | ||||
| 
 | ||||
| test('Get the last commit sha', async t => { | ||||
| @ -99,7 +100,7 @@ test('Fetch all tags on a detached head repository', async t => { | ||||
|   t.deepEqual((await getTags('master', {cwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0'].sort()); | ||||
| }); | ||||
| 
 | ||||
| test('Fetch all tags on a repository with a detached head from branch', async t => { | ||||
| test('Fetch all tags on a repository with a detached head from branch (CircleCI)', async t => { | ||||
|   let {cwd, repositoryUrl} = await gitRepo(); | ||||
| 
 | ||||
|   await gitCommits(['First'], {cwd}); | ||||
| @ -124,6 +125,34 @@ test('Fetch all tags on a repository with a detached head from branch', async t | ||||
|   t.deepEqual((await getTags('master', {cwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0', 'v2.0.0'].sort()); | ||||
| }); | ||||
| 
 | ||||
| test('Fetch all tags on a detached head repository with outdated cached repo (GitLab CI)', async t => { | ||||
|   const {cwd, repositoryUrl} = await gitRepo(); | ||||
| 
 | ||||
|   await gitCommits(['First'], {cwd}); | ||||
|   await gitTagVersion('v1.0.0', undefined, {cwd}); | ||||
|   await gitCommits(['Second'], {cwd}); | ||||
|   await gitTagVersion('v1.0.1', undefined, {cwd}); | ||||
|   let [commit] = await gitCommits(['Third'], {cwd}); | ||||
|   await gitTagVersion('v1.1.0', undefined, {cwd}); | ||||
|   await gitPush(repositoryUrl, 'master', {cwd}); | ||||
| 
 | ||||
|   // Create a clone (as first CI run would)
 | ||||
|   const cloneCwd = await gitShallowClone(repositoryUrl); | ||||
|   await gitFetch(repositoryUrl, {cwd: cloneCwd}); | ||||
|   await gitCheckout(commit.hash, false, {cwd: cloneCwd}); | ||||
| 
 | ||||
|   // Push tag to remote
 | ||||
|   [commit] = await gitCommits(['Fourth'], {cwd}); | ||||
|   await gitTagVersion('v1.2.0', undefined, {cwd}); | ||||
|   await gitPush(repositoryUrl, 'master', {cwd}); | ||||
| 
 | ||||
|   // Fetch on the cached repo and make detached head, leaving master outdated
 | ||||
|   await fetch(repositoryUrl, 'master', 'master', {cwd: cloneCwd}); | ||||
|   await gitCheckout(commit.hash, false, {cwd: cloneCwd}); | ||||
| 
 | ||||
|   t.deepEqual((await getTags('master', {cwd: cloneCwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0', 'v1.2.0'].sort()); | ||||
| }); | ||||
| 
 | ||||
| test('Verify if a branch exists', async t => { | ||||
|   // Create a git repository, set the current working directory at the root of the repo
 | ||||
|   const {cwd} = await gitRepo(); | ||||
|  | ||||
| @ -109,6 +109,16 @@ export async function gitCheckout(branch, create, execaOpts) { | ||||
|   await execa('git', create ? ['checkout', '-b', branch] : ['checkout', branch], execaOpts); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Fetch current git repository. | ||||
|  * | ||||
|  * @param {String} repositoryUrl The repository remote URL. | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  */ | ||||
| export async function gitFetch(repositoryUrl, execaOpts) { | ||||
|   await execa('git', ['fetch', repositoryUrl], execaOpts); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the HEAD sha. | ||||
|  * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user