-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Fix #47614 [BUG] AzureCliCredential fails in non-interactive environments du… #47615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…e to hardcoded /bin/sh PATH resolution Add ensureCliPath method to set Azure CLI installation paths in the process environment.
|
Thank you for your contribution @hydraxman! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a bug where AzureCliCredential and AzureDeveloperCliCredential fail in non-interactive environments due to the Azure CLI not being found in the PATH. The fix adds an ensureCliPath method that prepends common Homebrew installation directories (/usr/local/bin and /opt/homebrew/bin) to the PATH environment variable when executing CLI commands on non-Windows platforms.
Key changes:
- Added
ensureCliPathmethod to ensure Azure CLI installation paths are available in the process environment - Applied the path fix to both
getTokenFromAzureCLIAuthenticationandgetTokenFromAzureDeveloperCLIAuthenticationmethods
| private void ensureCliPath(ProcessBuilder builder) { | ||
| if (!isWindowsPlatform()) { | ||
| Map<String, String> env = builder.environment(); | ||
| String path = env.getOrDefault("PATH", ""); | ||
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | ||
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); | ||
| } | ||
| } | ||
| } |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new ensureCliPath method lacks test coverage. There are no tests validating that:
- The PATH is correctly modified when the directories are not present
- The PATH is not modified when the directories are already present
- The method correctly handles edge cases like empty PATH or PATH with trailing colons
- The method is correctly invoked for both Azure CLI and Azure Developer CLI commands
Since the existing test file AzureCliCredentialTest.java has comprehensive test coverage for other behaviors, tests should be added for this new functionality to maintain the same quality standard.
| * Ensures that the process environment PATH contains common Azure CLI installation directories | ||
| * when invoking CLI commands in non-interactive environments. | ||
| * Azure CLI is commonly installed via Homebrew on macOS and Linux, which places the `az` executable | ||
| * under locations such as {@code /usr/local/bin} (Intel) or {@code /opt/homebrew/bin} (Apple Silicon). | ||
| */ |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JavaDoc comment uses an asterisk (*) at the start of line 684 instead of the standard JavaDoc format with proper indentation and asterisk alignment. The opening /** should be on its own line, and each subsequent line should start with a space, asterisk, and space pattern for consistency with JavaDoc conventions used elsewhere in the codebase.
| * Ensures that the process environment PATH contains common Azure CLI installation directories | |
| * when invoking CLI commands in non-interactive environments. | |
| * Azure CLI is commonly installed via Homebrew on macOS and Linux, which places the `az` executable | |
| * under locations such as {@code /usr/local/bin} (Intel) or {@code /opt/homebrew/bin} (Apple Silicon). | |
| */ | |
| * Ensures that the process environment PATH contains common Azure CLI installation directories | |
| * when invoking CLI commands in non-interactive environments. | |
| * Azure CLI is commonly installed via Homebrew on macOS and Linux, which places the `az` executable | |
| * under locations such as {@code /usr/local/bin} (Intel) or {@code /opt/homebrew/bin} (Apple Silicon). | |
| */ |
| String path = env.getOrDefault("PATH", ""); | ||
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | ||
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When constructing the new PATH value, if the original PATH is empty or not set, this will result in PATH being set to /usr/local/bin:/opt/homebrew/bin: with a trailing colon. While this is typically handled gracefully by most systems (treating the empty entry as the current directory), it's not a best practice and could lead to subtle security issues. Consider handling the empty PATH case explicitly to avoid the trailing colon.
| String path = env.getOrDefault("PATH", ""); | |
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | |
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); | |
| String existingPath = env.get("PATH"); | |
| String pathToCheck = existingPath == null ? "" : existingPath; | |
| if (!pathToCheck.contains("/usr/local/bin") && !pathToCheck.contains("/opt/homebrew/bin")) { | |
| String additionalPaths = "/usr/local/bin:/opt/homebrew/bin"; | |
| if (existingPath == null || existingPath.isEmpty()) { | |
| env.put("PATH", additionalPaths); | |
| } else { | |
| env.put("PATH", additionalPaths + ":" + existingPath); | |
| } |
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | ||
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); | ||
| } |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current logic using contains() to check if paths are already in the PATH variable is fragile and can lead to false positives. For example, if PATH contains /home/user/opt/homebrew/bin/tool, the check path.contains("/opt/homebrew/bin") would incorrectly return true even though /opt/homebrew/bin is not actually in the PATH as a separate directory entry. This could prevent the fix from working in such cases.
Consider splitting the PATH by the path separator (: on Unix systems) and checking if the specific directories exist as individual entries in the resulting array.
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | |
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); | |
| } | |
| boolean hasUsrLocalBin = false; | |
| boolean hasOptHomebrewBin = false; | |
| if (!path.isEmpty()) { | |
| String[] entries = path.split(Pattern.quote(java.io.File.pathSeparator)); | |
| for (String entry : entries) { | |
| if ("/usr/local/bin".equals(entry)) { | |
| hasUsrLocalBin = true; | |
| } else if ("/opt/homebrew/bin".equals(entry)) { | |
| hasOptHomebrewBin = true; | |
| } | |
| if (hasUsrLocalBin && hasOptHomebrewBin) { | |
| break; | |
| } | |
| } | |
| } | |
| // Preserve original behavior: only prepend both directories when neither is present. | |
| if (!hasUsrLocalBin && !hasOptHomebrewBin) { | |
| StringBuilder updatedPath = new StringBuilder(); | |
| updatedPath.append("/usr/local/bin") | |
| .append(java.io.File.pathSeparator) | |
| .append("/opt/homebrew/bin") | |
| .append(java.io.File.pathSeparator) | |
| .append(path); | |
| env.put("PATH", updatedPath.toString()); | |
| } |
| private void ensureCliPath(ProcessBuilder builder) { | ||
| if (!isWindowsPlatform()) { | ||
| Map<String, String> env = builder.environment(); | ||
| String path = env.getOrDefault("PATH", ""); | ||
| if (!path.contains("/usr/local/bin") && !path.contains("/opt/homebrew/bin")) { | ||
| env.put("PATH", "/usr/local/bin:/opt/homebrew/bin:" + path); | ||
| } | ||
| } | ||
| } |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CHANGELOG.md file has not been updated to document this bug fix. According to the contribution guidelines and the checklist in the PR description, the CHANGELOG should be updated for bug fixes. Please add an entry in the "Bugs Fixed" section of the unreleased version (1.19.0-beta.2) describing this fix for AzureCliCredential failing in non-interactive environments.
Fix [BUG] AzureCliCredential fails in non-interactive environments due to hardcoded /bin/sh PATH resolution
#47614
Add ensureCliPath method to set Azure CLI installation paths in the process environment.
Description
Please add an informative description that covers that changes made by the pull request and link all relevant issues.
If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines