Sitelet https://github.com/taiki-e/checkout-action/commit/1544de8ca9377574def6cb4b338722247ce63df0
Skip to content

Commit 1544de8

Browse files
committed
Support checking out private repository
1 parent 29fe070 commit 1544de8

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

‎README.md‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,24 @@ The features supported as of v1.0.0 are purely based on my use cases within publ
2222
- uses: taiki-e/checkout-action@v1
2323
```
2424
25-
Almost equivalent to (for public repositories):
25+
Almost equivalent to:
26+
27+
```yaml
28+
- uses: actions/checkout@v6
29+
with:
30+
persist-credentials: false
31+
token: ''
32+
```
33+
34+
To use this action in private repositories, explicitly set `token` input option:
35+
36+
```yaml
37+
- uses: taiki-e/checkout-action@v1
38+
with:
39+
token: ${{ secrets.GITHUB_TOKEN }}
40+
```
41+
42+
Almost equivalent to:
2643

2744
```yaml
2845
- uses: actions/checkout@v6
@@ -36,6 +53,8 @@ As of 2024-03-08, the latest version of [actions/checkout] that uses node20 [doe
3653

3754
Also, in `actions/*` actions, each update of the Node.js used increments the major version (it is the correct behavior for compatibility although), so workflows that use it require maintenance on a regular basis. (Unless you have fully automated dependency updates.)
3855

56+
This action does not write credentials to files even if `token` input option is set, but actions/checkout (as of 6.0.2) [writes credentials to disk as plaintext even when `persist-credentials` is set to `false`, when git is available](https://github.com/taiki-e/checkout-action/pull/16). Therefore, this action is considered more secure than actions/checkout not only by default but also when `persist-credentials` is set to `false`.
57+
3958
## Security
4059

4160
The `@v<major>` tags are updated with each release. If you want to enhance workflow stability and security against supply chain attacks, consider using the `@v<major>.<minor>.<patch>` tag or their hash to pin the version and regularly updating with dependency cooldown. Since all releases are immutable, pinning the version in either way should have the same effect.

‎action.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
name: checkout-action
22
description: GitHub Action for checking out a repository. (Simplified actions/checkout alternative that does not depend on Node.js.)
33

4+
inputs:
5+
token:
6+
description: GitHub token for checking out a repository.
7+
required: false
8+
49
# Note:
510
# - inputs.* should be manually mapped to INPUT_* due to https://github.com/actions/runner/issues/665
611
# - Use GITHUB_*/RUNNER_* instead of github.*/runner.* due to https://github.com/actions/runner/issues/2185
@@ -41,6 +46,9 @@ runs:
4146
fi
4247
bash --noprofile --norc "${GITHUB_ACTION_PATH:?}/main.sh"
4348
shell: sh
49+
env:
50+
# NB: Sync with Windows case.
51+
INPUT_TOKEN: ${{ inputs.token }}
4452
if: runner.os != 'Windows'
4553
# Use pwsh and retry on bash startup failure to work around windows-11-arm runner bug:
4654
# https://github.com/actions/partner-runner-images/issues/169
@@ -64,4 +72,7 @@ runs:
6472
Write-Output "::error::installation failed due to bash startup failure (<https://github.com/actions/partner-runner-images/issues/169>); this maybe resolved by re-running job"
6573
exit 1
6674
shell: pwsh
75+
env:
76+
# NB: Sync with non-Windows case.
77+
INPUT_TOKEN: ${{ inputs.token }}
6778
if: runner.os == 'Windows'

‎main.sh‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ sys_install() {
9595
esac
9696
}
9797

98+
if [[ $# -gt 0 ]]; then
99+
bail "invalid argument '$1'"
100+
fi
101+
102+
token="${INPUT_TOKEN}"
103+
# This prevents tokens from being exposed to subprocesses via environment variables.
104+
unset INPUT_TOKEN
105+
98106
base_distro=''
99107
case "$(uname -s)" in
100108
Linux)
@@ -217,6 +225,29 @@ g git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
217225

218226
g git config --local gc.auto 0
219227

228+
if [[ -n "${token}" ]]; then
229+
prev_credential_helper=$(git config get --local credential.helper || true)
230+
if [[ -n "${prev_credential_helper}" ]]; then
231+
bail "credential helper is already set (${prev_credential_helper}); this should not happen in clean checkout"
232+
fi
233+
protocol="${GITHUB_SERVER_URL%%://*}"
234+
hostname="${GITHUB_SERVER_URL#*://}"
235+
hostname="${hostname%%/*}"
236+
# Sanitize inputs and runner-provided environment variables for here-doc.
237+
if [[ "${protocol}" == *$'\n'* ]] || [[ "${hostname}" == *$'\n'* ]] || [[ "${GITHUB_ACTOR}" == *$'\n'* ]] || [[ "${token}" == *$'\n'* ]]; then
238+
bail "GITHUB_SERVER_URL and GITHUB_ACTOR and 'token' input option must not contain newline"
239+
fi
240+
g git config --local credential.helper cache
241+
git credential approve <<EOF
242+
protocol=${protocol}
243+
host=${hostname}
244+
username=${GITHUB_ACTOR}
245+
password=${token}
246+
EOF
247+
# Remove credential helper config on exit.
248+
trap -- 'g git credential-cache exit; g git config --local --unset credential.helper || true' EXIT
249+
fi
250+
220251
if [[ "${GITHUB_REF}" == "refs/heads/"* ]]; then
221252
branch="${GITHUB_REF#refs/heads/}"
222253
remote_ref="refs/remotes/origin/${branch}"

0 commit comments

Comments
 (0)