Examples
Mapping projectsโ
In the following example you will ingest your Azure Devops projects and their default team (Optional) to Port, you may use the following Port blueprint definitions and integration configuration:
Project blueprint
{
"identifier": "project",
"title": "Project",
"icon": "AzureDevops",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current lifecycle state of the project."
},
"revision": {
"title": "Revision",
"type": "string",
"icon": "AzureDevops",
"description": "The revision number, indicating how many times the project configuration has been updated."
},
"visibility": {
"title": "Visibility",
"type": "string",
"icon": "AzureDevops",
"description": "Indicates whether the project is private or public"
},
"defaultTeam": {
"title": "Default Team",
"type": "string",
"icon": "Team",
"description": "Default Team of the project"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to azure devops project"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Integration mapping
resources:
- kind: project
selector:
query: 'true'
defaultTeam: 'true'
port:
entity:
mappings:
identifier: .id | gsub(" "; "")
title: .name
blueprint: '"project"'
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
Mapping repositories, file contents, repository policies and pull requestsโ
In the following example you will ingest your Azure Devops repositories, their README.md file contents and pull requests to Port, you may use the following Port blueprint definitions and integration configuration:
Project blueprint
{
"identifier": "project",
"title": "Project",
"icon": "AzureDevops",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current lifecycle state of the project."
},
"revision": {
"title": "Revision",
"type": "string",
"icon": "AzureDevops",
"description": "The revision number, indicating how many times the project configuration has been updated."
},
"visibility": {
"title": "Visibility",
"type": "string",
"icon": "AzureDevops",
"description": "Indicates whether the project is private or public"
},
"defaultTeam": {
"title": "Default Team",
"type": "string",
"icon": "Team",
"description": "Default Team of the project"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to azure devops project"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Repository blueprint
{
"identifier": "azureDevopsRepository",
"title": "Repository",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"title": "URL",
"format": "url",
"type": "string",
"icon": "Link"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown",
"icon": "Book"
},
"workItemLinking": {
"title": "Work Item Linking",
"default": false,
"type": "boolean"
},
"minimumApproverCount": {
"title": "Minimum Approver Count",
"default": 0,
"type": "number"
},
"slack": {
"icon": "Slack",
"type": "string",
"title": "Slack",
"format": "url"
},
"tier": {
"title": "Tier",
"type": "string",
"description": "How mission-critical the service is",
"enum": [
"Mission Critical",
"Customer Facing",
"Internal Service",
"Other"
],
"enumColors": {
"Mission Critical": "turquoise",
"Customer Facing": "green",
"Internal Service": "darkGray",
"Other": "yellow"
},
"icon": "DefaultProperty"
}
},
"required": []
},
"mirrorProperties": {
"defaultTeam": {
"title": "Default Team",
"path": "project.defaultTeam"
}
},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": false,
"many": false
}
}
}
Pull request blueprint
{
"identifier": "azureDevopsPullRequest",
"title": "Pull Request",
"icon": "AzureDevops",
"schema": {
"properties": {
"creator": {
"title": "Creator",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"completed",
"abandoned",
"active"
],
"enumColors": {
"completed": "yellow",
"abandoned": "red",
"active": "green"
}
},
"reviewers": {
"type": "array",
"title": "Reviewers",
"items": {
"type": "string",
"format": "user"
}
},
"createdAt": {
"title": "Create At",
"type": "string",
"format": "date-time"
},
"link": {
"title": "Link",
"format": "url",
"type": "string"
},
"leadTimeHours": {
"title": "Lead Time in hours",
"type": "number"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "azureDevopsRepository",
"required": false,
"many": false
}
}
}
Integration mapping
resources:
- kind: project
selector:
query: 'true'
defaultTeam: 'true'
port:
entity:
mappings:
identifier: '.id | gsub(" "; "")'
blueprint: '"project"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: "\(.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.name | ascii_downcase | gsub("[ ();]"; ""))"
title: .name
blueprint: '"azureDevopsRepository"'
properties:
url: .url
readme: file://README.md
relations:
project: .project.id | gsub(" "; "")
- kind: repository-policy
selector:
query: .type.displayName=="Minimum number of reviewers"
port:
entity:
mappings:
identifier: '.__repository.project.name + "/" + .__repository.name | gsub(" "; "")'
blueprint: '"azureDevopsRepository"'
properties:
minimumApproverCount: .settings.minimumApproverCount
- kind: repository-policy
selector:
query: .type.displayName=="Work item linking"
port:
entity:
mappings:
identifier: '.__repository.project.name + "/" + .__repository.name | gsub(" "; "")'
blueprint: '"azureDevopsRepository"'
properties:
workItemLinking: .isEnabled and .isBlocking
- kind: pull-request
selector:
query: 'true'
port:
entity:
mappings:
identifier: >-
.repository.project.name + "/" + .repository.name + (.pullRequestId
| tostring) | gsub(" "; "")
blueprint: '"azureDevopsPullRequest"'
properties:
creator: .createdBy.uniqueName
status: .status
reviewers: '[.reviewers[].uniqueName]'
createdAt: .creationDate
leadTimeHours: >-
(.creationDate as $createdAt | .status as $status | .closedDate as $closedAt |
($createdAt | sub("\\..*Z$"; "Z") | strptime("%Y-%m-%dT%H:%M:%SZ") | mktime) as $createdTimestamp |
($closedAt | if . == null then null else sub("\\..*Z$"; "Z") |
strptime("%Y-%m-%dT%H:%M:%SZ") | mktime end) as $closedTimestamp |
if $status == "completed" and $closedTimestamp != null then
(((($closedTimestamp - $createdTimestamp) / 3600) * 100 | floor) / 100)
else null end)
relations:
repository: '.repository.project.name + "/" + .repository.name | gsub(" "; "")'
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform Azure Devops objects to Port entities.
- Click Here for the Azure Devops repository object structure.
- Click Here for the Azure Devops repository-policy object structure.
- Click Here for the Azure Devops pull-request object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your repositories alongside their README.md
file contents and pull requests.
Mapping pipelinesโ
In the following example you will ingest your Azure Devops pipelines to Port, you may use the following Port blueprint definitions and integration configuration:
Project blueprint
{
"identifier": "project",
"title": "Project",
"icon": "AzureDevops",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current lifecycle state of the project."
},
"revision": {
"title": "Revision",
"type": "string",
"icon": "AzureDevops",
"description": "The revision number, indicating how many times the project configuration has been updated."
},
"visibility": {
"title": "Visibility",
"type": "string",
"icon": "AzureDevops",
"description": "Indicates whether the project is private or public"
},
"defaultTeam": {
"title": "Default Team",
"type": "string",
"icon": "Team",
"description": "Default Team of the project"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to azure devops project"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Pipeline blueprint
{
"identifier": "azureDevopsPipeline",
"title": "Pipeline",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"type": "string",
"format": "url",
"title": "URL"
},
"revision": {
"type": "number",
"title": "Revision"
},
"folder": {
"title": "Folder",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
}
}
}
Integration mapping
resources:
- kind: project
selector:
query: 'true'
defaultTeam: 'true'
port:
entity:
mappings:
identifier: '.id | gsub(" "; "")'
blueprint: '"project"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
- kind: pipeline
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"azureDevopsPipeline"'
properties:
url: .url
revision: .revision
folder: .folder
relations:
project: '.__projectId | gsub(" "; "")'
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform Azure Devops objects to Port entities.
- Click Here for the Azure Devops pipeline object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port.
Mapping users and teamsโ
The following example blueprints and integration configurations demonstrate how to ingest Azure Devops users and teams into Port:
Project blueprint
{
"identifier": "project",
"title": "Project",
"icon": "AzureDevops",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current lifecycle state of the project."
},
"revision": {
"title": "Revision",
"type": "string",
"icon": "AzureDevops",
"description": "The revision number, indicating how many times the project configuration has been updated."
},
"visibility": {
"title": "Visibility",
"type": "string",
"icon": "AzureDevops",
"description": "Indicates whether the project is private or public"
},
"defaultTeam": {
"title": "Default Team",
"type": "string",
"icon": "Team",
"description": "Default Team of the project"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to azure devops project"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
User blueprint
{
"identifier": "azureDevopsUser",
"title": "Azure Devops User",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"icon": "Link",
"title": "URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Team blueprint
{
"identifier": "azureDevopsTeam",
"title": "Azure Devops Team",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"icon": "Link",
"title": "URL",
"type": "string",
"format": "url"
},
"description": {
"title": "Description",
"type": "string",
"icon": "DefaultProperty"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
},
"members": {
"title": "Members",
"description": "The ADO users belonging to this team",
"target": "azureDevopsUser",
"required": false,
"many": true
}
}
}
Integration mapping
resources:
- kind: user
selector:
query: 'true'
port:
entity:
mappings:
identifier: .user.mailAddress
title: .user.displayName
blueprint: '"azureDevopsUser"'
properties:
url: .user.url
- kind: project
selector:
query: 'true'
defaultTeam: 'true'
port:
entity:
mappings:
identifier: '.id | gsub(" "; "")'
blueprint: '"project"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
- kind: team
selector:
query: 'true'
includeMembers: 'true'
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"azureDevopsTeam"'
properties:
url: .url
description: .description
relations:
project: .projectId | gsub(" "; "")
members: .__members | map(.identity.uniqueName)
- Refer to the setup section to learn more about the integration configuration setup process.
- Port leverages the JQ JSON processor to map and transform Azure Devops objects to Port entities.
- Click Here for the Azure Devops team object structure.
- Click Here for the Azure Devops User object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your teams alongside their members.
Mapping teams and members (Deprecated)โ
This section is deprecated and will be removed in a future version. Please refer to the Mapping users and teams section for the current implementation.
In the following example you will ingest your Azure Devops teams and their members to Port, you may use the following Port blueprint definitions and integration configuration:
Project blueprint
{
"identifier": "project",
"title": "Project",
"icon": "AzureDevops",
"schema": {
"properties": {
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current lifecycle state of the project."
},
"revision": {
"title": "Revision",
"type": "string",
"icon": "AzureDevops",
"description": "The revision number, indicating how many times the project configuration has been updated."
},
"visibility": {
"title": "Visibility",
"type": "string",
"icon": "AzureDevops",
"description": "Indicates whether the project is private or public"
},
"defaultTeam": {
"title": "Default Team",
"type": "string",
"icon": "Team",
"description": "Default Team of the project"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to azure devops project"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Repository blueprint
{
"identifier": "azureDevopsRepository",
"title": "Repository",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"title": "URL",
"format": "url",
"type": "string",
"icon": "Link"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown",
"icon": "Book"
},
"workItemLinking": {
"title": "Work Item Linking",
"default": false,
"type": "boolean"
},
"minimumApproverCount": {
"title": "Minimum Approver Count",
"default": 0,
"type": "number"
},
"slack": {
"icon": "Slack",
"type": "string",
"title": "Slack",
"format": "url"
},
"tier": {
"title": "Tier",
"type": "string",
"description": "How mission-critical the service is",
"enum": [
"Mission Critical",
"Customer Facing",
"Internal Service",
"Other"
],
"enumColors": {
"Mission Critical": "turquoise",
"Customer Facing": "green",
"Internal Service": "darkGray",
"Other": "yellow"
},
"icon": "DefaultProperty"
}
},
"required": []
},
"mirrorProperties": {
"defaultTeam": {
"title": "Default Team",
"path": "project.defaultTeam"
}
},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": false,
"many": false
}
}
}
Member blueprint
{
"identifier": "azureDevopsMember",
"title": "Azure Devops Member",
"icon": "AzureDevops",
"schema": {
"properties": {
"email": {
"title": "Email",
"type": "string",
"format": "user",
"icon": "DefaultProperty"
},
"url": {
"icon": "Link",
"title": "URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"team": {
"title": "team",
"target": "azureDevopsTeam",
"required": false,
"many": false
}
}
}
Team blueprint
{
"identifier": "azureDevopsTeam",
"title": "Azure Devops Team",
"icon": "AzureDevops",
"schema": {
"properties": {
"url": {
"icon": "Link",
"title": "URL",
"type": "string",
"format": "url"
},
"description": {
"title": "Description",
"type": "string",
"icon": "DefaultProperty"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
}
}
}
Integration mapping
resources:
- kind: project
selector:
query: 'true'
defaultTeam: 'true'
port:
entity:
mappings:
identifier: '.id | gsub(" "; "")'
blueprint: '"project"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: '.project.name + "/" + .name | gsub(" "; "")'
title: .name
blueprint: '"azureDevopsRepository"'
properties:
url: .url
readme: file://README.md
relations:
project: .project.id | gsub(" "; "")
- kind: repository-policy
selector:
query: .type.displayName=="Minimum number of reviewers"
port:
entity:
mappings:
identifier: '.__repository.project.name + "/" + .__repository.name | gsub(" "; "")'
blueprint: '"azureDevopsRepository"'
properties:
minimumApproverCount: .settings.minimumApproverCount
- kind: repository-policy
selector:
query: .type.displayName=="Work item linking"
port:
entity:
mappings:
identifier: '.__repository.project.name + "/" + .__repository.name | gsub(" "; "")'
blueprint: '"azureDevopsRepository"'
properties:
workItemLinking: .isEnabled and .isBlocking
- kind: team
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"azureDevopsTeam"'
properties:
url: .url
description: .description
relations:
project: .projectId | gsub(" "; "")
- kind: member
selector:
query: 'true'
port:
entity:
mappings:
identifier: .identity.uniqueName + "-" + .__teamId
title: .identity.displayName
blueprint: '"azureDevopsMember"'
properties:
url: .identity.url
email: .identity.uniqueName
relations:
team: .__teamId
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform Azure Devops objects to Port entities.
- Click Here for the Azure Devops team object structure.
- Click Here for the Azure Devops team member object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your teams alongside their members.
Mapping Work Itemsโ
In the following example you will ingest your Azure Devops work items to Port, you may use the following Port blueprint definitions and integration configuration:
Work item blueprint
{
"identifier": "workItem",
"title": "Work Item",
"icon": "AzureDevops",
"schema": {
"properties": {
"type": {
"title": "Type",
"type": "string",
"icon": "AzureDevops",
"description": "The type of work item (e.g., Bug, Task, User Story)",
"enum": [
"Issue",
"Epic",
"Task"
],
"enumColors": {
"Issue": "green",
"Epic": "orange",
"Task": "blue"
}
},
"state": {
"title": "State",
"type": "string",
"icon": "AzureDevops",
"description": "The current state of the work item (e.g., New, Active, Closed)"
},
"reason": {
"title": "Reason",
"type": "string",
"description": "The title of the work item"
},
"effort": {
"title": "Effort",
"type": "number",
"description": "The estimated effort for the work item"
},
"description": {
"title": "Description",
"type": "string",
"format": "markdown",
"description": "A detailed description of the work item"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to the work item in Azure DevOps"
},
"createdBy": {
"title": "Created By",
"type": "string",
"icon": "User",
"description": "The person who created the work item"
},
"changedBy": {
"title": "Changed By",
"type": "string",
"icon": "User",
"description": "The person who last changed the work item"
},
"assignedTo": {
"title": "Assigned To",
"type": "string",
"icon": "User",
"description": "The person assigned to this work item"
},
"createdDate": {
"title": "Created Date",
"type": "string",
"format": "date-time",
"description": "The date and time when the work item was created"
},
"changedDate": {
"title": "Changed Date",
"type": "string",
"format": "date-time",
"description": "The date and time when the work item was last changed"
}
},
"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
}
}
}
Integration mapping
resources:
- kind: work-item
selector:
query: 'true'
expand: 'All'
wiql: '[System.WorkItemType] = "Task" order by [System.CreatedDate] desc'
port:
entity:
mappings:
identifier: .id | tostring
title: .fields."System.Title"
blueprint: '"workItem"'
properties:
type: .fields."System.WorkItemType"
state: .fields."System.State"
effort: .fields."Microsoft.VSTS.Scheduling.Effort"
description: .fields."System.Description"
link: .url
reason: .fields."System.Reason"
createdBy: .fields."System.CreatedBy".displayName
changedBy: .fields."System.ChangedBy".displayName
assignedTo: .fields."System.AssignedTo".displayName
createdDate: .fields."System.CreatedDate"
changedDate: .fields."System.ChangedDate"
relations:
project: .__projectId | gsub(" "; "")
column: >-
.fields."System.WorkItemType"+"-"+.fields."System.BoardColumn"+"-"+.__project.id
| gsub(" "; "")
Mapping boardsโ
The example below shows how to ingest Azure DevOps Boards into Port.
You can use the following Port blueprint definitions and integration configuration:
Board blueprint
{
"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": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
}
}
}
Integration mapping
resources:
- kind: board
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id | gsub(" "; "")
title: .name
blueprint: '"board"'
properties:
link: .url
relations:
project: .__project.id | gsub(" "; "")
- Click here for the Azure DevOps board object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your Azure DevOps boards.
Mapping columnsโ
The example below shows how to ingest Azure DevOps Columns into Port.
You can use the following Port blueprint definitions and integration configuration:
Column blueprint
{
"identifier": "column",
"title": "Column",
"icon": "AzureDevops",
"schema": {
"properties": {},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"board": {
"title": "board",
"target": "board",
"required": true,
"many": false
}
}
}
Integration mapping
resources:
- kind: column
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__stateType+"-"+.name+"-"+.__board.__project.id | gsub(" "; "")
title: .name
blueprint: '"column"'
relations:
board: .__board.id | gsub(" "; "")
Click here to learn about the Azure DevOps column object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your Azure DevOps columns.
Mapping releasesโ
The example below shows how to ingest Azure DevOps Releases into Port.
You can use the following Port blueprint definitions and integration configuration:
Release blueprint
{
"identifier": "release",
"title": "Release",
"icon": "AzureDevops",
"schema": {
"properties": {
"status": {
"title": "Status",
"type": "string",
"icon": "DefaultProperty",
"description": "The current status of the release"
},
"reason": {
"title": "Reason",
"type": "string",
"description": "The reason for the release creation"
},
"createdDate": {
"title": "Created Date",
"type": "string",
"format": "date-time",
"description": "The date and time when the release was created"
},
"modifiedDate": {
"title": "Modified Date",
"type": "string",
"format": "date-time",
"description": "The date and time when the release was last modified"
},
"createdBy": {
"title": "Created By",
"type": "string",
"icon": "User",
"description": "The person who created the release"
},
"modifiedBy": {
"title": "Modified By",
"type": "string",
"icon": "User",
"description": "The person who last modified the release"
},
"definitionName": {
"title": "Definition Name",
"type": "string",
"description": "The name of the release definition"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "AzureDevops",
"description": "Link to the release in Azure DevOps"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"project": {
"title": "Project",
"target": "project",
"required": true,
"many": false
}
}
}
Integration mapping
resources:
- kind: release
selector:
query: 'true'
port:
entity:
mappings:
identifier: .projectReference.id + "-" + (.id | tostring) | gsub(" "; "")
title: .name
blueprint: '"release"'
properties:
status: .status
reason: .reason
createdDate: .createdOn
modifiedDate: .modifiedOn
createdBy: .createdBy.uniqueName
modifiedBy: .modifiedBy.uniqueName
definitionName: .releaseDefinition.name
link: ._links.web.href | gsub("_release?releaseId="; "")
relations:
project: .projectReference.id | gsub(" "; "")
Click here for the Azure DevOps release object structure.
Mapping filesโ
The example below shows how to ingest specific files from your Azure DevOps repositories into Port. This integration allows you to track and monitor individual files across your repositories.
Capabilities and Limitationsโ
Before implementing file mapping, please note the following:
- Explicit Paths Only: The integration supports explicit file paths relative to the repository root. Wildcard/glob patterns (e.g.,
*.yaml
or**/*.json
) are not yet supported. - File Types: Any plain-text or structured file (e.g.,
.yaml
,.json
,.md
,.py
) can be ingested. - Path Structure: Only relative paths from the repository root are currently supported. For example:
- โ
Correct paths:
README.md
docs/getting-started.md
src/config/default.json
deployment/k8s/production.yaml
- โ Incorrect paths:
/README.md
(leading slash)C:/repo/config.json
(absolute path)../other-repo/file.txt
(parent directory reference)*.yaml
(glob pattern)
- โ
Correct paths:
- Performance: For optimal performance, we recommend limiting the number of tracked files per repository.
- File Tracking: Each file specified in the configuration will be tracked as a separate entity in Port
- Change Detection: Changes to tracked files will be reflected in Port during the next sync
Configurationโ
You can use the following Port blueprint definitions and integration configuration:
File blueprint
{
"identifier": "file",
"title": "File",
"icon": "AzureDevops",
"schema": {
"properties": {
"path": {
"title": "Path",
"type": "string",
"icon": "DefaultProperty",
"description": "The path of the file in the repository"
},
"size": {
"title": "Size",
"type": "number",
"icon": "DefaultProperty",
"description": "The size of the file in bytes"
},
"content": {
"title": "Content",
"type": "string",
"icon": "DefaultProperty",
"description": "The content of the file"
},
"link": {
"title": "Link",
"type": "string",
"format": "url",
"icon": "Link",
"description": "Link to the file in Azure DevOps"
}
},
"required": ["path"]
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "service",
"required": true,
"many": false
}
}
}
Integration mapping
The selector
section within a file
resource demonstrates how to configure file ingestion from Azure DevOps repositories. You can control:
- path: Specify explicit file paths to ingest specific files (e.g.,
src/config.yaml
,deployment/helm/values.yaml
). - repos: Target specific repositories or leave blank to scan all repositories.
resources:
- kind: file
selector:
query: 'true'
files:
path: "src/config.yaml" # Pass a single explicit file path
repos: ["my-repo", "another-repo"] # Optional: specific repositories to scan
port:
entity:
mappings:
identifier: .file.path | gsub(" "; "")
title: .file.path
blueprint: '"file"'
properties:
path: .file.path
size: .file.size
content: .file.content
link: .repo.remoteUrl + "?path=" + (.file.path)
relations:
repository: >-
"\(.repo.project.name | ascii_downcase | gsub("[ ();]";
""))/\(.repo.name | ascii_downcase | gsub("[ ();]"; ""))"
- kind: file
selector:
query: 'true'
files:
path: # Pass an array of explicit file paths
- "deployment/helm/values.yaml"
- "config/settings.json"
- "docs/README.md"
- "package.json"
port:
entity:
mappings:
identifier: .repo.name + "/" + .file.objectId
title: .file.path
blueprint: '"file"'
properties:
path: .file.path
size: .file.size
content: .file.content
link: .repo.remoteUrl + "?path=" + (.file.path)
relations:
repository: >-
"\(.repo.project.name | ascii_downcase | gsub("[ ();]";
""))/\(.repo.name | ascii_downcase | gsub("[ ();]"; ""))"
Example Use Casesโ
Common scenarios for file mapping include:
- Tracking configuration files (e.g.,
deployment.yaml
,config.json
) - Monitoring documentation files (e.g.,
README.md
,CONTRIBUTING.md
) - Tracking infrastructure definitions (e.g.,
terraform.tf
,docker-compose.yml
)
Click here for the Azure DevOps file object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your specified files.
Mapping supported resourcesโ
The above examples shows a specific use cases, but Port's Azure Devops integration supports the ingestion of many other Azure Devops objects, to adapt the examples above, use the Azure Devops API reference to learn about the available fields for the different supported objects:
repository
repository-policy
project
pull-request
pipeline
user
team
member
work-item
board
release
file
When adding the ingestion of other resources, remember to add an entry to the resources
array and change the value provided to the kind
key accordingly.