Skip to content

Commit 40f0576

Browse files
authored
Add automatic Azure DevOps CLI authentication via AZURE_DEVOPS_EXT_PAT (#1)
* Add devops login token for easier az cli devops use * Address PR feedback: fix test isolation and documentation wording - Add mkdir -p ${HOME}/bin in test cases that were missing it to ensure each test is independent and not order-dependent - Change 'PAT' to 'access token' in NOTES.md to accurately reflect what ado-auth-helper returns
1 parent 8fe9488 commit 40f0576

3 files changed

Lines changed: 121 additions & 0 deletions

File tree

src/artifacts-helper/NOTES.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ The `az` shim specifically intercepts `az account get-access-token` requests and
66
to acquire tokens via the ado-codespaces-auth VS Code extension. This enables `DefaultAzureCredential`'s
77
`AzureCliCredential` to work in Codespaces without requiring `az login`.
88

9+
## Azure DevOps CLI Integration
10+
11+
For `az devops` commands, the shim automatically sets the `AZURE_DEVOPS_EXT_PAT` environment variable
12+
using the `ado-auth-helper` when falling through to the real Azure CLI. This enables `az devops`
13+
commands to authenticate without requiring manual `az devops login` or setting the token manually.
14+
15+
The shim will:
16+
1. Wait for `ado-auth-helper` to become available (up to 3 minutes, configurable via `MAX_WAIT`)
17+
2. Call `ado-auth-helper get-access-token` to retrieve an access token used by the Azure DevOps CLI extension
18+
3. Export `AZURE_DEVOPS_EXT_PAT` before executing the real `az` command
19+
20+
If `AZURE_DEVOPS_EXT_PAT` is already set, the shim will not overwrite it. If `ado-auth-helper` is not
21+
available after the timeout, the command will still execute (but may fail to authenticate to Azure DevOps).
22+
923
For `npm`, `yarn`, `rush`, and `pnpm` this requires that your `~/.npmrc` file is configured to use the ${ARTIFACTS_ACCESSTOKEN}
1024
environment variable for the `authToken`. A helper script has been added that you can use to write your `~/.npmrc`
1125
file during your setup process, though there are many ways you could accomplish this. To use the script, run it like

src/artifacts-helper/scripts/az

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,43 @@ EOF
100100
fi
101101

102102
# Fall through to real az CLI for all other commands
103+
# Before fallthrough, set AZURE_DEVOPS_EXT_PAT if ado-auth-helper is available
104+
# This enables 'az devops' commands to authenticate automatically
105+
if [[ -z "${AZURE_DEVOPS_EXT_PAT}" ]]; then
106+
MAX_WAIT=${MAX_WAIT:-180}
107+
ELAPSED=0
108+
109+
if [[ "${ARTIFACTS_HELPER_VERBOSE}" == "true" ]]; then
110+
echo "::step::Waiting for AzDO Authentication Helper for az devops..." >&2
111+
fi
112+
113+
while [[ $ELAPSED -lt $MAX_WAIT ]]; do
114+
if [[ -f "${HOME}/ado-auth-helper" ]]; then
115+
AZURE_DEVOPS_EXT_PAT=$("${HOME}/ado-auth-helper" get-access-token 2>/dev/null)
116+
if [[ $? -eq 0 && -n "$AZURE_DEVOPS_EXT_PAT" ]]; then
117+
export AZURE_DEVOPS_EXT_PAT
118+
if [[ "${ARTIFACTS_HELPER_VERBOSE}" == "true" ]]; then
119+
echo "::step::✓ AZURE_DEVOPS_EXT_PAT set successfully" >&2
120+
fi
121+
break
122+
fi
123+
fi
124+
sleep 2
125+
ELAPSED=$((ELAPSED + 2))
126+
127+
# Progress indicator every 20 seconds (verbose only)
128+
if [[ "${ARTIFACTS_HELPER_VERBOSE}" == "true" && $((ELAPSED % 20)) -eq 0 ]]; then
129+
echo " Still waiting... (${ELAPSED}s elapsed)" >&2
130+
fi
131+
done
132+
133+
# Always show timeout warnings regardless of verbose setting, as this indicates a potential issue
134+
if [[ $ELAPSED -ge $MAX_WAIT ]]; then
135+
echo "::warning::AzDO Authentication Helper not found after ${MAX_WAIT} seconds" >&2
136+
echo "Continuing without AZURE_DEVOPS_EXT_PAT..." >&2
137+
fi
138+
fi
139+
103140
AZ_EXE="$(resolve_shim)"
104141
if [[ -n "$AZ_EXE" ]]; then
105142
exec "${AZ_EXE}" "$@"

test/artifacts-helper/test_az_shim.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,76 @@ check "az shim bypasses interception in GitHub Actions" bash -c '
7474
echo "$output" | grep -qv "test-token-12345" && echo "SUCCESS" || echo "FAILED"
7575
' | grep -q "SUCCESS"
7676

77+
# Test AZURE_DEVOPS_EXT_PAT integration with ado-auth-helper
78+
check "az shim sets AZURE_DEVOPS_EXT_PAT when ado-auth-helper exists" bash -c '
79+
export HOME='"$TEST_HOME"'
80+
export MAX_WAIT=2 # Short timeout for testing
81+
# Create a mock ado-auth-helper
82+
cat > "${HOME}/ado-auth-helper" << '\''HELPER'\''
83+
#!/bin/bash
84+
echo "ado-test-pat-token"
85+
HELPER
86+
chmod +x "${HOME}/ado-auth-helper"
87+
88+
# Create a mock az that echoes the env var
89+
mkdir -p "${HOME}/bin"
90+
cat > "${HOME}/bin/az" << '\''MOCKAZ'\''
91+
#!/bin/bash
92+
echo "PAT=${AZURE_DEVOPS_EXT_PAT}"
93+
MOCKAZ
94+
chmod +x "${HOME}/bin/az"
95+
export PATH="${HOME}/bin:$PATH"
96+
97+
# Call the shim with a non-token command
98+
output=$(/usr/local/share/codespace-shims/az devops --help 2>&1)
99+
echo "$output" | grep -q "PAT=ado-test-pat-token" && echo "SUCCESS" || echo "FAILED: $output"
100+
' | grep -q "SUCCESS"
101+
102+
# Test that existing AZURE_DEVOPS_EXT_PAT is not overwritten
103+
check "az shim does not overwrite existing AZURE_DEVOPS_EXT_PAT" bash -c '
104+
export HOME='"$TEST_HOME"'
105+
export MAX_WAIT=2
106+
export AZURE_DEVOPS_EXT_PAT="existing-pat-value"
107+
# Create mock ado-auth-helper that would return different value
108+
cat > "${HOME}/ado-auth-helper" << '\''HELPER'\''
109+
#!/bin/bash
110+
echo "new-pat-token"
111+
HELPER
112+
chmod +x "${HOME}/ado-auth-helper"
113+
114+
# Create mock az
115+
mkdir -p "${HOME}/bin"
116+
cat > "${HOME}/bin/az" << '\''MOCKAZ'\''
117+
#!/bin/bash
118+
echo "PAT=${AZURE_DEVOPS_EXT_PAT}"
119+
MOCKAZ
120+
chmod +x "${HOME}/bin/az"
121+
export PATH="${HOME}/bin:$PATH"
122+
123+
output=$(/usr/local/share/codespace-shims/az devops --help 2>&1)
124+
# Should still have original value
125+
echo "$output" | grep -q "PAT=existing-pat-value" && echo "SUCCESS" || echo "FAILED: $output"
126+
' | grep -q "SUCCESS"
127+
128+
# Test that missing ado-auth-helper still allows fallthrough
129+
check "az shim falls through without ado-auth-helper" bash -c '
130+
export HOME='"$TEST_HOME"'
131+
export MAX_WAIT=2 # Short timeout
132+
rm -f "${HOME}/ado-auth-helper"
133+
134+
# Create mock az
135+
mkdir -p "${HOME}/bin"
136+
cat > "${HOME}/bin/az" << '\''MOCKAZ'\''
137+
#!/bin/bash
138+
echo "FALLTHROUGH_OK"
139+
MOCKAZ
140+
chmod +x "${HOME}/bin/az"
141+
export PATH="${HOME}/bin:$PATH"
142+
143+
output=$(/usr/local/share/codespace-shims/az version 2>&1)
144+
echo "$output" | grep -q "FALLTHROUGH_OK" && echo "SUCCESS" || echo "FAILED: $output"
145+
' | grep -q "SUCCESS"
146+
77147
# Cleanup
78148
rm -rf "$TEST_HOME"
79149

0 commit comments

Comments
 (0)