Skip to content

Commit 62a7a9d

Browse files
committed
feat: Add SSH key support as alternative to token authentication
Changes: - Add ssh-key input parameter - Make api-token optional when ssh-key is provided - Pass ssh-key to actions/checkout steps - Skip token validation when using SSH key - Skip git credential config when using SSH key - Validate that only one auth method is provided This allows the action to work with deploy keys, matching the functionality of the previous reusable workflow implementation. Refs: https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#push-using-ssh-deploy-keys
1 parent 9333c40 commit 62a7a9d

File tree

1 file changed

+71
-50
lines changed

1 file changed

+71
-50
lines changed

updater/action.yml

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@ inputs:
3434
required: false
3535
default: ''
3636
api-token:
37-
description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
38-
required: true
37+
description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}. Not required if ssh-key is provided.'
38+
required: false
39+
default: ''
40+
ssh-key:
41+
description: 'SSH private key for repository authentication. Alternative to api-token. Use for deploy key authentication.'
42+
required: false
43+
default: ''
3944
post-update-script:
4045
description: 'Optional script to run after successful dependency update. Can be a bash script (.sh) or PowerShell script (.ps1). The script will be executed in the caller-repo directory before PR creation.'
4146
required: false
@@ -117,71 +122,85 @@ runs:
117122
}
118123
Write-Output "✓ Post-update script path '${{ inputs.post-update-script }}' is valid"
119124
120-
- name: Validate GitHub token
125+
- name: Validate authentication
121126
shell: pwsh
122127
env:
123128
GH_TOKEN: ${{ inputs.api-token }}
129+
SSH_KEY: ${{ inputs.ssh-key }}
124130
run: |
125-
if ([string]::IsNullOrEmpty($env:GH_TOKEN)) {
126-
Write-Output "::error::GitHub token is empty. Please verify the token is passed correctly."
131+
$hasToken = -not [string]::IsNullOrEmpty($env:GH_TOKEN)
132+
$hasSshKey = -not [string]::IsNullOrEmpty($env:SSH_KEY)
133+
134+
if (-not $hasToken -and -not $hasSshKey) {
135+
Write-Output "::error::Either api-token or ssh-key must be provided for authentication."
127136
exit 1
128137
}
129138
130-
if ($env:GH_TOKEN -match '-----BEGIN') {
131-
Write-Output "::error::The provided token appears to be an SSH private key, not a GitHub token."
132-
Write-Output "::error::The api-token input requires a GitHub Personal Access Token (PAT) or GITHUB_TOKEN."
133-
Write-Output "::error::SSH keys should be configured separately using deploy keys or ssh-key inputs."
139+
if ($hasToken -and $hasSshKey) {
140+
Write-Output "::error::Both api-token and ssh-key were provided. Please provide only one."
134141
exit 1
135142
}
136143
137-
if ($env:GH_TOKEN -match '\s') {
138-
$tokenLength = $env:GH_TOKEN.Length
139-
$whitespaceMatch = [regex]::Match($env:GH_TOKEN, '\s')
140-
$position = $whitespaceMatch.Index
141-
$char = $whitespaceMatch.Value
142-
$charName = switch ($char) {
143-
"`n" { "newline (LF)" }
144-
"`r" { "carriage return (CR)" }
145-
"`t" { "tab" }
146-
" " { "space" }
147-
default { "whitespace character (code: $([int][char]$char))" }
148-
}
149-
Write-Output "::error::GitHub token contains whitespace at position $position of $tokenLength characters: $charName"
150-
Write-Output "::error::This suggests the token secret may be malformed. Check for extra newlines when setting the secret."
144+
if ($hasToken -and $env:GH_TOKEN -match '-----BEGIN') {
145+
Write-Output "::error::The api-token input appears to contain an SSH private key."
146+
Write-Output "::error::Please use the ssh-key input for SSH authentication instead of api-token."
151147
exit 1
152148
}
153149
154-
# Check token scopes (works for classic PATs only)
155-
$headers = curl -sS -I -H "Authorization: token $env:GH_TOKEN" https://api.github.com 2>&1
156-
$scopeLine = $headers | Select-String -Pattern '^x-oauth-scopes:' -CaseSensitive:$false
157-
if ($scopeLine) {
158-
$scopes = $scopeLine -replace '^x-oauth-scopes:\s*', '' -replace '\r', ''
159-
if ([string]::IsNullOrWhiteSpace($scopes)) {
160-
Write-Output "::warning::Token has no scopes. If using a fine-grained PAT, ensure it has Contents (write) and Pull Requests (write) permissions."
161-
} else {
162-
Write-Output "Token scopes: $scopes"
163-
if ($scopes -notmatch '\brepo\b' -and $scopes -notmatch '\bpublic_repo\b') {
164-
Write-Output "::warning::Token may be missing 'repo' or 'public_repo' scope. This may cause issues with private repositories."
150+
# Token-specific validation
151+
if ($hasToken) {
152+
if ($env:GH_TOKEN -match '\s') {
153+
$tokenLength = $env:GH_TOKEN.Length
154+
$whitespaceMatch = [regex]::Match($env:GH_TOKEN, '\s')
155+
$position = $whitespaceMatch.Index
156+
$char = $whitespaceMatch.Value
157+
$charName = switch ($char) {
158+
"`n" { "newline (LF)" }
159+
"`r" { "carriage return (CR)" }
160+
"`t" { "tab" }
161+
" " { "space" }
162+
default { "whitespace character (code: $([int][char]$char))" }
165163
}
164+
Write-Output "::error::GitHub token contains whitespace at position $position of $tokenLength characters: $charName"
165+
Write-Output "::error::This suggests the token secret may be malformed. Check for extra newlines when setting the secret."
166+
exit 1
166167
}
167-
} else {
168-
Write-Output "::notice::Could not detect token scopes (this is normal for fine-grained PATs). Ensure token has Contents (write) and Pull Requests (write) permissions."
169-
}
170168
171-
# Check token validity and access
172-
gh api repos/${{ github.repository }} --silent 2>&1 | Out-Null
173-
if ($LASTEXITCODE -ne 0) {
174-
Write-Output "::error::GitHub token validation failed. Please verify:"
175-
Write-Output " 1. Token is not empty or malformed"
176-
Write-Output " 2. Token has not expired"
177-
Write-Output " 3. Token has an expiration date set"
178-
Write-Output " 4. Token has 'repo' and 'workflow' scopes"
179-
exit 1
180-
}
169+
# Check token scopes (works for classic PATs only)
170+
$headers = curl -sS -I -H "Authorization: token $env:GH_TOKEN" https://api.github.com 2>&1
171+
$scopeLine = $headers | Select-String -Pattern '^x-oauth-scopes:' -CaseSensitive:$false
172+
if ($scopeLine) {
173+
$scopes = $scopeLine -replace '^x-oauth-scopes:\s*', '' -replace '\r', ''
174+
if ([string]::IsNullOrWhiteSpace($scopes)) {
175+
Write-Output "::warning::Token has no scopes. If using a fine-grained PAT, ensure it has Contents (write) and Pull Requests (write) permissions."
176+
} else {
177+
Write-Output "Token scopes: $scopes"
178+
if ($scopes -notmatch '\brepo\b' -and $scopes -notmatch '\bpublic_repo\b') {
179+
Write-Output "::warning::Token may be missing 'repo' or 'public_repo' scope. This may cause issues with private repositories."
180+
}
181+
}
182+
} else {
183+
Write-Output "::notice::Could not detect token scopes (this is normal for fine-grained PATs). Ensure token has Contents (write) and Pull Requests (write) permissions."
184+
}
181185
182-
Write-Output "✓ GitHub token is valid and has access to this repository"
186+
# Check token validity and access
187+
gh api repos/${{ github.repository }} --silent 2>&1 | Out-Null
188+
if ($LASTEXITCODE -ne 0) {
189+
Write-Output "::error::GitHub token validation failed. Please verify:"
190+
Write-Output " 1. Token is not empty or malformed"
191+
Write-Output " 2. Token has not expired"
192+
Write-Output " 3. Token has an expiration date set"
193+
Write-Output " 4. Token has 'repo' and 'workflow' scopes"
194+
exit 1
195+
}
196+
197+
Write-Output "✓ GitHub token is valid and has access to this repository"
198+
} else {
199+
Write-Output "✓ Using SSH key authentication"
200+
}
183201
184202
- name: Configure git credentials
203+
if: ${{ inputs.api-token != '' }}
185204
shell: pwsh
186205
env:
187206
GH_TOKEN: ${{ inputs.api-token }}
@@ -210,7 +229,8 @@ runs:
210229
- name: Checkout repository
211230
uses: actions/checkout@v4
212231
with:
213-
token: ${{ inputs.api-token }}
232+
token: ${{ inputs.api-token || github.token }}
233+
ssh-key: ${{ inputs.ssh-key }}
214234
ref: ${{ inputs.target-branch || github.ref }}
215235
path: caller-repo
216236

@@ -349,7 +369,8 @@ runs:
349369
if: ${{ ( steps.target.outputs.latestTag != steps.target.outputs.originalTag ) && ( steps.existing-pr.outputs.url == '') && ( steps.root.outputs.changed == 'false') }}
350370
uses: actions/checkout@v4
351371
with:
352-
token: ${{ inputs.api-token }}
372+
token: ${{ inputs.api-token || github.token }}
373+
ssh-key: ${{ inputs.ssh-key }}
353374
ref: ${{ inputs.target-branch || github.ref }}
354375
path: caller-repo
355376

0 commit comments

Comments
 (0)