Skip to content
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

[Integration][ADO] Added Support for boards and columns #1034

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
38d645e
Support Boards
oiadebayo Sep 19, 2024
220ad6c
Support for columns
oiadebayo Sep 19, 2024
3474b11
Added examples for new integrations
oiadebayo Sep 19, 2024
2b8b120
Fix naming conflict
oiadebayo Sep 19, 2024
6a90eba
Lint fix
oiadebayo Sep 19, 2024
d11050c
Updated example to pass lint
oiadebayo Sep 19, 2024
dd219f5
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
oiadebayo Sep 19, 2024
968d456
Lint fix
oiadebayo Sep 19, 2024
cbf6add
Attended to review comments
oiadebayo Sep 20, 2024
265c930
Lint
oiadebayo Sep 20, 2024
af6a16c
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
oiadebayo Sep 26, 2024
cde43a3
Update pyproject.toml
oiadebayo Sep 26, 2024
e85358f
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
oiadebayo Oct 2, 2024
8acbe98
Update integrations/azure-devops/azure_devops/client/azure_devops_cli…
oiadebayo Oct 2, 2024
063a3a0
Update integrations/azure-devops/azure_devops/client/azure_devops_cli…
oiadebayo Oct 2, 2024
3705816
Added test for ADO client
oiadebayo Oct 2, 2024
a8c09a4
Update test_azure_devops_client.py
oiadebayo Oct 2, 2024
650c79b
Lint fix
oiadebayo Oct 2, 2024
4efefdd
Undo changes
oiadebayo Oct 2, 2024
4419a74
Lint fix
oiadebayo Oct 2, 2024
93b748d
Fixed lint
oiadebayo Oct 2, 2024
a0ee7c6
Lint fix
oiadebayo Oct 2, 2024
0d9fe8d
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
PeyGis Oct 7, 2024
21c7c73
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
oiadebayo Oct 8, 2024
2c12b41
Update pyproject.toml
oiadebayo Oct 8, 2024
c47035c
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
oiadebayo Oct 10, 2024
f880641
Updated changelog
oiadebayo Oct 10, 2024
37febe6
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
PeyGis Oct 10, 2024
ecc3664
Merge branch 'main' into PORT-10285-Azure-Devops-Integration-Add-Supp…
PeyGis Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion integrations/azure-devops/.port/resources/blueprints.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@
"type": "string",
"icon": "AzureDevops",
"description": "The type of work item (e.g., Bug, Task, User Story)",
"enum": ["Issue", "Epic", "Task"],
"enum": [
"Issue",
"Epic",
"Task"
],
"enumColors": {
"Issue": "green",
"Epic": "orange",
Expand Down Expand Up @@ -190,6 +194,66 @@
},
"required": []
},
"mirrorProperties": {
"board": {
"title": "Board",
"path": "column.board.$title"
}
},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
},
"column": {
"title": "Column",
"description": "The column the entity belongs",
"target": "column",
"required": true,
"many": false
}
}
},
{
"identifier": "column",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's make the identifier consistent with the others azureDevopsBoard, azureDevopsColumn

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The none of the kinds in the default blueprint has this prefix azureDevops

"title": "Column",
"icon": "AzureDevops",
"schema": {
"properties": {},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"board": {
"title": "board",
"target": "board",
"required": true,
"many": false
}
}
},
{
"identifier": "board",
"title": "Board",
"icon": "AzureDevops",
"schema": {
"properties": {
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to the board in Azure DevOps"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
Expand Down
25 changes: 25 additions & 0 deletions integrations/azure-devops/.port/resources/port-app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ resources:
blueprint: '"service"'
properties:
workItemLinking: .isEnabled and .isBlocking
- kind: board
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id | gsub(" "; "")
title: .name
blueprint: '"board"'
properties:
link: .url
relations:
project: .__project.id | gsub(" "; "")
- kind: work-item
selector:
query: 'true'
Expand All @@ -76,3 +89,15 @@ resources:
changedDate: .fields."System.ChangedDate"
relations:
project: .__projectId | gsub(" "; "")
column: .__project.id + .fields."System.BoardColumn" | gsub(" "; "")
PeyGis marked this conversation as resolved.
Show resolved Hide resolved
- kind: column
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__project.id+.name | gsub(" "; "")
title: .name
PeyGis marked this conversation as resolved.
Show resolved Hide resolved
blueprint: '"column"'
relations:
board: .__board_id | gsub(" "; "")
8 changes: 8 additions & 0 deletions integrations/azure-devops/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- towncrier release notes start -->

## 0.1.69 (2024-09-19)


### Improvements

- Added support for ingesting boards and columns


## 0.1.68 (2024-09-17)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,49 @@ async def get_repository(self, repository_id: str) -> dict[Any, Any]:
repository_data = response.json()
return repository_data

async def get_columns(self) -> list[dict[str, Any]]:
async for boards in self.get_boards_in_organization():
for board in boards:
omby8888 marked this conversation as resolved.
Show resolved Hide resolved
yield [
{
**column,
"__board_id": board.get("id"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return the full board data instead of just the id

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"__project": board.get("__project"),
}
for column in board.get("columns", [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this will fit in since the boards API return only name, id and url. How do we get the columns to be returned as part of the boards?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another function that enriches the data on line 273

]

async def _enrich_board(
oiadebayo marked this conversation as resolved.
Show resolved Hide resolved
self, boards: list[dict[str, Any]], project_id: str
) -> list[dict[str, Any]]:
for board in boards:
response = await self.send_request(
"GET",
f"{self._organization_base_url}/{project_id}/{API_URL_PREFIX}/work/boards/{board['id']}",
)
board.update(response.json())
return boards

async def _get_board(self, project_id: str) -> list[dict[str, Any]]:
oiadebayo marked this conversation as resolved.
Show resolved Hide resolved
get_boards_url = (
f"{self._organization_base_url}/{project_id}/{API_URL_PREFIX}/work/boards"
)
response = await self.send_request("GET", get_boards_url)
board_data = response.json().get("value", [])
logger.info(f"Found {len(board_data)} boards for project {project_id}")
return await self._enrich_board(board_data, project_id)

@cache_iterator_result()
async def get_boards_in_organization(
self,
) -> AsyncGenerator[list[dict[str, Any]], None]:
async for projects in self.generate_projects():
yield [
{**board, "__project": project}
for project in projects
for board in await self._get_board(project["id"])
]

async def generate_subscriptions_webhook_events(self) -> list[WebhookEvent]:
headers = {"Content-Type": "application/json"}
try:
Expand Down
2 changes: 2 additions & 0 deletions integrations/azure-devops/azure_devops/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class Kind(StrEnum):
TEAM = "team"
PROJECT = "project"
WORK_ITEM = "work-item"
BOARD = "board"
COLUMN = "column"


PULL_REQUEST_SEARCH_CRITERIA: list[dict[str, Any]] = [
Expand Down
16 changes: 16 additions & 0 deletions integrations/azure-devops/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ async def resync_workitems(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
yield work_items


@ocean.on_resync(Kind.COLUMN)
async def resync_boards(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
azure_devops_client = AzureDevopsClient.create_from_ocean_config()
async for columns in azure_devops_client.get_columns():
logger.info(f"Resyncing {len(columns)} columns")
yield columns


@ocean.on_resync(Kind.BOARD)
async def resync_boards(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
azure_devops_client = AzureDevopsClient.create_from_ocean_config()
async for boards in azure_devops_client.get_boards_in_organization():
logger.info(f"Resyncing {len(boards)} boards")
yield boards


@ocean.router.post("/webhook")
async def webhook(request: Request) -> dict[str, Any]:
body = await request.json()
Expand Down
2 changes: 1 addition & 1 deletion integrations/azure-devops/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "azure-devops"
version = "0.1.68"
version = "0.1.69"
description = "An Azure Devops Ocean integration"
authors = ["Matan Geva <matang@getport.io>"]

Expand Down
Loading