Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d5d72f348 | ||
|
|
1cb683f59c | ||
|
|
1faf939219 | ||
|
|
7e0f95e47a | ||
|
|
95951da3cb | ||
|
|
bdc764ff89 | ||
|
|
be5e352fa7 | ||
|
|
016e95b24b | ||
|
|
67a3a54916 | ||
|
|
ccbde630fa | ||
|
|
1d92969ea6 | ||
|
|
8098344c6b | ||
|
|
ff93395c55 | ||
|
|
f863e5cf3d | ||
|
|
7892dca28d | ||
|
|
2541b1294d | ||
|
|
0ffe6f9c55 |
38
.github/workflows/test.yml
vendored
38
.github/workflows/test.yml
vendored
@@ -205,3 +205,41 @@ jobs:
|
||||
path: basic
|
||||
- name: Verify basic
|
||||
run: __test__/verify-basic.sh --archive
|
||||
|
||||
test-git-container:
|
||||
runs-on: ubuntu-latest
|
||||
container: bitnami/git:latest
|
||||
steps:
|
||||
# Clone this repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: v3
|
||||
|
||||
# Basic checkout using git
|
||||
- name: Checkout basic
|
||||
uses: ./v3
|
||||
with:
|
||||
ref: test-data/v2/basic
|
||||
- name: Verify basic
|
||||
run: |
|
||||
if [ ! -f "./basic-file.txt" ]; then
|
||||
echo "Expected basic file does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify .git folder
|
||||
if [ ! -d "./.git" ]; then
|
||||
echo "Expected ./.git folder to exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify auth token
|
||||
git config --global --add safe.directory "*"
|
||||
git fetch --no-tags --depth=1 origin +refs/heads/main:refs/remotes/origin/main
|
||||
|
||||
# needed to make checkout post cleanup succeed
|
||||
- name: Fix Checkout v3
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: v3
|
||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -1,4 +1,21 @@
|
||||
__test__/_temp
|
||||
_temp/
|
||||
lib/
|
||||
node_modules/
|
||||
node_modules/
|
||||
/dist/fs-helper.d.ts
|
||||
/dist/git-auth-helper.d.ts
|
||||
/dist/git-command-manager.d.ts
|
||||
/dist/git-directory-helper.d.ts
|
||||
/dist/git-source-provider.d.ts
|
||||
/dist/git-source-settings.d.ts
|
||||
/dist/git-version.d.ts
|
||||
/dist/github-api-helper.d.ts
|
||||
/dist/input-helper.d.ts
|
||||
/dist/main.d.ts
|
||||
/dist/misc/generate-docs.d.ts
|
||||
/dist/ref-helper.d.ts
|
||||
/dist/regexp-helper.d.ts
|
||||
/dist/retry-helper.d.ts
|
||||
/dist/state-helper.d.ts
|
||||
/dist/url-helper.d.ts
|
||||
/dist/workflow-context-helper.d.ts
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## v3.0.2
|
||||
- [Add input `set-safe-directory`](https://github.com/actions/checkout/pull/770)
|
||||
|
||||
## v3.0.1
|
||||
- [Fixed an issue where checkout failed to run in container jobs due to the new git setting `safe.directory`](https://github.com/actions/checkout/pull/762)
|
||||
- [Bumped various npm package versions](https://github.com/actions/checkout/pull/744)
|
||||
|
||||
25
README.md
25
README.md
@@ -2,26 +2,22 @@
|
||||
<a href="https://github.com/actions/checkout"><img alt="GitHub Actions status" src="https://github.com/actions/checkout/workflows/test-local/badge.svg"></a>
|
||||
</p>
|
||||
|
||||
# Checkout V3
|
||||
|
||||
This action checks-out your repository under `$GITHUB_WORKSPACE`, so your workflow can access it.
|
||||
|
||||
Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set `fetch-depth: 0` to fetch all history for all branches and tags. Refer [here](https://help.github.com/en/articles/events-that-trigger-workflows) to learn which commit `$GITHUB_SHA` points to for different events.
|
||||
|
||||
The auth token is persisted in the local git config. This enables your scripts to run authenticated git commands. The token is removed during post-job cleanup. Set `persist-credentials: false` to opt-out.
|
||||
|
||||
When Git 2.18 or higher is not in your PATH, falls back to the REST API to download the files.
|
||||
This is a fork of https://github.com/actions/checkout@v3
|
||||
|
||||
# What's new
|
||||
|
||||
- Updated to the node16 runtime by default
|
||||
- This requires a minimum [Actions Runner](https://github.com/actions/runner/releases/tag/v2.285.0) version of v2.285.0 to run, which is by default available in GHES 3.4 or later.
|
||||
With this action it is possible to check out a repository located on a Gitea instance with subdirectories.
|
||||
|
||||
Changed
|
||||
`https://<domain>[:<port>]/<name>/<repository>`
|
||||
to
|
||||
`https://<domain>[:<port>]/<subpath>/<name>/<repository>`
|
||||
|
||||
# Usage
|
||||
|
||||
<!-- start usage -->
|
||||
```yaml
|
||||
- uses: actions/checkout@v3
|
||||
- uses: https://gitea.com/ScMi1/checkout@v1
|
||||
with:
|
||||
# Repository name with owner. For example, actions/checkout
|
||||
# Default: ${{ github.repository }}
|
||||
@@ -92,6 +88,11 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
|
||||
#
|
||||
# Default: false
|
||||
submodules: ''
|
||||
|
||||
# Add repository path as safe.directory for Git global config by running `git
|
||||
# config --global --add safe.directory <path>`
|
||||
# Default: true
|
||||
set-safe-directory: ''
|
||||
```
|
||||
<!-- end usage -->
|
||||
|
||||
|
||||
@@ -777,7 +777,8 @@ async function setup(testName: string): Promise<void> {
|
||||
sshKey: sshPath ? 'some ssh private key' : '',
|
||||
sshKnownHosts: '',
|
||||
sshStrict: true,
|
||||
workflowOrganizationId: 123456
|
||||
workflowOrganizationId: 123456,
|
||||
setSafeDirectory: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ describe('input-helper tests', () => {
|
||||
expect(settings.repositoryName).toBe('some-repo')
|
||||
expect(settings.repositoryOwner).toBe('some-owner')
|
||||
expect(settings.repositoryPath).toBe(gitHubWorkspace)
|
||||
expect(settings.setSafeDirectory).toBe(true)
|
||||
})
|
||||
|
||||
it('qualifies ref', async () => {
|
||||
|
||||
@@ -68,6 +68,9 @@ inputs:
|
||||
When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are
|
||||
converted to HTTPS.
|
||||
default: false
|
||||
set-safe-directory:
|
||||
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
|
||||
default: true
|
||||
runs:
|
||||
using: node16
|
||||
main: dist/index.js
|
||||
|
||||
33288
dist/index.js
vendored
33288
dist/index.js
vendored
File diff suppressed because one or more lines are too long
32849
package-lock.json
generated
32849
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@ export interface IGitAuthHelper {
|
||||
configureAuth(): Promise<void>
|
||||
configureGlobalAuth(): Promise<void>
|
||||
configureSubmoduleAuth(): Promise<void>
|
||||
configureTempGlobalConfig(repositoryPath?: string): Promise<string>
|
||||
configureTempGlobalConfig(): Promise<string>
|
||||
removeAuth(): Promise<void>
|
||||
removeGlobalConfig(): Promise<void>
|
||||
}
|
||||
@@ -53,7 +53,7 @@ class GitAuthHelper {
|
||||
|
||||
// Token auth header
|
||||
const serverUrl = urlHelper.getServerUrl()
|
||||
this.tokenConfigKey = `http.${serverUrl.origin}/.extraheader` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||
this.tokenConfigKey = `http.${serverUrl.origin}${serverUrl.pathname}/.extraheader` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||
const basicCredential = Buffer.from(
|
||||
`x-access-token:${this.settings.authToken}`,
|
||||
'utf8'
|
||||
@@ -63,7 +63,7 @@ class GitAuthHelper {
|
||||
this.tokenConfigValue = `AUTHORIZATION: basic ${basicCredential}`
|
||||
|
||||
// Instead of SSH URL
|
||||
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||
this.insteadOfKey = `url.${serverUrl.origin}${serverUrl.pathname}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
|
||||
this.insteadOfValues.push(`git@${serverUrl.hostname}:`)
|
||||
if (this.settings.workflowOrganizationId) {
|
||||
this.insteadOfValues.push(
|
||||
@@ -81,7 +81,7 @@ class GitAuthHelper {
|
||||
await this.configureToken()
|
||||
}
|
||||
|
||||
async configureTempGlobalConfig(repositoryPath?: string): Promise<string> {
|
||||
async configureTempGlobalConfig(): Promise<string> {
|
||||
// Already setup global config
|
||||
if (this.temporaryHomePath?.length > 0) {
|
||||
return path.join(this.temporaryHomePath, '.gitconfig')
|
||||
@@ -121,21 +121,6 @@ class GitAuthHelper {
|
||||
)
|
||||
this.git.setEnvironmentVariable('HOME', this.temporaryHomePath)
|
||||
|
||||
// Setup the workspace as a safe directory, so if we pass this into a container job with a different user it doesn't fail
|
||||
// Otherwise all git commands we run in a container fail
|
||||
core.info(
|
||||
`Adding working directory to the temporary git global config as a safe directory`
|
||||
)
|
||||
await this.git
|
||||
.config(
|
||||
'safe.directory',
|
||||
repositoryPath ?? this.settings.repositoryPath,
|
||||
true,
|
||||
true
|
||||
)
|
||||
.catch(error => {
|
||||
core.info(`Failed to initialize safe directory with error: ${error}`)
|
||||
})
|
||||
return newGitConfigPath
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ class GitCommandManager {
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
await this.execGit(['config', '--global', 'init.defaultBranch', 'main'])
|
||||
await this.execGit(['init', this.workingDirectory])
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,24 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
|
||||
try {
|
||||
if (git) {
|
||||
authHelper = gitAuthHelper.createAuthHelper(git, settings)
|
||||
await authHelper.configureTempGlobalConfig()
|
||||
if (settings.setSafeDirectory) {
|
||||
// Setup the repository path as a safe directory, so if we pass this into a container job with a different user it doesn't fail
|
||||
// Otherwise all git commands we run in a container fail
|
||||
await authHelper.configureTempGlobalConfig()
|
||||
core.info(
|
||||
`Adding repository directory to the temporary git global config as a safe directory`
|
||||
)
|
||||
|
||||
await git
|
||||
.config('safe.directory', settings.repositoryPath, true, true)
|
||||
.catch(error => {
|
||||
core.info(
|
||||
`Failed to initialize safe directory with error: ${error}`
|
||||
)
|
||||
})
|
||||
|
||||
stateHelper.setSafeDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare existing directory, otherwise recreate
|
||||
@@ -249,7 +266,21 @@ export async function cleanup(repositoryPath: string): Promise<void> {
|
||||
// Remove auth
|
||||
const authHelper = gitAuthHelper.createAuthHelper(git)
|
||||
try {
|
||||
await authHelper.configureTempGlobalConfig(repositoryPath)
|
||||
if (stateHelper.PostSetSafeDirectory) {
|
||||
// Setup the repository path as a safe directory, so if we pass this into a container job with a different user it doesn't fail
|
||||
// Otherwise all git commands we run in a container fail
|
||||
await authHelper.configureTempGlobalConfig()
|
||||
core.info(
|
||||
`Adding repository directory to the temporary git global config as a safe directory`
|
||||
)
|
||||
|
||||
await git
|
||||
.config('safe.directory', repositoryPath, true, true)
|
||||
.catch(error => {
|
||||
core.info(`Failed to initialize safe directory with error: ${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
await authHelper.removeAuth()
|
||||
} finally {
|
||||
await authHelper.removeGlobalConfig()
|
||||
|
||||
@@ -78,4 +78,9 @@ export interface IGitSourceSettings {
|
||||
* Organization ID for the currently running workflow (used for auth settings)
|
||||
*/
|
||||
workflowOrganizationId: number | undefined
|
||||
|
||||
/**
|
||||
* Indicates whether to add repositoryPath as safe.directory in git global config
|
||||
*/
|
||||
setSafeDirectory: boolean
|
||||
}
|
||||
|
||||
@@ -122,5 +122,8 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||
// Workflow organization ID
|
||||
result.workflowOrganizationId = await workflowContextHelper.getOrganizationId()
|
||||
|
||||
// Set safe.directory in git global config.
|
||||
result.setSafeDirectory =
|
||||
(core.getInput('set-safe-directory') || 'true').toUpperCase() === 'TRUE'
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@ export const IsPost = !!process.env['STATE_isPost']
|
||||
export const RepositoryPath =
|
||||
(process.env['STATE_repositoryPath'] as string) || ''
|
||||
|
||||
/**
|
||||
* The set-safe-directory for the POST action. The value is set if input: 'safe-directory' is set during the MAIN action.
|
||||
*/
|
||||
export const PostSetSafeDirectory =
|
||||
(process.env['STATE_setSafeDirectory'] as string) === 'true'
|
||||
|
||||
/**
|
||||
* The SSH key path for the POST action. The value is empty during the MAIN action.
|
||||
*/
|
||||
@@ -51,6 +57,13 @@ export function setSshKnownHostsPath(sshKnownHostsPath: string) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the sef-safe-directory input so the POST action can retrieve the value.
|
||||
*/
|
||||
export function setSafeDirectory() {
|
||||
coreCommand.issueCommand('save-state', {name: 'setSafeDirectory'}, 'true')
|
||||
}
|
||||
|
||||
// Publish a variable so that when the POST action runs, it can determine it should run the cleanup logic.
|
||||
// This is necessary since we don't have a separate entry point.
|
||||
if (!IsPost) {
|
||||
|
||||
@@ -16,7 +16,7 @@ export function getFetchUrl(settings: IGitSourceSettings): string {
|
||||
}
|
||||
|
||||
// "origin" is SCHEME://HOSTNAME[:PORT]
|
||||
return `${serviceUrl.origin}/${encodedOwner}/${encodedName}`
|
||||
return `${serviceUrl.origin}${serviceUrl.pathname}/${encodedOwner}/${encodedName}`
|
||||
}
|
||||
|
||||
export function getServerUrl(): URL {
|
||||
|
||||
Reference in New Issue
Block a user