diff --git a/README.md b/README.md index 9b6176d..0098750 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,11 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ # Otherwise, uses the default branch. ref: '' + # Indicates whether to checkout the default repository branch if the requested ref + # does not exist + # Default: false + default-branch-checkout: '' + # Personal access token (PAT) used to fetch the repository. The PAT is configured # with the local git config, which enables your scripts to run authenticated git # commands. The post-job step removes the PAT. diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts index 7633704..6cbc872 100644 --- a/__test__/git-auth-helper.test.ts +++ b/__test__/git-auth-helper.test.ts @@ -815,6 +815,7 @@ async function setup(testName: string): Promise { nestedSubmodules: false, persistCredentials: true, ref: 'refs/heads/main', + defaultBranchCheckout: false, repositoryName: 'my-repo', repositoryOwner: 'my-org', repositoryPath: '', diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts index 9514cb4..fcb242a 100644 --- a/__test__/input-helper.test.ts +++ b/__test__/input-helper.test.ts @@ -80,6 +80,7 @@ describe('input-helper tests', () => { expect(settings.commit).toBeTruthy() expect(settings.commit).toBe('1234567890123456789012345678901234567890') expect(settings.filter).toBe(undefined) + expect(settings.defaultBranchCheckout).toBe(false) expect(settings.sparseCheckout).toBe(undefined) expect(settings.sparseCheckoutConeMode).toBe(true) expect(settings.fetchDepth).toBe(1) diff --git a/action.yml b/action.yml index 75d5ae2..774c606 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,9 @@ inputs: 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, uses the default branch. + default-branch-checkout: + description: 'Indicates whether to checkout the default repository branch if the requested ref does not exist' + default: false token: description: > Personal access token (PAT) used to fetch the repository. The PAT is configured diff --git a/dist/index.js b/dist/index.js index c39596b..af523f2 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1280,7 +1280,7 @@ function getSource(settings) { else if (settings.sparseCheckout) { fetchOptions.filter = 'blob:none'; } - if (settings.fetchDepth <= 0) { + if (settings.fetchDepth <= 0 || settings.defaultBranchCheckout) { // Fetch all branches and tags let refSpec = refHelper.getRefSpecForAllHistory(settings.ref, settings.commit); yield git.fetch(refSpec, fetchOptions); @@ -1300,7 +1300,22 @@ function getSource(settings) { core.endGroup(); // Checkout info core.startGroup('Determining the checkout info'); - const checkoutInfo = yield refHelper.getCheckoutInfo(git, settings.ref, settings.commit); + let checkoutInfo; + try { + checkoutInfo = yield refHelper.getCheckoutInfo(git, settings.ref, settings.commit); + } + catch (error) { + if (settings.defaultBranchCheckout) { + core.info('Could not determine the checkout info. Trying the default repository branch'); + const repositoryDefaultBranch = settings.sshKey + ? yield git.getDefaultBranch(repositoryUrl) + : yield githubApiHelper.getDefaultBranch(settings.authToken, settings.repositoryOwner, settings.repositoryName); + checkoutInfo = yield refHelper.getCheckoutInfo(git, repositoryDefaultBranch, settings.commit); + } + else { + throw error; + } + } core.endGroup(); // LFS fetch // Explicit lfs-fetch to avoid slow checkout (fetches one lfs object at a time). @@ -1765,6 +1780,11 @@ function getInputs() { } core.debug(`ref = '${result.ref}'`); core.debug(`commit = '${result.commit}'`); + // Default branch checkout + result.defaultBranchCheckout = + (core.getInput('default-branch-checkout') || 'false').toUpperCase() === + 'TRUE'; + core.debug(`default-branch-checkout = '${result.defaultBranchCheckout}'`); // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'; core.debug(`clean = ${result.clean}`); diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts index f723d94..ca449e6 100644 --- a/src/git-source-provider.ts +++ b/src/git-source-provider.ts @@ -169,7 +169,7 @@ export async function getSource(settings: IGitSourceSettings): Promise { fetchOptions.filter = 'blob:none' } - if (settings.fetchDepth <= 0) { + if (settings.fetchDepth <= 0 || settings.defaultBranchCheckout) { // Fetch all branches and tags let refSpec = refHelper.getRefSpecForAllHistory( settings.ref, @@ -193,11 +193,34 @@ export async function getSource(settings: IGitSourceSettings): Promise { // Checkout info core.startGroup('Determining the checkout info') - const checkoutInfo = await refHelper.getCheckoutInfo( - git, - settings.ref, - settings.commit - ) + let checkoutInfo: refHelper.ICheckoutInfo + try { + checkoutInfo = await refHelper.getCheckoutInfo( + git, + settings.ref, + settings.commit + ) + } catch (error) { + if (settings.defaultBranchCheckout) { + core.info( + 'Could not determine the checkout info. Trying the default repository branch' + ) + const repositoryDefaultBranch = settings.sshKey + ? await git.getDefaultBranch(repositoryUrl) + : await githubApiHelper.getDefaultBranch( + settings.authToken, + settings.repositoryOwner, + settings.repositoryName + ) + checkoutInfo = await refHelper.getCheckoutInfo( + git, + repositoryDefaultBranch, + settings.commit + ) + } else { + throw error + } + } core.endGroup() // LFS fetch diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index 4e41ac3..87a0a4c 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -19,6 +19,11 @@ export interface IGitSourceSettings { */ ref: string + /** + * Indicates whether to checkout the default repository branch if the requested ref does not exist + */ + defaultBranchCheckout: boolean + /** * The commit to checkout */ diff --git a/src/input-helper.ts b/src/input-helper.ts index 059232f..1b02e6b 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -78,6 +78,12 @@ export async function getInputs(): Promise { core.debug(`ref = '${result.ref}'`) core.debug(`commit = '${result.commit}'`) + // Default branch checkout + result.defaultBranchCheckout = + (core.getInput('default-branch-checkout') || 'false').toUpperCase() === + 'TRUE' + core.debug(`default-branch-checkout = '${result.defaultBranchCheckout}'`) + // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE' core.debug(`clean = ${result.clean}`)