diff --git a/README.md b/README.md index 9b6176d94..36f6465ce 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: '' + # The commit SHA to checkout. Used when ref is not specified or is ambiguous. This + # can be used as a replacement for ref, or alongside it to checkout a specific + # commit of the ref. + commit: '' + # 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__/input-helper.test.ts b/__test__/input-helper.test.ts index 9514cb42d..99187b691 100644 --- a/__test__/input-helper.test.ts +++ b/__test__/input-helper.test.ts @@ -144,4 +144,30 @@ describe('input-helper tests', () => { const settings: IGitSourceSettings = await inputHelper.getInputs() expect(settings.workflowOrganizationId).toBe(123456) }) + + it('accepts ref and commit', async () => { + inputs.ref = 'refs/pull/123/merge' + inputs.commit = '0123456789012345678901234567890123456789' + const settings: IGitSourceSettings = await inputHelper.getInputs() + expect(settings).toBeTruthy() + expect(settings.ref).toBeTruthy() + expect(settings.ref).toStrictEqual('refs/pull/123/merge') + expect(settings.commit).toBeTruthy() + expect(settings.commit).toStrictEqual( + '0123456789012345678901234567890123456789' + ) + }) + + it('ref fallbacks to commit if ref is empty but commit is specified', async () => { + inputs.ref = '' + inputs.commit = '0123456789012345678901234567890123456789' + const settings: IGitSourceSettings = await inputHelper.getInputs() + expect(settings).toBeTruthy() + expect(settings.ref).toBeFalsy() + expect(settings.ref).toStrictEqual('') + expect(settings.commit).toBeTruthy() + expect(settings.commit).toStrictEqual( + '0123456789012345678901234567890123456789' + ) + }) }) diff --git a/action.yml b/action.yml index 75d5ae2d8..0ec5365db 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,11 @@ 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. + commit: + description: > + The commit SHA to checkout. Used when ref is not specified or is ambiguous. + This can be used as a replacement for ref, or alongside it to checkout a + specific commit of the ref. 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 9d959a9ee..06398b566 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1748,7 +1748,11 @@ function getInputs() { const isWorkflowRepository = qualifiedRepository.toUpperCase() === `${github.context.repo.owner}/${github.context.repo.repo}`.toUpperCase(); // Source branch, source version - result.ref = core.getInput('ref'); + result.commit = core.getInput('commit'); + if (result.commit && !result.commit.match(/^[0-9a-fA-F]{40}$/)) { + throw new Error(`The commit SHA '${result.commit}' is not a valid SHA.`); + } + result.ref = core.getInput('ref') || result.commit; if (!result.ref) { if (isWorkflowRepository) { result.ref = github.context.ref; diff --git a/src/input-helper.ts b/src/input-helper.ts index 059232f5c..de6463612 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -57,7 +57,12 @@ export async function getInputs(): Promise { `${github.context.repo.owner}/${github.context.repo.repo}`.toUpperCase() // Source branch, source version - result.ref = core.getInput('ref') + result.commit = core.getInput('commit') + if (result.commit && !result.commit.match(/^[0-9a-fA-F]{40}$/)) { + throw new Error(`The commit SHA '${result.commit}' is not a valid SHA.`) + } + + result.ref = core.getInput('ref') || result.commit if (!result.ref) { if (isWorkflowRepository) { result.ref = github.context.ref