diff --git a/Usage.md b/Usage.md index 15661f4d..a84f854e 100644 --- a/Usage.md +++ b/Usage.md @@ -277,11 +277,18 @@ git_provider="azure" use_repo_settings_file=false ``` -And use the following settings (you have to replace the values) in .secrets.toml: +Azure DevOps provider supports [PAT token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) or [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview#authentication-in-server-environments) authentication. +PAT is faster to create, but has build in experation date, and will use the user identity for API calls. +Using DefaultAzureCredential you can use managed identity or Service principle, which are more secure and will create seperate ADO user identity (via AAD) to the agent. + +If PAT was choosen, you can assign the value in .secrets.toml. +If DefaultAzureCredential was choosen, you can assigned the additional env vars like AZURE_CLIENT_SECRET directly, +or use managed identity/az cli (for local develpment) without any additional configuration. +in any case, 'org' value must be assigned in .secrets.toml: ``` [azure_devops] org = "https://dev.azure.com/YOUR_ORGANIZATION/" -pat = "YOUR_PAT_TOKEN" +# pat = "YOUR_PAT_TOKEN" needed only if using PAT for authentication ``` ##### Azure DevOps Webhook @@ -470,4 +477,4 @@ patch_extra_lines=3 ``` Increasing this number provides more context to the model, but will also increase the token budget. -If the PR is too large (see [PR Compression strategy](./PR_COMPRESSION.md)), PR-Agent automatically sets this number to 0, using the original git patch. +If the PR is too large (see [PR Compression strategy](./PR_COMPRESSION.md)), PR-Agent automatically sets this number to 0, using the original git patch. \ No newline at end of file diff --git a/docs/Full_environments.md b/docs/Full_environments.md index d94657cf..3584b006 100644 --- a/docs/Full_environments.md +++ b/docs/Full_environments.md @@ -15,7 +15,7 @@ | | Generate Custom Labels 💎 | :white_check_mark: | :white_check_mark: | | | | | | | | | | | | | | USAGE | CLI | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | App / webhook | :white_check_mark: | :white_check_mark: | | | | +| | App / webhook | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | | | Tagging bot | :white_check_mark: | | | | | | | Actions | :white_check_mark: | | | | | | | Web server | | | | | | :white_check_mark: | @@ -24,4 +24,4 @@ | | Repo language prioritization | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Adaptive and token-aware
file patch fitting | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Multiple models support | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Incremental PR Review | :white_check_mark: | | | | | | \ No newline at end of file +| | Incremental PR Review | :white_check_mark: | | | | | | diff --git a/pr_agent/git_providers/azuredevops_provider.py b/pr_agent/git_providers/azuredevops_provider.py index d467547b..c5cdb531 100644 --- a/pr_agent/git_providers/azuredevops_provider.py +++ b/pr_agent/git_providers/azuredevops_provider.py @@ -10,6 +10,7 @@ from .git_provider import GitProvider from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo AZURE_DEVOPS_AVAILABLE = True +ADO_APP_CLIENT_DEFAULT_ID = "499b84ac-1321-427f-aa17-267ca6975798/.default" MAX_PR_DESCRIPTION_AZURE_LENGTH = 4000-1 try: @@ -18,6 +19,8 @@ try: # noinspection PyUnresolvedReferences from azure.devops.connection import Connection # noinspection PyUnresolvedReferences + from azure.identity import DefaultAzureCredential + # noinspection PyUnresolvedReferences from azure.devops.v7_1.git.models import ( Comment, CommentThread, @@ -507,13 +510,30 @@ class AzureDevopsProvider(GitProvider): @staticmethod def _get_azure_devops_client(): - try: - pat = get_settings().azure_devops.pat - org = get_settings().azure_devops.org - except AttributeError as e: - raise ValueError("Azure DevOps PAT token is required ") from e + org = get_settings().azure_devops.get("org", None) + pat = get_settings().azure_devops.get("pat", None) - credentials = BasicAuthentication("", pat) + if not org: + raise ValueError("Azure DevOps organization is required") + + if pat: + auth_token = pat + else: + try: + # try to use azure default credentials + # see https://learn.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python + # for usage and env var configuration of user-assigned managed identity, local machine auth etc. + get_logger().info("No PAT found in settings, trying to use Azure Default Credentials.") + credentials = DefaultAzureCredential() + accessToken = credentials.get_token(ADO_APP_CLIENT_DEFAULT_ID) + auth_token = accessToken.token + except Exception as e: + get_logger().error(f"No PAT found in settings, and Azure Default Authentication failed, error: {e}") + raise + + credentials = BasicAuthentication("", auth_token) + + credentials = BasicAuthentication("", auth_token) azure_devops_connection = Connection(base_url=org, creds=credentials) azure_devops_client = azure_devops_connection.clients.get_git_client() @@ -543,3 +563,4 @@ class AzureDevopsProvider(GitProvider): if get_settings().config.verbosity_level >= 2: get_logger().error(f"Failed to get pr id, error: {e}") return "" + diff --git a/requirements.txt b/requirements.txt index b649f304..d34eb763 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ aiohttp==3.9.1 atlassian-python-api==3.41.4 azure-devops==7.1.0b3 +azure-identity==1.15.0 boto3==1.33.6 dynaconf==3.2.4 fastapi==0.99.0