Compare commits

..

5 Commits

Author SHA1 Message Date
c455122937 . 2020-03-19 00:43:38 -04:00
605b7eb961 . 2020-03-19 00:37:38 -04:00
036772999d . 2020-03-19 00:14:00 -04:00
46054cf00b . 2020-03-18 23:34:02 -04:00
85a425b582 use token for workflow repo 2020-03-18 23:33:26 -04:00
16 changed files with 704 additions and 14065 deletions

View File

@ -1,26 +1,5 @@
# Changelog # Changelog
## 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
- [Group output](https://github.com/actions/checkout/pull/191)
- [Changes to support GHES alpha release](https://github.com/actions/checkout/pull/199)
- [Persist core.sshCommand for submodules](https://github.com/actions/checkout/pull/184)
- [Add support ssh](https://github.com/actions/checkout/pull/163)
- [Convert submodule SSH URL to HTTPS, when not using SSH](https://github.com/actions/checkout/pull/179)
- [Add submodule support](https://github.com/actions/checkout/pull/157)
- [Follow proxy settings](https://github.com/actions/checkout/pull/144)
- [Fix ref for pr closed event when a pr is merged](https://github.com/actions/checkout/pull/141)
- [Fix issue checking detached when git less than 2.22](https://github.com/actions/checkout/pull/128)
## v2.0.0
- [Do not pass cred on command line](https://github.com/actions/checkout/pull/108)
- [Add input persist-credentials](https://github.com/actions/checkout/pull/107)
- [Fallback to REST API to download repo](https://github.com/actions/checkout/pull/104)
## v2 (beta) ## v2 (beta)
- Improved fetch performance - Improved fetch performance

View File

@ -18,7 +18,6 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
- Fetches only a single commit by default - Fetches only a single commit by default
- Script authenticated git commands - Script authenticated git commands
- Auth token persisted in the local git config - Auth token persisted in the local git config
- Supports SSH
- Creates a local branch - Creates a local branch
- No longer detached HEAD when checking out a branch - No longer detached HEAD when checking out a branch
- Improved layout - Improved layout
@ -27,6 +26,7 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
- Fallback to REST API download - Fallback to REST API download
- When Git 2.18 or higher is not in the PATH, the REST API will be used to download the files - When Git 2.18 or higher is not in the PATH, the REST API will be used to download the files
- When using a job container, the container's PATH is used - When using a job container, the container's PATH is used
- Removed input `submodules`
Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous versions. Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous versions.
@ -117,6 +117,7 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
- [Checkout multiple repos (private)](#Checkout-multiple-repos-private) - [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 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) - [Checkout pull request on closed event](#Checkout-pull-request-on-closed-event)
- [Checkout submodules](#Checkout-submodules)
- [Fetch all tags](#Fetch-all-tags) - [Fetch all tags](#Fetch-all-tags)
- [Fetch all branches](#Fetch-all-branches) - [Fetch all branches](#Fetch-all-branches)
- [Fetch all history for all tags and branches](#Fetch-all-history-for-all-tags-and-branches) - [Fetch all history for all tags and branches](#Fetch-all-history-for-all-tags-and-branches)
@ -207,6 +208,20 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
``` ```
## Checkout submodules
```yaml
- uses: actions/checkout@v2
- name: Checkout submodules
shell: bash
run: |
# If your submodules are configured to use SSH instead of HTTPS please uncomment the following line
# git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
```
## Fetch all tags ## Fetch all tags
```yaml ```yaml

View File

@ -725,6 +725,7 @@ async function setup(testName: string): Promise<void> {
setEnvironmentVariable: jest.fn((name: string, value: string) => { setEnvironmentVariable: jest.fn((name: string, value: string) => {
git.env[name] = value git.env[name] = value
}), }),
setRemoteUrl: jest.fn(),
submoduleForeach: jest.fn(async () => { submoduleForeach: jest.fn(async () => {
return '' return ''
}), }),
@ -748,7 +749,7 @@ async function setup(testName: string): Promise<void> {
} }
), ),
tryDisableAutomaticGarbageCollection: jest.fn(), tryDisableAutomaticGarbageCollection: jest.fn(),
tryGetFetchUrl: jest.fn(), tryGetRemoteUrl: jest.fn(),
tryReset: jest.fn() tryReset: jest.fn()
} }
@ -757,6 +758,7 @@ async function setup(testName: string): Promise<void> {
clean: true, clean: true,
commit: '', commit: '',
fetchDepth: 1, fetchDepth: 1,
isWorkflowRepository: true,
lfs: false, lfs: false,
submodules: false, submodules: false,
nestedSubmodules: false, nestedSubmodules: false,

View File

@ -7,7 +7,8 @@ import {IGitCommandManager} from '../lib/git-command-manager'
const testWorkspace = path.join(__dirname, '_temp', 'git-directory-helper') const testWorkspace = path.join(__dirname, '_temp', 'git-directory-helper')
let repositoryPath: string let repositoryPath: string
let repositoryUrl: string let httpsUrl: string
let sshUrl: string
let clean: boolean let clean: boolean
let git: IGitCommandManager let git: IGitCommandManager
@ -40,7 +41,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -62,7 +64,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -87,7 +90,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -108,7 +112,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -136,7 +141,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -155,14 +161,15 @@ describe('git-directory-helper tests', () => {
await setup(removesContentsWhenDifferentRepositoryUrl) await setup(removesContentsWhenDifferentRepositoryUrl)
clean = false clean = false
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '') await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
const differentRepositoryUrl = const differentRemoteUrl =
'https://github.com/my-different-org/my-different-repo' 'https://github.com/my-different-org/my-different-repo'
// Act // Act
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
differentRepositoryUrl, differentRemoteUrl,
[differentRemoteUrl],
clean clean
) )
@ -186,7 +193,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -211,7 +219,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -235,7 +244,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
undefined, undefined,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -259,7 +269,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -289,7 +300,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -319,7 +331,8 @@ describe('git-directory-helper tests', () => {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
repositoryPath, repositoryPath,
repositoryUrl, httpsUrl,
[httpsUrl, sshUrl],
clean clean
) )
@ -329,6 +342,30 @@ describe('git-directory-helper tests', () => {
expect(git.branchDelete).toHaveBeenCalledWith(true, 'remote-branch-1') expect(git.branchDelete).toHaveBeenCalledWith(true, 'remote-branch-1')
expect(git.branchDelete).toHaveBeenCalledWith(true, 'remote-branch-2') expect(git.branchDelete).toHaveBeenCalledWith(true, 'remote-branch-2')
}) })
const updatesRemoteUrl = 'updates remote URL'
it(updatesRemoteUrl, async () => {
// Arrange
await setup(updatesRemoteUrl)
await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
// Act
await gitDirectoryHelper.prepareExistingDirectory(
git,
repositoryPath,
sshUrl,
[sshUrl, httpsUrl],
clean
)
// Assert
const files = await fs.promises.readdir(repositoryPath)
expect(files.sort()).toEqual(['.git', 'my-file'])
expect(git.isDetached).toHaveBeenCalled()
expect(git.branchList).toHaveBeenCalled()
expect(core.warning).not.toHaveBeenCalled()
expect(git.setRemoteUrl).toHaveBeenCalledWith(sshUrl)
})
}) })
async function setup(testName: string): Promise<void> { async function setup(testName: string): Promise<void> {
@ -338,8 +375,9 @@ async function setup(testName: string): Promise<void> {
repositoryPath = path.join(testWorkspace, testName) repositoryPath = path.join(testWorkspace, testName)
await fs.promises.mkdir(path.join(repositoryPath, '.git'), {recursive: true}) await fs.promises.mkdir(path.join(repositoryPath, '.git'), {recursive: true})
// Repository URL // Remote URLs
repositoryUrl = 'https://github.com/my-org/my-repo' httpsUrl = 'https://github.com/my-org/my-repo'
sshUrl = 'git@github.com:my-org/my-repo'
// Clean // Clean
clean = true clean = true
@ -365,6 +403,7 @@ async function setup(testName: string): Promise<void> {
remoteAdd: jest.fn(), remoteAdd: jest.fn(),
removeEnvironmentVariable: jest.fn(), removeEnvironmentVariable: jest.fn(),
setEnvironmentVariable: jest.fn(), setEnvironmentVariable: jest.fn(),
setRemoteUrl: jest.fn(),
submoduleForeach: jest.fn(), submoduleForeach: jest.fn(),
submoduleSync: jest.fn(), submoduleSync: jest.fn(),
submoduleUpdate: jest.fn(), submoduleUpdate: jest.fn(),
@ -374,10 +413,10 @@ async function setup(testName: string): Promise<void> {
}), }),
tryConfigUnset: jest.fn(), tryConfigUnset: jest.fn(),
tryDisableAutomaticGarbageCollection: jest.fn(), tryDisableAutomaticGarbageCollection: jest.fn(),
tryGetFetchUrl: jest.fn(async () => { tryGetRemoteUrl: jest.fn(async () => {
// Sanity check - this function shouldn't be called when the .git directory doesn't exist // Sanity check - this function shouldn't be called when the .git directory doesn't exist
await fs.promises.stat(path.join(repositoryPath, '.git')) await fs.promises.stat(path.join(repositoryPath, '.git'))
return repositoryUrl return httpsUrl
}), }),
tryReset: jest.fn(async () => { tryReset: jest.fn(async () => {
return true return true

View File

@ -29,26 +29,14 @@ We want to take this opportunity to make behavioral changes, from v1. This docum
description: > description: >
Personal access token (PAT) used to fetch the repository. The PAT is configured 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 with the local git config, which enables your scripts to run authenticated git
commands. The post-job step removes the PAT. commands. The post-job step removes the PAT. [Learn more about creating and using
encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
We recommend using a service account with the least permissions necessary.
Also when generating a new PAT, select the least scopes necessary.
[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
default: ${{ github.token }} default: ${{ github.token }}
ssh-key: ssh-key:
description: > description: >
SSH key used to fetch the repository. The SSH key is configured with the local SSH key used to fetch the repository. SSH key is configured with the local
git config, which enables your scripts to run authenticated git commands. git config, which enables your scripts to run authenticated git commands.
The post-job step removes the SSH key. The post-job step removes the SSH key. [Learn more about creating and using
We recommend using a service account with the least permissions necessary.
[Learn more about creating and using
encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
ssh-known-hosts: ssh-known-hosts:
description: > description: >
@ -56,10 +44,7 @@ We want to take this opportunity to make behavioral changes, from v1. This docum
SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example,
`ssh-keyscan github.com`. The public key for github.com is always implicitly added. `ssh-keyscan github.com`. The public key for github.com is always implicitly added.
ssh-strict: ssh-strict:
description: > description: 'Whether to perform strict host key checking'
Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes`
and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to
configure additional hosts.
default: true default: true
persist-credentials: persist-credentials:
description: 'Whether to configure the token or SSH key with the local git config' description: 'Whether to configure the token or SSH key with the local git config'
@ -79,11 +64,7 @@ We want to take this opportunity to make behavioral changes, from v1. This docum
description: > description: >
Whether to checkout submodules: `true` to checkout submodules or `recursive` to Whether to checkout submodules: `true` to checkout submodules or `recursive` to
recursively checkout submodules. recursively checkout submodules.
default: 'false'
When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are
converted to HTTPS.
default: false
``` ```
Note: Note:

14366
dist/index.js vendored

File diff suppressed because one or more lines are too long

125
package-lock.json generated
View File

@ -15,19 +15,19 @@
"integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ==" "integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ=="
}, },
"@actions/github": { "@actions/github": {
"version": "2.2.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-2.2.0.tgz", "resolved": "https://registry.npmjs.org/@actions/github/-/github-2.1.0.tgz",
"integrity": "sha512-9UAZqn8ywdR70n3GwVle4N8ALosQs4z50N7XMXrSTUVOmVpaBC5kE3TRTT7qQdi3OaQV24mjGuJZsHUmhD+ZXw==", "integrity": "sha512-G4ncMlh4pLLAvNgHUYUtpWQ1zPf/VYqmRH9oshxLabdaOOnp7i1hgSgzr2xne2YUaSND3uqemd3YYTIsm2f/KQ==",
"requires": { "requires": {
"@actions/http-client": "^1.0.3", "@actions/http-client": "^1.0.3",
"@octokit/graphql": "^4.3.1", "@octokit/graphql": "^4.3.1",
"@octokit/rest": "^16.43.1" "@octokit/rest": "^16.15.0"
} }
}, },
"@actions/http-client": { "@actions/http-client": {
"version": "1.0.8", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.3.tgz",
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "integrity": "sha512-wFwh1U4adB/Zsk4cc9kVqaBOHoknhp/pJQk+aWTocbAZWpIl4Zx/At83WFRLXvxB+5HVTWOACM6qjULMZfQSfw==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "0.0.6"
}, },
@ -622,23 +622,13 @@
} }
}, },
"@octokit/endpoint": { "@octokit/endpoint": {
"version": "6.0.1", "version": "5.5.1",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.1.tgz",
"integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", "integrity": "sha512-nBFhRUb5YzVTCX/iAK1MgQ4uWo89Gu0TH00qQHoYRCsE12dWcG1OiLd7v2EIo2+tpUKPMOQ62QFy9hy9Vg2ULg==",
"requires": { "requires": {
"@octokit/types": "^2.11.1", "@octokit/types": "^2.0.0",
"is-plain-object": "^3.0.0", "is-plain-object": "^3.0.0",
"universal-user-agent": "^5.0.0" "universal-user-agent": "^4.0.0"
},
"dependencies": {
"universal-user-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz",
"integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==",
"requires": {
"os-name": "^3.1.0"
}
}
} }
}, },
"@octokit/graphql": { "@octokit/graphql": {
@ -651,57 +641,25 @@
"universal-user-agent": "^4.0.0" "universal-user-agent": "^4.0.0"
} }
}, },
"@octokit/plugin-paginate-rest": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz",
"integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==",
"requires": {
"@octokit/types": "^2.0.1"
}
},
"@octokit/plugin-request-log": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz",
"integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw=="
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz",
"integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==",
"requires": {
"@octokit/types": "^2.0.1",
"deprecation": "^2.3.1"
}
},
"@octokit/request": { "@octokit/request": {
"version": "5.4.2", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.1.tgz",
"integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", "integrity": "sha512-5/X0AL1ZgoU32fAepTfEoggFinO3rxsMLtzhlUX+RctLrusn/CApJuGFCd0v7GMFhF+8UiCsTTfsu7Fh1HnEJg==",
"requires": { "requires": {
"@octokit/endpoint": "^6.0.1", "@octokit/endpoint": "^5.5.0",
"@octokit/request-error": "^2.0.0", "@octokit/request-error": "^1.0.1",
"@octokit/types": "^2.11.1", "@octokit/types": "^2.0.0",
"deprecation": "^2.0.0", "deprecation": "^2.0.0",
"is-plain-object": "^3.0.0", "is-plain-object": "^3.0.0",
"node-fetch": "^2.3.0", "node-fetch": "^2.3.0",
"once": "^1.4.0", "once": "^1.4.0",
"universal-user-agent": "^5.0.0" "universal-user-agent": "^4.0.0"
},
"dependencies": {
"universal-user-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz",
"integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==",
"requires": {
"os-name": "^3.1.0"
}
}
} }
}, },
"@octokit/request-error": { "@octokit/request-error": {
"version": "2.0.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.0.tgz",
"integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", "integrity": "sha512-DNBhROBYjjV/I9n7A8kVkmQNkqFAMem90dSxqvPq57e2hBr7mNTX98y3R2zDpqMQHVRpBDjsvsfIGgBzy+4PAg==",
"requires": { "requires": {
"@octokit/types": "^2.0.0", "@octokit/types": "^2.0.0",
"deprecation": "^2.0.0", "deprecation": "^2.0.0",
@ -709,14 +667,11 @@
} }
}, },
"@octokit/rest": { "@octokit/rest": {
"version": "16.43.1", "version": "16.38.1",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.38.1.tgz",
"integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==", "integrity": "sha512-zyNFx+/Bd1EXt7LQjfrc6H4wryBQ/oDuZeZhGMBSFr1eMPFDmpEweFQR3R25zjKwBQpDY7L5GQO6A3XSaOfV1w==",
"requires": { "requires": {
"@octokit/auth-token": "^2.4.0", "@octokit/auth-token": "^2.4.0",
"@octokit/plugin-paginate-rest": "^1.1.1",
"@octokit/plugin-request-log": "^1.0.0",
"@octokit/plugin-rest-endpoint-methods": "2.4.0",
"@octokit/request": "^5.2.0", "@octokit/request": "^5.2.0",
"@octokit/request-error": "^1.0.2", "@octokit/request-error": "^1.0.2",
"atob-lite": "^2.0.0", "atob-lite": "^2.0.0",
@ -729,24 +684,12 @@
"octokit-pagination-methods": "^1.1.0", "octokit-pagination-methods": "^1.1.0",
"once": "^1.4.0", "once": "^1.4.0",
"universal-user-agent": "^4.0.0" "universal-user-agent": "^4.0.0"
},
"dependencies": {
"@octokit/request-error": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz",
"integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==",
"requires": {
"@octokit/types": "^2.0.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
}
} }
}, },
"@octokit/types": { "@octokit/types": {
"version": "2.14.0", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.1.1.tgz",
"integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", "integrity": "sha512-89LOYH+d/vsbDX785NOfLxTW88GjNd0lWRz1DVPVsZgg9Yett5O+3MOvwo7iHgvUwbFz0mf/yPIjBkUbs4kxoQ==",
"requires": { "requires": {
"@types/node": ">= 8" "@types/node": ">= 8"
} }
@ -6777,9 +6720,9 @@
} }
}, },
"universal-user-agent": { "universal-user-agent": {
"version": "4.0.1", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
"integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
"requires": { "requires": {
"os-name": "^3.1.0" "os-name": "^3.1.0"
} }
@ -6958,9 +6901,9 @@
"dev": true "dev": true
}, },
"windows-release": { "windows-release": {
"version": "3.3.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
"integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
"requires": { "requires": {
"execa": "^1.0.0" "execa": "^1.0.0"
} }

View File

@ -28,7 +28,7 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.1.3", "@actions/core": "^1.1.3",
"@actions/exec": "^1.0.1", "@actions/exec": "^1.0.1",
"@actions/github": "^2.2.0", "@actions/github": "^2.0.2",
"@actions/io": "^1.0.1", "@actions/io": "^1.0.1",
"@actions/tool-cache": "^1.1.2", "@actions/tool-cache": "^1.1.2",
"uuid": "^3.3.3" "uuid": "^3.3.3"

View File

@ -7,12 +7,12 @@ import * as os from 'os'
import * as path from 'path' import * as path from 'path'
import * as regexpHelper from './regexp-helper' import * as regexpHelper from './regexp-helper'
import * as stateHelper from './state-helper' import * as stateHelper from './state-helper'
import * as urlHelper from './url-helper'
import {default as uuid} from 'uuid/v4' import {default as uuid} from 'uuid/v4'
import {IGitCommandManager} from './git-command-manager' import {IGitCommandManager} from './git-command-manager'
import {IGitSourceSettings} from './git-source-settings' import {IGitSourceSettings} from './git-source-settings'
const IS_WINDOWS = process.platform === 'win32' const IS_WINDOWS = process.platform === 'win32'
const HOSTNAME = 'github.com'
const SSH_COMMAND_KEY = 'core.sshCommand' const SSH_COMMAND_KEY = 'core.sshCommand'
export interface IGitAuthHelper { export interface IGitAuthHelper {
@ -33,15 +33,15 @@ export function createAuthHelper(
class GitAuthHelper { class GitAuthHelper {
private readonly git: IGitCommandManager private readonly git: IGitCommandManager
private readonly settings: IGitSourceSettings private readonly settings: IGitSourceSettings
private readonly tokenConfigKey: string private readonly tokenConfigKey: string = `http.https://${HOSTNAME}/.extraheader`
private readonly tokenConfigValue: string
private readonly tokenPlaceholderConfigValue: string private readonly tokenPlaceholderConfigValue: string
private readonly insteadOfKey: string private readonly insteadOfKey: string = `url.https://${HOSTNAME}/.insteadOf`
private readonly insteadOfValue: string private readonly insteadOfValue: string = `git@${HOSTNAME}:`
private sshCommand = '' private sshCommand = ''
private sshKeyPath = '' private sshKeyPath = ''
private sshKnownHostsPath = '' private sshKnownHostsPath = ''
private temporaryHomePath = '' private temporaryHomePath = ''
private tokenConfigValue: string
constructor( constructor(
gitCommandManager: IGitCommandManager, gitCommandManager: IGitCommandManager,
@ -51,8 +51,6 @@ class GitAuthHelper {
this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings) this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings)
// Token auth header // Token auth header
const serverUrl = urlHelper.getServerUrl()
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader` // "origin" is SCHEME://HOSTNAME[:PORT]
const basicCredential = Buffer.from( const basicCredential = Buffer.from(
`x-access-token:${this.settings.authToken}`, `x-access-token:${this.settings.authToken}`,
'utf8' 'utf8'
@ -60,10 +58,6 @@ class GitAuthHelper {
core.setSecret(basicCredential) core.setSecret(basicCredential)
this.tokenPlaceholderConfigValue = `AUTHORIZATION: basic ***` this.tokenPlaceholderConfigValue = `AUTHORIZATION: basic ***`
this.tokenConfigValue = `AUTHORIZATION: basic ${basicCredential}` this.tokenConfigValue = `AUTHORIZATION: basic ${basicCredential}`
// Instead of SSH URL
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
this.insteadOfValue = `git@${serverUrl.hostname}:`
} }
async configureAuth(): Promise<void> { async configureAuth(): Promise<void> {

View File

@ -33,6 +33,7 @@ export interface IGitCommandManager {
remoteAdd(remoteName: string, remoteUrl: string): Promise<void> remoteAdd(remoteName: string, remoteUrl: string): Promise<void>
removeEnvironmentVariable(name: string): void removeEnvironmentVariable(name: string): void
setEnvironmentVariable(name: string, value: string): void setEnvironmentVariable(name: string, value: string): void
setRemoteUrl(url: string): Promise<void>
submoduleForeach(command: string, recursive: boolean): Promise<string> submoduleForeach(command: string, recursive: boolean): Promise<string>
submoduleSync(recursive: boolean): Promise<void> submoduleSync(recursive: boolean): Promise<void>
submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void>
@ -40,7 +41,7 @@ export interface IGitCommandManager {
tryClean(): Promise<boolean> tryClean(): Promise<boolean>
tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean> tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
tryDisableAutomaticGarbageCollection(): Promise<boolean> tryDisableAutomaticGarbageCollection(): Promise<boolean>
tryGetFetchUrl(): Promise<string> tryGetRemoteUrl(): Promise<string>
tryReset(): Promise<boolean> tryReset(): Promise<boolean>
} }
@ -241,6 +242,10 @@ class GitCommandManager {
this.gitEnv[name] = value this.gitEnv[name] = value
} }
async setRemoteUrl(value: string): Promise<void> {
await this.config('git.remote.url', value)
}
async submoduleForeach(command: string, recursive: boolean): Promise<string> { async submoduleForeach(command: string, recursive: boolean): Promise<string> {
const args = ['submodule', 'foreach'] const args = ['submodule', 'foreach']
if (recursive) { if (recursive) {
@ -309,7 +314,7 @@ class GitCommandManager {
return output.exitCode === 0 return output.exitCode === 0
} }
async tryGetFetchUrl(): Promise<string> { async tryGetRemoteUrl(): Promise<string> {
const output = await this.execGit( const output = await this.execGit(
['config', '--local', '--get', 'remote.origin.url'], ['config', '--local', '--get', 'remote.origin.url'],
true true

View File

@ -10,15 +10,24 @@ import {IGitSourceSettings} from './git-source-settings'
export async function prepareExistingDirectory( export async function prepareExistingDirectory(
git: IGitCommandManager | undefined, git: IGitCommandManager | undefined,
repositoryPath: string, repositoryPath: string,
repositoryUrl: string, preferredRemoteUrl: string,
allowedRemoteUrls: string[],
clean: boolean clean: boolean
): Promise<void> { ): Promise<void> {
assert.ok(repositoryPath, 'Expected repositoryPath to be defined') assert.ok(repositoryPath, 'Expected repositoryPath to be defined')
assert.ok(repositoryUrl, 'Expected repositoryUrl to be defined') assert.ok(preferredRemoteUrl, 'Expected preferredRemoteUrl to be defined')
assert.ok(allowedRemoteUrls, 'Expected allowedRemoteUrls to be defined')
assert.ok(
allowedRemoteUrls.length,
'Expected allowedRemoteUrls to have at least one value'
)
// Indicates whether to delete the directory contents // Indicates whether to delete the directory contents
let remove = false let remove = false
// The remote URL
let remoteUrl: string
// Check whether using git or REST API // Check whether using git or REST API
if (!git) { if (!git) {
remove = true remove = true
@ -26,7 +35,7 @@ export async function prepareExistingDirectory(
// Fetch URL does not match // Fetch URL does not match
else if ( else if (
!fsHelper.directoryExistsSync(path.join(repositoryPath, '.git')) || !fsHelper.directoryExistsSync(path.join(repositoryPath, '.git')) ||
repositoryUrl !== (await git.tryGetFetchUrl()) allowedRemoteUrls.indexOf((remoteUrl = await git.tryGetRemoteUrl())) < 0
) { ) {
remove = true remove = true
} else { } else {
@ -82,6 +91,13 @@ export async function prepareExistingDirectory(
) )
} }
} }
// Update to the preferred remote URL
if (remoteUrl !== preferredRemoteUrl) {
core.startGroup('Updating the remote URL')
await git.setRemoteUrl(preferredRemoteUrl)
core.endGroup()
}
} catch (error) { } catch (error) {
core.warning( core.warning(
`Unable to prepare the existing repository. The repository will be recreated instead.` `Unable to prepare the existing repository. The repository will be recreated instead.`

View File

@ -8,16 +8,27 @@ import * as io from '@actions/io'
import * as path from 'path' import * as path from 'path'
import * as refHelper from './ref-helper' import * as refHelper from './ref-helper'
import * as stateHelper from './state-helper' import * as stateHelper from './state-helper'
import * as urlHelper from './url-helper'
import {IGitCommandManager} from './git-command-manager' import {IGitCommandManager} from './git-command-manager'
import {IGitSourceSettings} from './git-source-settings' import {IGitSourceSettings} from './git-source-settings'
const hostname = 'github.com'
export async function getSource(settings: IGitSourceSettings): Promise<void> { export async function getSource(settings: IGitSourceSettings): Promise<void> {
// Repository URL
core.info( core.info(
`Syncing repository: ${settings.repositoryOwner}/${settings.repositoryName}` `Syncing repository: ${settings.repositoryOwner}/${settings.repositoryName}`
) )
const repositoryUrl = urlHelper.getFetchUrl(settings)
// Remote URL
const httpsUrl = `https://${hostname}/${encodeURIComponent(
settings.repositoryOwner
)}/${encodeURIComponent(settings.repositoryName)}`
const sshUrl = `git@${hostname}:${encodeURIComponent(
settings.repositoryOwner
)}/${encodeURIComponent(settings.repositoryName)}.git`
// Always fetch the workflow repository using the token, not the SSH key
const initialRemoteUrl =
!settings.sshKey || settings.isWorkflowRepository ? httpsUrl : sshUrl
// Remove conflicting file path // Remove conflicting file path
if (fsHelper.fileExistsSync(settings.repositoryPath)) { if (fsHelper.fileExistsSync(settings.repositoryPath)) {
@ -41,7 +52,8 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
await gitDirectoryHelper.prepareExistingDirectory( await gitDirectoryHelper.prepareExistingDirectory(
git, git,
settings.repositoryPath, settings.repositoryPath,
repositoryUrl, initialRemoteUrl,
[httpsUrl, sshUrl],
settings.clean settings.clean
) )
} }
@ -82,7 +94,7 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
) { ) {
core.startGroup('Initializing the repository') core.startGroup('Initializing the repository')
await git.init() await git.init()
await git.remoteAdd('origin', repositoryUrl) await git.remoteAdd('origin', initialRemoteUrl)
core.endGroup() core.endGroup()
} }
@ -131,6 +143,13 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
core.endGroup() core.endGroup()
} }
// Fix URL when using SSH
if (settings.sshKey && initialRemoteUrl !== sshUrl) {
core.startGroup('Updating the remote URL')
await git.setRemoteUrl(sshUrl)
core.endGroup()
}
// Checkout // Checkout
core.startGroup('Checking out the ref') core.startGroup('Checking out the ref')
await git.checkout(checkoutInfo.ref, checkoutInfo.startPoint) await git.checkout(checkoutInfo.ref, checkoutInfo.startPoint)

View File

@ -14,6 +14,11 @@ export interface IGitSourceSettings {
*/ */
repositoryName: string repositoryName: string
/**
* Indicates whether the repository is main workflow repository
*/
isWorkflowRepository: boolean
/** /**
* The ref to fetch * The ref to fetch
*/ */

View File

@ -7,7 +7,7 @@ import * as path from 'path'
import * as retryHelper from './retry-helper' import * as retryHelper from './retry-helper'
import * as toolCache from '@actions/tool-cache' import * as toolCache from '@actions/tool-cache'
import {default as uuid} from 'uuid/v4' import {default as uuid} from 'uuid/v4'
import {Octokit} from '@octokit/rest' import {ReposGetArchiveLinkParams} from '@octokit/rest'
const IS_WINDOWS = process.platform === 'win32' const IS_WINDOWS = process.platform === 'win32'
@ -75,7 +75,7 @@ async function downloadArchive(
commit: string commit: string
): Promise<Buffer> { ): Promise<Buffer> {
const octokit = new github.GitHub(authToken) const octokit = new github.GitHub(authToken)
const params: Octokit.ReposGetArchiveLinkParams = { const params: ReposGetArchiveLinkParams = {
owner: owner, owner: owner,
repo: repo, repo: repo,
archive_format: IS_WINDOWS ? 'zipball' : 'tarball', archive_format: IS_WINDOWS ? 'zipball' : 'tarball',

View File

@ -4,6 +4,8 @@ import * as github from '@actions/github'
import * as path from 'path' import * as path from 'path'
import {IGitSourceSettings} from './git-source-settings' import {IGitSourceSettings} from './git-source-settings'
const hostname = 'github.com'
export function getInputs(): IGitSourceSettings { export function getInputs(): IGitSourceSettings {
const result = ({} as unknown) as IGitSourceSettings const result = ({} as unknown) as IGitSourceSettings
@ -51,14 +53,14 @@ export function getInputs(): IGitSourceSettings {
} }
// Workflow repository? // Workflow repository?
const isWorkflowRepository = result.isWorkflowRepository =
qualifiedRepository.toUpperCase() === qualifiedRepository.toUpperCase() ===
`${github.context.repo.owner}/${github.context.repo.repo}`.toUpperCase() `${github.context.repo.owner}/${github.context.repo.repo}`.toUpperCase()
// Source branch, source version // Source branch, source version
result.ref = core.getInput('ref') result.ref = core.getInput('ref')
if (!result.ref) { if (!result.ref) {
if (isWorkflowRepository) { if (result.isWorkflowRepository) {
result.ref = github.context.ref result.ref = github.context.ref
result.commit = github.context.sha result.commit = github.context.sha

View File

@ -1,29 +0,0 @@
import * as assert from 'assert'
import {IGitSourceSettings} from './git-source-settings'
import {URL} from 'url'
export function getFetchUrl(settings: IGitSourceSettings): string {
assert.ok(
settings.repositoryOwner,
'settings.repositoryOwner must be defined'
)
assert.ok(settings.repositoryName, 'settings.repositoryName must be defined')
const serviceUrl = getServerUrl()
const encodedOwner = encodeURIComponent(settings.repositoryOwner)
const encodedName = encodeURIComponent(settings.repositoryName)
if (settings.sshKey) {
return `git@${serviceUrl.hostname}:${encodedOwner}/${encodedName}.git`
}
// "origin" is SCHEME://HOSTNAME[:PORT]
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`
}
export function getServerUrl(): URL {
// todo: remove GITHUB_URL after support for GHES Alpha is no longer needed
return new URL(
process.env['GITHUB_SERVER_URL'] ||
process.env['GITHUB_URL'] ||
'https://github.com'
)
}