Skip to content

Commit 416cd28

Browse files
authored
ref(integrations): Small updates to ADO after investigation (#50525)
This PR has three minor changes to the ADO integration: - Adds docs links to each of the endpoints - Adds a sequence of checks to work-item-states check in case the project does not have the 'Bug' work item - Updates the error when we encounter permission errors on fetching the subscription to be more helpful. At this stage we're not using the user's credentials so the original error wasn't entirely accurate. <img width="712" alt="image" src="https://github.com/getsentry/sentry/assets/35509934/f6fe98ad-5a2b-442a-b7dc-3252a5a483d8">
1 parent ffc3bc8 commit 416cd28

File tree

3 files changed

+51
-17
lines changed

3 files changed

+51
-17
lines changed

src/sentry/integrations/vsts/client.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,51 @@
2424

2525

2626
class VstsApiPath:
27+
"""
28+
Endpoints used by the Azure Devops (Formerly 'Visual Studios Team Services') integration client.
29+
Last Updated: 06/2023
30+
"""
31+
32+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get
2733
commit = "{instance}_apis/git/repositories/{repo_id}/commits/{commit_id}"
34+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-commits
2835
commits = "{instance}_apis/git/repositories/{repo_id}/commits"
36+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-commits-batch
2937
commits_batch = "{instance}_apis/git/repositories/{repo_id}/commitsBatch"
38+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-changes
3039
commits_changes = "{instance}_apis/git/repositories/{repo_id}/commits/{commit_id}/changes"
40+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/core/projects/get
3141
project = "{instance}_apis/projects/{project_id}"
42+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/core/projects/list
3243
projects = "{instance}_apis/projects"
44+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/get-repository
3345
repository = "{instance}{project}_apis/git/repositories/{repo_id}"
46+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/list
3447
repositories = "{instance}{project}_apis/git/repositories"
48+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/get
49+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/delete
50+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/replace-subscription
3551
subscription = "{instance}_apis/hooks/subscriptions/{subscription_id}"
52+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/create
3653
subscriptions = "{instance}_apis/hooks/subscriptions"
54+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/get-work-item
55+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/update
3756
work_items = "{instance}_apis/wit/workitems/{id}"
57+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-items/create
3858
work_items_create = "{instance}{project}/_apis/wit/workitems/${type}"
39-
# TODO(lb): Fix this url so that the base url is given by vsts rather than built by us
59+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/search/work-item-search-results/fetch-work-item-search-results
4060
work_item_search = (
61+
# TODO(lb): Fix this url so that the base url is given by vsts rather than built by us
4162
"https://{account_name}.almsearch.visualstudio.com/_apis/search/workitemsearchresults"
4263
)
64+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-item-type-states/list
4365
work_item_states = "{instance}{project}/_apis/wit/workitemtypes/{type}/states"
44-
# TODO(lb): Fix this url so that the base url is given by vsts rather than built by us
45-
users = "https://{account_name}.vssps.visualstudio.com/_apis/graph/users"
66+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/users/get
67+
users = (
68+
# TODO(lb): Fix this url so that the base url is given by vsts rather than built by us
69+
"https://{account_name}.vssps.visualstudio.com/_apis/graph/users"
70+
)
71+
# https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work-item-type-categories/list
4672
work_item_categories = "{instance}{project}/_apis/wit/workitemtypecategories"
4773

4874

@@ -166,15 +192,23 @@ def get_work_item(self, instance: str, id: str) -> Response:
166192
return self.get(VstsApiPath.work_items.format(instance=instance, id=id))
167193

168194
def get_work_item_states(self, instance: str, project: str) -> Response:
169-
return self.get(
170-
VstsApiPath.work_item_states.format(
171-
instance=instance,
172-
project=project,
173-
# TODO(lb): might want to make this custom like jira at some point
174-
type="Bug",
175-
),
176-
api_preview=True,
177-
)
195+
# XXX: Until we add the option to enter the 'WorkItemType' for syncing status changes from
196+
# Sentry to Azure DevOps, we need will attempt to use the sequence below. There are certain
197+
# ADO configurations which don't have 'Bug' or 'Issue', hence iterating until we find a match.
198+
check_sequence = ["Bug", "Issue", "Task"]
199+
response = None
200+
for check_type in check_sequence:
201+
response = self.get(
202+
VstsApiPath.work_item_states.format(
203+
instance=instance,
204+
project=project,
205+
type=check_type,
206+
),
207+
api_preview=True,
208+
)
209+
if response.get("count", 0) > 0:
210+
break
211+
return response
178212

179213
def get_work_item_categories(self, instance: str, project: str) -> Response:
180214
return self.get(VstsApiPath.work_item_categories.format(instance=instance, project=project))

src/sentry/integrations/vsts/integration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,9 @@ def create_subscription(
462462
},
463463
)
464464
raise IntegrationProviderError(
465-
"You do not have sufficient account access to create webhooks\n"
466-
"on the selected Azure DevOps organization.\n"
467-
"Please check with the owner of this Azure DevOps account."
465+
"Sentry cannot communicate with this Azure DevOps organization.\n"
466+
"Please ensure third-party app access via OAuth is enabled \n"
467+
"in the organization's security policy."
468468
)
469469
raise e
470470

tests/sentry/integrations/vsts/test_integration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def test_create_subscription_forbidden(self, mock_get_scopes):
207207
integration.set_pipeline(pipeline)
208208
with pytest.raises(IntegrationProviderError) as err:
209209
integration.build_integration(state)
210-
assert "sufficient account access to create webhooks" in str(err)
210+
assert "ensure third-party app access via OAuth is enabled" in str(err)
211211

212212
@patch("sentry.integrations.vsts.VstsIntegrationProvider.get_scopes", return_value=FULL_SCOPES)
213213
def test_create_subscription_unauthorized(self, mock_get_scopes):
@@ -242,7 +242,7 @@ def test_create_subscription_unauthorized(self, mock_get_scopes):
242242
integration.set_pipeline(pipeline)
243243
with pytest.raises(IntegrationProviderError) as err:
244244
integration.build_integration(state)
245-
assert "sufficient account access to create webhooks" in str(err)
245+
assert "ensure third-party app access via OAuth is enabled" in str(err)
246246

247247

248248
@control_silo_test

0 commit comments

Comments
 (0)