Skip to content

Commit 770a9d7

Browse files
Sync eng/common directory with azure-sdk-tools for PR 14219 (Azure#48167)
* Add action to use github app via github workflows * Add note about environment * Use env variables to help prevent injection attacks * Remove note about outputs * Add test workflow for login-to-github --------- Co-authored-by: Wes Haggard <Wes.Haggard@microsoft.com>
1 parent 0e3c287 commit 770a9d7

2 files changed

Lines changed: 119 additions & 4 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Login to GitHub - Composite Action
2+
#
3+
# Mints a GitHub App installation access token using Azure Key Vault signing.
4+
# This action wraps eng/common/scripts/login-to-github.ps1 for use in GitHub
5+
# Actions workflows. The same script is used by Azure DevOps pipelines via
6+
# eng/common/pipelines/templates/steps/login-to-github.yml.
7+
#
8+
# IMPORTANT: This action requires Azure CLI to be pre-authenticated.
9+
# You must call azure/login BEFORE this action in your workflow.
10+
# This is because composite actions cannot call azure/login internally.
11+
#
12+
# Usage (single owner):
13+
# jobs:
14+
# my-job:
15+
# # An environment is required for OIDC (federated credential) login.
16+
# # Work with EngSys to configure the environment with the federated
17+
# # credential for the AzureSDKEngKeyVault Secrets service connection.
18+
# environment: AzureSDKEngKeyVault
19+
# permissions:
20+
# id-token: write # Required for azure/login OIDC
21+
# steps:
22+
# # Step 1: Authenticate to Azure (required before this action)
23+
# - uses: azure/login@v2
24+
# with:
25+
# client-id: 5786d1fb-187e-4ca9-9a81-ab89ea278986
26+
# tenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47
27+
# subscription-id: a18897a6-7e44-457d-9260-f2854c0aca42
28+
#
29+
# # Step 2: Mint GitHub App token
30+
# - uses: ./eng/common/actions/login-to-github
31+
# with:
32+
# token-owners: Azure
33+
#
34+
# # Step 3: Use the token (available as env var in all subsequent steps)
35+
# - run: gh pr list --repo Azure/azure-sdk-tools
36+
# env:
37+
# GH_TOKEN: ${{ env.GH_TOKEN }}
38+
#
39+
# Usage (multiple owners):
40+
# - uses: ./eng/common/actions/login-to-github
41+
# with:
42+
# token-owners: Azure,azure-sdk,MicrosoftDocs
43+
#
44+
# - run: gh pr list --repo Azure/azure-sdk-tools
45+
# env:
46+
# GH_TOKEN: ${{ env.GH_TOKEN_Azure }}
47+
#
48+
# Tokens are exported to GITHUB_ENV so all subsequent steps can reference
49+
# them as ${{ env.GH_TOKEN }} (single owner) or ${{ env.GH_TOKEN_<Owner> }}
50+
# (multiple owners). This matches the Azure DevOps behavior where tokens
51+
# are set as pipeline variables.
52+
53+
name: 'Login to GitHub'
54+
description: 'Mint a GitHub App installation token via Azure Key Vault signing'
55+
56+
inputs:
57+
token-owners:
58+
description: >
59+
Comma-separated list of GitHub organizations or users for which to
60+
obtain installation tokens (e.g. "Azure" or "Azure,azure-sdk").
61+
required: false
62+
default: 'Azure'
63+
variable-name-prefix:
64+
description: >
65+
Prefix for the exported variable name. With a single owner the
66+
variable is named exactly this (default GH_TOKEN). With multiple
67+
owners each variable is named <prefix>_<owner>.
68+
required: false
69+
default: 'GH_TOKEN'
70+
key-vault-name:
71+
description: 'Azure Key Vault name containing the signing key'
72+
required: false
73+
default: 'azuresdkengkeyvault'
74+
key-name:
75+
description: 'Name of the RSA key in Key Vault'
76+
required: false
77+
default: 'azure-sdk-automation'
78+
app-id:
79+
description: 'GitHub App numeric ID'
80+
required: false
81+
default: '1086291'
82+
83+
runs:
84+
using: 'composite'
85+
steps:
86+
- shell: pwsh
87+
env:
88+
INPUT_TOKEN_OWNERS: ${{ inputs.token-owners }}
89+
INPUT_VARIABLE_NAME_PREFIX: ${{ inputs.variable-name-prefix }}
90+
INPUT_KEY_VAULT_NAME: ${{ inputs.key-vault-name }}
91+
INPUT_KEY_NAME: ${{ inputs.key-name }}
92+
INPUT_APP_ID: ${{ inputs.app-id }}
93+
ACTION_PATH: ${{ github.action_path }}
94+
run: |
95+
$scriptPath = Join-Path $env:ACTION_PATH ".." ".." "scripts" "login-to-github.ps1"
96+
$owners = $env:INPUT_TOKEN_OWNERS -split ',' | ForEach-Object { $_.Trim() }
97+
& $scriptPath `
98+
-KeyVaultName $env:INPUT_KEY_VAULT_NAME `
99+
-KeyName $env:INPUT_KEY_NAME `
100+
-GitHubAppId $env:INPUT_APP_ID `
101+
-InstallationTokenOwners $owners `
102+
-VariableNamePrefix $env:INPUT_VARIABLE_NAME_PREFIX

eng/common/scripts/login-to-github.ps1

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
Mints a GitHub App installation access token using Azure Key Vault 'sign' (non-exportable key),
44
and logs in the GitHub CLI by setting GH_TOKEN.
55
6+
Works in both Azure DevOps pipelines and GitHub Actions workflows.
7+
Requires Azure CLI to be pre-authenticated (via AzureCLI@2 in ADO, or azure/login in GH Actions).
8+
69
.PARAMETER KeyVaultName
710
Name of the Azure Key Vault containing the non-exportable RSA key.
811
@@ -16,10 +19,13 @@
1619
List of GitHub organizations or users for which to obtain installation tokens.
1720
1821
.PARAMETER VariableNamePrefix
19-
Name of the ADO variable to set when -SetPipelineVariable is used (default: GH_TOKEN).
22+
Prefix for the exported variable name (default: GH_TOKEN).
23+
With a single owner, exports as GH_TOKEN. With multiple owners, exports as GH_TOKEN_<Owner>.
2024
2125
.OUTPUTS
22-
Writes minimal info to stdout. Token is placed in $env:GH_TOKEN if there is only one owner otherwise $env:GH_TOKEN_<Owner> for each owner.
26+
Sets environment variables in the current process and exports them to the CI system:
27+
- Azure DevOps: sets secret pipeline variables via ##vso logging commands
28+
- GitHub Actions: writes to GITHUB_ENV and masks the token
2329
#>
2430

2531
[CmdletBinding()]
@@ -98,7 +104,7 @@ function New-GitHubAppJwt {
98104
--digest $Base64Value | ConvertFrom-Json
99105

100106
if ($LASTEXITCODE -ne 0) {
101-
throw "Failed to sign JWT with Azure Key Vault. Error: $SignResult"
107+
throw "Failed to sign JWT with Azure Key Vault. Error: $($SignResultJson | ConvertTo-Json -Compress)"
102108
}
103109

104110
if (!$SignResultJson.signature) {
@@ -167,12 +173,19 @@ foreach ($InstallationTokenOwner in $InstallationTokenOwners)
167173
# Export for gh CLI & git
168174
Write-Host "$variableName has been set in the current process."
169175

170-
# Optionally set an Azure DevOps secret variable (so later tasks can reuse it)
176+
# Azure DevOps: set secret pipeline variable (so later tasks can reuse it)
171177
if ($null -ne $env:SYSTEM_TEAMPROJECTID) {
172178
Write-Host "##vso[task.setvariable variable=$variableName;issecret=true]$installationToken"
173179
Write-Host "Azure DevOps variable '$variableName' has been set (secret)."
174180
}
175181

182+
# GitHub Actions: mask the token and export to GITHUB_ENV
183+
if ($env:GITHUB_ACTIONS -eq 'true') {
184+
Write-Host "::add-mask::$installationToken"
185+
Add-Content -Path $env:GITHUB_ENV -Value "$variableName=$installationToken"
186+
Write-Host "GitHub Actions env variable '$variableName' has been exported."
187+
}
188+
176189
try {
177190
Write-Host "`n--- gh auth status ---"
178191
$gh_token_value_before = $env:GH_TOKEN

0 commit comments

Comments
 (0)