diff --git a/.github/workflows/publish-immutable-actions.yml b/.github/workflows/publish-immutable-actions.yml deleted file mode 100644 index 87c0207..0000000 --- a/.github/workflows/publish-immutable-actions.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: 'Publish Immutable Action Version' - -on: - release: - types: [published] - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - packages: write - - steps: - - name: Checking out - uses: actions/checkout@v4 - - name: Publish - id: publish - uses: actions/publish-immutable-action@0.0.3 diff --git a/CHANGELOG.md b/CHANGELOG.md index a96c76e..877a50f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,5 @@ # Changelog -## v4.2.2 -* `url-helper.ts` now leverages well-known environment variables by @jww3 in https://github.com/actions/checkout/pull/1941 -* Expand unit test coverage for `isGhes` by @jww3 in https://github.com/actions/checkout/pull/1946 - -## v4.2.1 -* Check out other refs/* by commit if provided, fall back to ref by @orhantoy in https://github.com/actions/checkout/pull/1924 - ## v4.2.0 * Add Ref and Commit outputs by @lucacome in https://github.com/actions/checkout/pull/1180 diff --git a/README.md b/README.md index 64dc025..e1ea032 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,6 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ - [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) -- [Push a commit to a PR using the built-in token](#Push-a-commit-to-a-PR-using-the-built-in-token) ## Fetch only the root files @@ -212,7 +211,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ repository: my-org/my-tools path: my-tools ``` -> - If your secondary repository is private or internal you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private) +> - If your secondary repository is private you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private) ## Checkout multiple repos (nested) @@ -226,7 +225,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ repository: my-org/my-tools path: my-tools ``` -> - If your secondary repository is private or internal you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private) +> - If your secondary repository is private you will need to add the option noted in [Checkout multiple repos (private)](#Checkout-multiple-repos-private) ## Checkout multiple repos (private) @@ -289,40 +288,6 @@ jobs: ``` *NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D -## Push a commit to a PR using the built-in token - -In a pull request trigger, `ref` is required as GitHub Actions checks out in detached HEAD mode, meaning it doesn’t check out your branch by default. - -```yaml -on: pull_request -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - - run: | - date > generated.txt - # Note: the following account information will not work on GHES - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add . - git commit -m "generated" - git push -``` - -*NOTE:* The user email is `{user.id}+{user.login}@users.noreply.github.com`. See users API: https://api.github.com/users/github-actions%5Bbot%5D - -# Recommended permissions - -When using the `checkout` action in your GitHub Actions workflow, it is recommended to set the following `GITHUB_TOKEN` permissions to ensure proper functionality, unless alternative auth is provided via the `token` or `ssh-key` inputs: - -```yaml -permissions: - contents: read -``` - # License The scripts and documentation in this project are released under the [MIT License](LICENSE) diff --git a/__test__/ref-helper.test.ts b/__test__/ref-helper.test.ts index 5c8d76b..d3b00b7 100644 --- a/__test__/ref-helper.test.ts +++ b/__test__/ref-helper.test.ts @@ -77,16 +77,6 @@ describe('ref-helper tests', () => { expect(checkoutInfo.startPoint).toBeFalsy() }) - it('getCheckoutInfo refs/ without commit', async () => { - const checkoutInfo = await refHelper.getCheckoutInfo( - git, - 'refs/non-standard-ref', - '' - ) - expect(checkoutInfo.ref).toBe('refs/non-standard-ref') - expect(checkoutInfo.startPoint).toBeFalsy() - }) - it('getCheckoutInfo unqualified branch only', async () => { git.branchExists = jest.fn(async (remote: boolean, pattern: string) => { return true diff --git a/__test__/url-helper.test.ts b/__test__/url-helper.test.ts deleted file mode 100644 index 57cb28f..0000000 --- a/__test__/url-helper.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as urlHelper from '../src/url-helper' - -describe('getServerUrl tests', () => { - it('basics', async () => { - // Note that URL::toString will append a trailing / when passed just a domain name ... - expect(urlHelper.getServerUrl().toString()).toBe('https://github.com/') - expect(urlHelper.getServerUrl(' ').toString()).toBe('https://github.com/') - expect(urlHelper.getServerUrl(' ').toString()).toBe('https://github.com/') - expect(urlHelper.getServerUrl('http://contoso.com').toString()).toBe( - 'http://contoso.com/' - ) - expect(urlHelper.getServerUrl('https://contoso.com').toString()).toBe( - 'https://contoso.com/' - ) - expect(urlHelper.getServerUrl('https://contoso.com/').toString()).toBe( - 'https://contoso.com/' - ) - - // ... but can't make that same assumption when passed an URL that includes some deeper path. - expect(urlHelper.getServerUrl('https://contoso.com/a/b').toString()).toBe( - 'https://contoso.com/a/b' - ) - }) -}) - -describe('isGhes tests', () => { - const pristineEnv = process.env - - beforeEach(() => { - jest.resetModules() - process.env = {...pristineEnv} - }) - - afterAll(() => { - process.env = pristineEnv - }) - - it('basics', async () => { - delete process.env['GITHUB_SERVER_URL'] - expect(urlHelper.isGhes()).toBeFalsy() - expect(urlHelper.isGhes('https://github.com')).toBeFalsy() - expect(urlHelper.isGhes('https://contoso.ghe.com')).toBeFalsy() - expect(urlHelper.isGhes('https://test.github.localhost')).toBeFalsy() - expect(urlHelper.isGhes('https://src.onpremise.fabrikam.com')).toBeTruthy() - }) - - it('returns false when the GITHUB_SERVER_URL environment variable is not defined', async () => { - delete process.env['GITHUB_SERVER_URL'] - expect(urlHelper.isGhes()).toBeFalsy() - }) - - it('returns false when the GITHUB_SERVER_URL environment variable is set to github.com', async () => { - process.env['GITHUB_SERVER_URL'] = 'https://github.com' - expect(urlHelper.isGhes()).toBeFalsy() - }) - - it('returns false when the GITHUB_SERVER_URL environment variable is set to a GitHub Enterprise Cloud-style URL', async () => { - process.env['GITHUB_SERVER_URL'] = 'https://contoso.ghe.com' - expect(urlHelper.isGhes()).toBeFalsy() - }) - - it('returns false when the GITHUB_SERVER_URL environment variable has a .localhost suffix', async () => { - process.env['GITHUB_SERVER_URL'] = 'https://mock-github.localhost' - expect(urlHelper.isGhes()).toBeFalsy() - }) - - it('returns true when the GITHUB_SERVER_URL environment variable is set to some other URL', async () => { - process.env['GITHUB_SERVER_URL'] = 'https://src.onpremise.fabrikam.com' - expect(urlHelper.isGhes()).toBeTruthy() - }) -}) - -describe('getServerApiUrl tests', () => { - it('basics', async () => { - expect(urlHelper.getServerApiUrl()).toBe('https://api.github.com') - expect(urlHelper.getServerApiUrl('https://github.com')).toBe( - 'https://api.github.com' - ) - expect(urlHelper.getServerApiUrl('https://GitHub.com')).toBe( - 'https://api.github.com' - ) - expect(urlHelper.getServerApiUrl('https://contoso.ghe.com')).toBe( - 'https://api.contoso.ghe.com' - ) - expect(urlHelper.getServerApiUrl('https://fabrikam.GHE.COM')).toBe( - 'https://api.fabrikam.ghe.com' - ) - expect( - urlHelper.getServerApiUrl('https://src.onpremise.fabrikam.com') - ).toBe('https://src.onpremise.fabrikam.com/api/v3') - }) -}) diff --git a/dist/index.js b/dist/index.js index b0db713..2b7dd09 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2005,8 +2005,8 @@ function getCheckoutInfo(git, ref, commit) { result.ref = ref; } // refs/ - else if (upperRef.startsWith('REFS/')) { - result.ref = commit ? commit : ref; + else if (upperRef.startsWith('REFS/') && commit) { + result.ref = commit; } // Unqualified ref, check for a matching branch or tag else { @@ -2454,50 +2454,22 @@ function getFetchUrl(settings) { return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`; } function getServerUrl(url) { - let resolvedUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com'; - if (hasContent(url, WhitespaceMode.Trim)) { - resolvedUrl = url; - } - return new url_1.URL(resolvedUrl); + let urlValue = url && url.trim().length > 0 + ? url + : process.env['GITHUB_SERVER_URL'] || 'https://github.com'; + return new url_1.URL(urlValue); } function getServerApiUrl(url) { - if (hasContent(url, WhitespaceMode.Trim)) { - let serverUrl = getServerUrl(url); - if (isGhes(url)) { - serverUrl.pathname = 'api/v3'; - } - else { - serverUrl.hostname = 'api.' + serverUrl.hostname; - } - return pruneSuffix(serverUrl.toString(), '/'); + let apiUrl = 'https://api.github.com'; + if (isGhes(url)) { + const serverUrl = getServerUrl(url); + apiUrl = new url_1.URL(`${serverUrl.origin}/api/v3`).toString(); } - return process.env['GITHUB_API_URL'] || 'https://api.github.com'; + return apiUrl; } function isGhes(url) { - const ghUrl = new url_1.URL(url || process.env['GITHUB_SERVER_URL'] || 'https://github.com'); - const hostname = ghUrl.hostname.trimEnd().toUpperCase(); - const isGitHubHost = hostname === 'GITHUB.COM'; - const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM'); - const isLocalHost = hostname.endsWith('.LOCALHOST'); - return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost; -} -function pruneSuffix(text, suffix) { - if (hasContent(suffix, WhitespaceMode.Preserve) && (text === null || text === void 0 ? void 0 : text.endsWith(suffix))) { - return text.substring(0, text.length - suffix.length); - } - return text; -} -var WhitespaceMode; -(function (WhitespaceMode) { - WhitespaceMode[WhitespaceMode["Trim"] = 0] = "Trim"; - WhitespaceMode[WhitespaceMode["Preserve"] = 1] = "Preserve"; -})(WhitespaceMode || (WhitespaceMode = {})); -function hasContent(text, whitespaceMode) { - let refinedText = text !== null && text !== void 0 ? text : ''; - if (whitespaceMode == WhitespaceMode.Trim) { - refinedText = refinedText.trim(); - } - return refinedText.length > 0; + const ghUrl = getServerUrl(url); + return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; } diff --git a/package-lock.json b/package-lock.json index 25753a2..a84d3bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "checkout", - "version": "4.2.2", + "version": "4.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "checkout", - "version": "4.2.2", + "version": "4.2.0", "license": "MIT", "dependencies": { "@actions/core": "^1.10.1", diff --git a/package.json b/package.json index 5661d70..cdccbfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "checkout", - "version": "4.2.2", + "version": "4.2.0", "description": "checkout action", "main": "lib/main.js", "scripts": { diff --git a/src/ref-helper.ts b/src/ref-helper.ts index cbd865f..725660a 100644 --- a/src/ref-helper.ts +++ b/src/ref-helper.ts @@ -46,8 +46,8 @@ export async function getCheckoutInfo( result.ref = ref } // refs/ - else if (upperRef.startsWith('REFS/')) { - result.ref = commit ? commit : ref + else if (upperRef.startsWith('REFS/') && commit) { + result.ref = commit } // Unqualified ref, check for a matching branch or tag else { diff --git a/src/url-helper.ts b/src/url-helper.ts index 17a0842..64ecbf3 100644 --- a/src/url-helper.ts +++ b/src/url-helper.ts @@ -21,61 +21,26 @@ export function getFetchUrl(settings: IGitSourceSettings): string { } export function getServerUrl(url?: string): URL { - let resolvedUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com' - if (hasContent(url, WhitespaceMode.Trim)) { - resolvedUrl = url! - } - - return new URL(resolvedUrl) + let urlValue = + url && url.trim().length > 0 + ? url + : process.env['GITHUB_SERVER_URL'] || 'https://github.com' + return new URL(urlValue) } export function getServerApiUrl(url?: string): string { - if (hasContent(url, WhitespaceMode.Trim)) { - let serverUrl = getServerUrl(url) - if (isGhes(url)) { - serverUrl.pathname = 'api/v3' - } else { - serverUrl.hostname = 'api.' + serverUrl.hostname - } + let apiUrl = 'https://api.github.com' - return pruneSuffix(serverUrl.toString(), '/') + if (isGhes(url)) { + const serverUrl = getServerUrl(url) + apiUrl = new URL(`${serverUrl.origin}/api/v3`).toString() } - return process.env['GITHUB_API_URL'] || 'https://api.github.com' + return apiUrl } export function isGhes(url?: string): boolean { - const ghUrl = new URL( - url || process.env['GITHUB_SERVER_URL'] || 'https://github.com' - ) + const ghUrl = getServerUrl(url) - const hostname = ghUrl.hostname.trimEnd().toUpperCase() - const isGitHubHost = hostname === 'GITHUB.COM' - const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM') - const isLocalHost = hostname.endsWith('.LOCALHOST') - - return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost -} - -function pruneSuffix(text: string, suffix: string) { - if (hasContent(suffix, WhitespaceMode.Preserve) && text?.endsWith(suffix)) { - return text.substring(0, text.length - suffix.length) - } - return text -} - -enum WhitespaceMode { - Trim, - Preserve -} - -function hasContent( - text: string | undefined, - whitespaceMode: WhitespaceMode -): boolean { - let refinedText = text ?? '' - if (whitespaceMode == WhitespaceMode.Trim) { - refinedText = refinedText.trim() - } - return refinedText.length > 0 + return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM' }