mirror of
				https://github.com/actions/checkout.git
				synced 2025-10-31 15:47:36 +00:00 
			
		
		
		
	Compare commits
	
		
			11 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2036a08e25 | ||
|   | 592cf69a22 | ||
|   | a4b69b4886 | ||
|   | 1433f62caa | ||
|   | 61b9e3751b | ||
|   | 28c7f3d2b5 | ||
|   | fb6f360df2 | ||
|   | b4483adec3 | ||
|   | 00a3be8934 | ||
|   | 453ee27fca | ||
|   | 65865e15a1 | 
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ on: | ||||
|   pull_request: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|       - main | ||||
|       - releases/* | ||||
|  | ||||
| jobs: | ||||
|   | ||||
							
								
								
									
										11
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,9 +1,20 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## v2.3.1 | ||||
|  | ||||
| - [Fix default branch resolution for .wiki and when using SSH](https://github.com/actions/checkout/pull/284) | ||||
|  | ||||
|  | ||||
| ## v2.3.0 | ||||
|  | ||||
| - [Fallback to the default branch](https://github.com/actions/checkout/pull/278) | ||||
|  | ||||
| ## v2.2.0 | ||||
|  | ||||
| - [Fetch all history for all tags and branches when fetch-depth=0](https://github.com/actions/checkout/pull/258) | ||||
|  | ||||
| ## v2.1.1 | ||||
|  | ||||
| - Changes to support GHES ([here](https://github.com/actions/checkout/pull/236) and [here](https://github.com/actions/checkout/pull/248)) | ||||
|  | ||||
| ## v2.1.0 | ||||
|   | ||||
							
								
								
									
										25
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								README.md
									
									
									
									
									
								
							| @@ -42,7 +42,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous | ||||
|  | ||||
|     # The branch, tag or SHA to checkout. When checking out the repository that | ||||
|     # triggered a workflow, this defaults to the reference or SHA for that event. | ||||
|     # Otherwise, defaults to `master`. | ||||
|     # Otherwise, uses the default branch. | ||||
|     ref: '' | ||||
|  | ||||
|     # Personal access token (PAT) used to fetch the repository. The PAT is configured | ||||
| @@ -89,7 +89,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous | ||||
|     # Default: true | ||||
|     clean: '' | ||||
|  | ||||
|     # Number of commits to fetch. 0 indicates all history. | ||||
|     # Number of commits to fetch. 0 indicates all history for all branches and tags. | ||||
|     # Default: 1 | ||||
|     fetch-depth: '' | ||||
|  | ||||
| @@ -118,6 +118,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous | ||||
| - [Checkout multiple repos (private)](#Checkout-multiple-repos-private) | ||||
| - [Checkout pull request HEAD commit instead of merge commit](#Checkout-pull-request-HEAD-commit-instead-of-merge-commit) | ||||
| - [Checkout pull request on closed event](#Checkout-pull-request-on-closed-event) | ||||
| - [Push a commit using the built-in token](#Push-a-commit-using-the-built-in-token) | ||||
|  | ||||
| ## Fetch all history for all tags and branches | ||||
|  | ||||
| @@ -204,7 +205,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous | ||||
| ```yaml | ||||
| on: | ||||
|   pull_request: | ||||
|     branches: [master] | ||||
|     branches: [main] | ||||
|     types: [opened, synchronize, closed] | ||||
| jobs: | ||||
|   build: | ||||
| @@ -213,6 +214,24 @@ jobs: | ||||
|       - uses: actions/checkout@v2 | ||||
| ``` | ||||
|  | ||||
| ## Push a commit using the built-in token | ||||
|  | ||||
| ```yaml | ||||
| on: push | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v2 | ||||
|       - run: | | ||||
|           date > generated.txt | ||||
|           git config user.name github-actions | ||||
|           git config user.email github-actions@github.com | ||||
|           git add . | ||||
|           git commit -m "generated" | ||||
|           git push | ||||
| ``` | ||||
|  | ||||
| # License | ||||
|  | ||||
| The scripts and documentation in this project are released under the [MIT License](LICENSE) | ||||
|   | ||||
| @@ -714,6 +714,7 @@ async function setup(testName: string): Promise<void> { | ||||
|     ), | ||||
|     env: {}, | ||||
|     fetch: jest.fn(), | ||||
|     getDefaultBranch: jest.fn(), | ||||
|     getWorkingDirectory: jest.fn(() => workspace), | ||||
|     init: jest.fn(), | ||||
|     isDetached: jest.fn(), | ||||
| @@ -763,7 +764,7 @@ async function setup(testName: string): Promise<void> { | ||||
|     submodules: false, | ||||
|     nestedSubmodules: false, | ||||
|     persistCredentials: true, | ||||
|     ref: 'refs/heads/master', | ||||
|     ref: 'refs/heads/main', | ||||
|     repositoryName: 'my-repo', | ||||
|     repositoryOwner: 'my-org', | ||||
|     repositoryPath: '', | ||||
|   | ||||
| @@ -408,6 +408,7 @@ async function setup(testName: string): Promise<void> { | ||||
|     config: jest.fn(), | ||||
|     configExists: jest.fn(), | ||||
|     fetch: jest.fn(), | ||||
|     getDefaultBranch: jest.fn(), | ||||
|     getWorkingDirectory: jest.fn(() => repositoryPath), | ||||
|     init: jest.fn(), | ||||
|     isDetached: jest.fn(), | ||||
|   | ||||
| @@ -110,13 +110,6 @@ describe('input-helper tests', () => { | ||||
|     ) | ||||
|   }) | ||||
|  | ||||
|   it('sets correct default ref/sha for other repo', () => { | ||||
|     inputs.repository = 'some-owner/some-other-repo' | ||||
|     const settings: IGitSourceSettings = inputHelper.getInputs() | ||||
|     expect(settings.ref).toBe('refs/heads/master') | ||||
|     expect(settings.commit).toBeFalsy() | ||||
|   }) | ||||
|  | ||||
|   it('sets ref to empty when explicit sha', () => { | ||||
|     inputs.ref = '1111111111222222222233333333334444444444' | ||||
|     const settings: IGitSourceSettings = inputHelper.getInputs() | ||||
|   | ||||
| @@ -20,5 +20,5 @@ else | ||||
|  | ||||
|   # Verify auth token | ||||
|   cd basic | ||||
|   git fetch --no-tags --depth=1 origin +refs/heads/master:refs/remotes/origin/master | ||||
|   git fetch --no-tags --depth=1 origin +refs/heads/main:refs/remotes/origin/main | ||||
| fi | ||||
|   | ||||
| @@ -12,6 +12,6 @@ if [[ "$(git status --porcelain)" != "" ]]; then | ||||
|     echo ---------------------------------------- | ||||
|     echo Troubleshooting | ||||
|     echo ---------------------------------------- | ||||
|     echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && npm ci && npm run all" | ||||
|     echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && npm ci && npm run format && npm run build" | ||||
|     exit 1 | ||||
| fi | ||||
|   | ||||
| @@ -8,7 +8,7 @@ inputs: | ||||
|     description: > | ||||
|       The branch, tag or SHA to checkout. When checking out the repository that | ||||
|       triggered a workflow, this defaults to the reference or SHA for that | ||||
|       event.  Otherwise, defaults to `master`. | ||||
|       event.  Otherwise, uses the default branch. | ||||
|   token: | ||||
|     description: > | ||||
|       Personal access token (PAT) used to fetch the repository. The PAT is configured | ||||
| @@ -54,7 +54,7 @@ inputs: | ||||
|     description: 'Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching' | ||||
|     default: true | ||||
|   fetch-depth: | ||||
|     description: 'Number of commits to fetch. 0 indicates all history.' | ||||
|     description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' | ||||
|     default: 1 | ||||
|   lfs: | ||||
|     description: 'Whether to download Git-LFS files' | ||||
|   | ||||
| @@ -24,7 +24,7 @@ We want to take this opportunity to make behavioral changes, from v1. This docum | ||||
|     description: > | ||||
|       The branch, tag or SHA to checkout. When checking out the repository that | ||||
|       triggered a workflow, this defaults to the reference or SHA for that | ||||
|       event.  Otherwise, defaults to `master`. | ||||
|       event.  Otherwise, uses the default branch. | ||||
|   token: | ||||
|     description: > | ||||
|       Personal access token (PAT) used to fetch the repository. The PAT is configured | ||||
| @@ -277,7 +277,7 @@ Note: | ||||
| ### Branching strategy and release tags | ||||
|  | ||||
| - Create a servicing branch for V1: `releases/v1` | ||||
| - Merge the changes into `master` | ||||
| - Merge the changes into the default branch | ||||
| - Release using a new tag `preview` | ||||
| - When stable, release using a new tag `v2` | ||||
|  | ||||
|   | ||||
							
								
								
									
										88
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							| @@ -5827,6 +5827,33 @@ class GitCommandManager { | ||||
|             })); | ||||
|         }); | ||||
|     } | ||||
|     getDefaultBranch(repositoryUrl) { | ||||
|         return __awaiter(this, void 0, void 0, function* () { | ||||
|             let output; | ||||
|             yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { | ||||
|                 output = yield this.execGit([ | ||||
|                     'ls-remote', | ||||
|                     '--quiet', | ||||
|                     '--exit-code', | ||||
|                     '--symref', | ||||
|                     repositoryUrl, | ||||
|                     'HEAD' | ||||
|                 ]); | ||||
|             })); | ||||
|             if (output) { | ||||
|                 // Satisfy compiler, will always be set | ||||
|                 for (let line of output.stdout.trim().split('\n')) { | ||||
|                     line = line.trim(); | ||||
|                     if (line.startsWith('ref:') || line.endsWith('HEAD')) { | ||||
|                         return line | ||||
|                             .substr('ref:'.length, line.length - 'ref:'.length - 'HEAD'.length) | ||||
|                             .trim(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             throw new Error('Unexpected output when retrieving default branch'); | ||||
|         }); | ||||
|     } | ||||
|     getWorkingDirectory() { | ||||
|         return this.workingDirectory; | ||||
|     } | ||||
| @@ -5873,7 +5900,7 @@ class GitCommandManager { | ||||
|     /** | ||||
|      * Resolves a ref to a SHA. For a branch or lightweight tag, the commit SHA is returned. | ||||
|      * For an annotated tag, the tag SHA is returned. | ||||
|      * @param {string} ref  For example: 'refs/heads/master' or '/refs/tags/v1' | ||||
|      * @param {string} ref  For example: 'refs/heads/main' or '/refs/tags/v1' | ||||
|      * @returns {Promise<string>} | ||||
|      */ | ||||
|     revParse(ref) { | ||||
| @@ -6166,6 +6193,17 @@ function getSource(settings) { | ||||
|             core.startGroup('Setting up auth'); | ||||
|             yield authHelper.configureAuth(); | ||||
|             core.endGroup(); | ||||
|             // Determine the default branch | ||||
|             if (!settings.ref && !settings.commit) { | ||||
|                 core.startGroup('Determining the default branch'); | ||||
|                 if (settings.sshKey) { | ||||
|                     settings.ref = yield git.getDefaultBranch(repositoryUrl); | ||||
|                 } | ||||
|                 else { | ||||
|                     settings.ref = yield githubApiHelper.getDefaultBranch(settings.authToken, settings.repositoryOwner, settings.repositoryName); | ||||
|                 } | ||||
|                 core.endGroup(); | ||||
|             } | ||||
|             // LFS install | ||||
|             if (settings.lfs) { | ||||
|                 yield git.lfsInstall(); | ||||
| @@ -9525,6 +9563,11 @@ const v4_1 = __importDefault(__webpack_require__(826)); | ||||
| const IS_WINDOWS = process.platform === 'win32'; | ||||
| function downloadRepository(authToken, owner, repo, ref, commit, repositoryPath) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         // Determine the default branch | ||||
|         if (!ref && !commit) { | ||||
|             core.info('Determining the default branch'); | ||||
|             ref = yield getDefaultBranch(authToken, owner, repo); | ||||
|         } | ||||
|         // Download the archive | ||||
|         let archiveData = yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { | ||||
|             core.info('Downloading the archive'); | ||||
| @@ -9569,6 +9612,42 @@ function downloadRepository(authToken, owner, repo, ref, commit, repositoryPath) | ||||
|     }); | ||||
| } | ||||
| exports.downloadRepository = downloadRepository; | ||||
| /** | ||||
|  * Looks up the default branch name | ||||
|  */ | ||||
| function getDefaultBranch(authToken, owner, repo) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { | ||||
|             core.info('Retrieving the default branch name'); | ||||
|             const octokit = new github.GitHub(authToken); | ||||
|             let result; | ||||
|             try { | ||||
|                 // Get the default branch from the repo info | ||||
|                 const response = yield octokit.repos.get({ owner, repo }); | ||||
|                 result = response.data.default_branch; | ||||
|                 assert.ok(result, 'default_branch cannot be empty'); | ||||
|             } | ||||
|             catch (err) { | ||||
|                 // Handle .wiki repo | ||||
|                 if (err['status'] === 404 && repo.toUpperCase().endsWith('.WIKI')) { | ||||
|                     result = 'master'; | ||||
|                 } | ||||
|                 // Otherwise error | ||||
|                 else { | ||||
|                     throw err; | ||||
|                 } | ||||
|             } | ||||
|             // Print the default branch | ||||
|             core.info(`Default branch '${result}'`); | ||||
|             // Prefix with 'refs/heads' | ||||
|             if (!result.startsWith('refs/')) { | ||||
|                 result = `refs/heads/${result}`; | ||||
|             } | ||||
|             return result; | ||||
|         })); | ||||
|     }); | ||||
| } | ||||
| exports.getDefaultBranch = getDefaultBranch; | ||||
| function downloadArchive(authToken, owner, repo, ref, commit) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const octokit = new github.GitHub(authToken); | ||||
| @@ -14466,14 +14545,11 @@ function getInputs() { | ||||
|             result.ref = github.context.ref; | ||||
|             result.commit = github.context.sha; | ||||
|             // Some events have an unqualifed ref. For example when a PR is merged (pull_request closed event), | ||||
|             // the ref is unqualifed like "master" instead of "refs/heads/master". | ||||
|             // the ref is unqualifed like "main" instead of "refs/heads/main". | ||||
|             if (result.commit && result.ref && !result.ref.startsWith('refs/')) { | ||||
|                 result.ref = `refs/heads/${result.ref}`; | ||||
|             } | ||||
|         } | ||||
|         if (!result.ref && !result.commit) { | ||||
|             result.ref = 'refs/heads/master'; | ||||
|         } | ||||
|     } | ||||
|     // SHA? | ||||
|     else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) { | ||||
| @@ -14508,7 +14584,7 @@ function getInputs() { | ||||
|     core.debug(`submodules = ${result.submodules}`); | ||||
|     core.debug(`recursive submodules = ${result.nestedSubmodules}`); | ||||
|     // Auth token | ||||
|     result.authToken = core.getInput('token'); | ||||
|     result.authToken = core.getInput('token', { required: true }); | ||||
|     // SSH | ||||
|     result.sshKey = core.getInput('ssh-key'); | ||||
|     result.sshKnownHosts = core.getInput('ssh-known-hosts'); | ||||
|   | ||||
							
								
								
									
										1328
									
								
								dist/licenses.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1328
									
								
								dist/licenses.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -25,6 +25,7 @@ export interface IGitCommandManager { | ||||
|   ): Promise<void> | ||||
|   configExists(configKey: string, globalConfig?: boolean): Promise<boolean> | ||||
|   fetch(refSpec: string[], fetchDepth?: number): Promise<void> | ||||
|   getDefaultBranch(repositoryUrl: string): Promise<string> | ||||
|   getWorkingDirectory(): string | ||||
|   init(): Promise<void> | ||||
|   isDetached(): Promise<boolean> | ||||
| @@ -195,6 +196,34 @@ class GitCommandManager { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   async getDefaultBranch(repositoryUrl: string): Promise<string> { | ||||
|     let output: GitOutput | undefined | ||||
|     await retryHelper.execute(async () => { | ||||
|       output = await this.execGit([ | ||||
|         'ls-remote', | ||||
|         '--quiet', | ||||
|         '--exit-code', | ||||
|         '--symref', | ||||
|         repositoryUrl, | ||||
|         'HEAD' | ||||
|       ]) | ||||
|     }) | ||||
|  | ||||
|     if (output) { | ||||
|       // Satisfy compiler, will always be set | ||||
|       for (let line of output.stdout.trim().split('\n')) { | ||||
|         line = line.trim() | ||||
|         if (line.startsWith('ref:') || line.endsWith('HEAD')) { | ||||
|           return line | ||||
|             .substr('ref:'.length, line.length - 'ref:'.length - 'HEAD'.length) | ||||
|             .trim() | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     throw new Error('Unexpected output when retrieving default branch') | ||||
|   } | ||||
|  | ||||
|   getWorkingDirectory(): string { | ||||
|     return this.workingDirectory | ||||
|   } | ||||
| @@ -241,7 +270,7 @@ class GitCommandManager { | ||||
|   /** | ||||
|    * Resolves a ref to a SHA. For a branch or lightweight tag, the commit SHA is returned. | ||||
|    * For an annotated tag, the tag SHA is returned. | ||||
|    * @param {string} ref  For example: 'refs/heads/master' or '/refs/tags/v1' | ||||
|    * @param {string} ref  For example: 'refs/heads/main' or '/refs/tags/v1' | ||||
|    * @returns {Promise<string>} | ||||
|    */ | ||||
|   async revParse(ref: string): Promise<string> { | ||||
|   | ||||
| @@ -103,6 +103,21 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> { | ||||
|     await authHelper.configureAuth() | ||||
|     core.endGroup() | ||||
|  | ||||
|     // Determine the default branch | ||||
|     if (!settings.ref && !settings.commit) { | ||||
|       core.startGroup('Determining the default branch') | ||||
|       if (settings.sshKey) { | ||||
|         settings.ref = await git.getDefaultBranch(repositoryUrl) | ||||
|       } else { | ||||
|         settings.ref = await githubApiHelper.getDefaultBranch( | ||||
|           settings.authToken, | ||||
|           settings.repositoryOwner, | ||||
|           settings.repositoryName | ||||
|         ) | ||||
|       } | ||||
|       core.endGroup() | ||||
|     } | ||||
|  | ||||
|     // LFS install | ||||
|     if (settings.lfs) { | ||||
|       await git.lfsInstall() | ||||
|   | ||||
| @@ -19,6 +19,12 @@ export async function downloadRepository( | ||||
|   commit: string, | ||||
|   repositoryPath: string | ||||
| ): Promise<void> { | ||||
|   // Determine the default branch | ||||
|   if (!ref && !commit) { | ||||
|     core.info('Determining the default branch') | ||||
|     ref = await getDefaultBranch(authToken, owner, repo) | ||||
|   } | ||||
|  | ||||
|   // Download the archive | ||||
|   let archiveData = await retryHelper.execute(async () => { | ||||
|     core.info('Downloading the archive') | ||||
| @@ -67,6 +73,46 @@ export async function downloadRepository( | ||||
|   io.rmRF(extractPath) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Looks up the default branch name | ||||
|  */ | ||||
| export async function getDefaultBranch( | ||||
|   authToken: string, | ||||
|   owner: string, | ||||
|   repo: string | ||||
| ): Promise<string> { | ||||
|   return await retryHelper.execute(async () => { | ||||
|     core.info('Retrieving the default branch name') | ||||
|     const octokit = new github.GitHub(authToken) | ||||
|     let result: string | ||||
|     try { | ||||
|       // Get the default branch from the repo info | ||||
|       const response = await octokit.repos.get({owner, repo}) | ||||
|       result = response.data.default_branch | ||||
|       assert.ok(result, 'default_branch cannot be empty') | ||||
|     } catch (err) { | ||||
|       // Handle .wiki repo | ||||
|       if (err['status'] === 404 && repo.toUpperCase().endsWith('.WIKI')) { | ||||
|         result = 'master' | ||||
|       } | ||||
|       // Otherwise error | ||||
|       else { | ||||
|         throw err | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Print the default branch | ||||
|     core.info(`Default branch '${result}'`) | ||||
|  | ||||
|     // Prefix with 'refs/heads' | ||||
|     if (!result.startsWith('refs/')) { | ||||
|       result = `refs/heads/${result}` | ||||
|     } | ||||
|  | ||||
|     return result | ||||
|   }) | ||||
| } | ||||
|  | ||||
| async function downloadArchive( | ||||
|   authToken: string, | ||||
|   owner: string, | ||||
|   | ||||
| @@ -63,15 +63,11 @@ export function getInputs(): IGitSourceSettings { | ||||
|       result.commit = github.context.sha | ||||
|  | ||||
|       // Some events have an unqualifed ref. For example when a PR is merged (pull_request closed event), | ||||
|       // the ref is unqualifed like "master" instead of "refs/heads/master". | ||||
|       // the ref is unqualifed like "main" instead of "refs/heads/main". | ||||
|       if (result.commit && result.ref && !result.ref.startsWith('refs/')) { | ||||
|         result.ref = `refs/heads/${result.ref}` | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (!result.ref && !result.commit) { | ||||
|       result.ref = 'refs/heads/master' | ||||
|     } | ||||
|   } | ||||
|   // SHA? | ||||
|   else if (result.ref.match(/^[0-9a-fA-F]{40}$/)) { | ||||
| @@ -110,7 +106,7 @@ export function getInputs(): IGitSourceSettings { | ||||
|   core.debug(`recursive submodules = ${result.nestedSubmodules}`) | ||||
|  | ||||
|   // Auth token | ||||
|   result.authToken = core.getInput('token') | ||||
|   result.authToken = core.getInput('token', {required: true}) | ||||
|  | ||||
|   // SSH | ||||
|   result.sshKey = core.getInput('ssh-key') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user