Examples
Mapping projectsโ
The following example demonstrates how to ingest your Azure Devops projects and their default team (Optional) to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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 (Click to expand)
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, repository policies and pull requestsโ
The following example demonstrates how to ingest your Azure Devops repositories, their README.md file contents and pull requests to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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 (click to expand)
  {
    "identifier": "service",
    "title": "Service",
    "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 (click to expand)
{
  "identifier": "azureDevopsPullRequest",
  "title": "Pull Request",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "status": {
        "title": "Status",
        "type": "string",
        "enum": [
          "completed",
          "abandoned",
          "active"
        ],
        "enumColors": {
          "completed": "yellow",
          "abandoned": "red",
          "active": "green"
        }
      },
      "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": {
    "service": {
      "title": "Service",
      "target": "service",
      "required": false,
      "many": false
    },
    "creator": {
      "title": "Creator",
      "target": "azureDevopsUser",
      "required": false,
      "many": false
    },
    "reviewers": {
      "title": "Reviewers",
      "target": "azureDevopsUser",
      "required": false,
      "many": true
    }
  }
}
Integration mapping (Click to expand)
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: '"service"'
          properties:
            url: .remoteUrl
            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 | ascii_downcase | gsub("[ ();]"; ""))/\(.__repository.name | ascii_downcase | gsub("[ ();]"; ""))"
          blueprint: '"service"'
          properties:
            minimumApproverCount: .settings.minimumApproverCount
  - kind: repository-policy
    selector:
      query: .type.displayName=="Work item linking"
    port:
      entity:
        mappings:
          identifier: >-
            "\(.__repository.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.__repository.name | ascii_downcase | gsub("[ ();]"; ""))"
          blueprint: '"service"'
          properties:
            workItemLinking: .isEnabled and .isBlocking
  - kind: pull-request
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: >-
            "\(.repository.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.repository.name | ascii_downcase | gsub("[ ();]"; ""))/\(.pullRequestId | tostring)"
          blueprint: '"azureDevopsPullRequest"'
          properties:
            status: .status
            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:
            service: >-
              "\(.repository.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.repository.name | ascii_downcase | gsub("[ ();]"; ""))"
            creator: .createdBy.uniqueName
            reviewers: '[.reviewers[].uniqueName]'
- 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โ
The following example demonstrates how to ingest your Azure Devops pipelines to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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 (click to expand)
{
  "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 (click to expand)
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 buildsโ
The following example demonstrates how to ingest your Azure DevOps builds to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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": {}
  }
Build blueprint (click to expand)
{
  "identifier": "build",
  "title": "Build",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "status": {
        "type": "string",
        "title": "Status"
      },
      "result": {
        "type": "string",
        "title": "Result"
      },
      "queueTime": {
        "type": "string",
        "format": "date-time",
        "title": "Queue Time"
      },
      "startTime": {
        "type": "string",
        "format": "date-time",
        "title": "Start Time"
      },
      "finishTime": {
        "type": "string",
        "format": "date-time",
        "title": "Finish Time"
      },
      "definitionName": {
        "type": "string",
        "title": "Definition Name"
      },
      "requestedFor": {
        "type": "string",
        "title": "Requested For"
      },
      "link": {
        "type": "string",
        "format": "url",
        "title": "Link"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "project",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: project
    selector:
      query: 'true'
      defaultTeam: 'false'
    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: build
    selector:
      query: "true"
    port:
      entity:
        mappings:
          identifier: .__project.id + "-" + (.id | tostring) | gsub(" "; "")
          title: .buildNumber
          blueprint: '"build"'
          properties:
            status: .status
            result: .result
            queueTime: .queueTime
            startTime: .startTime
            finishTime: .finishTime
            definitionName: .definition.name
            requestedFor: .requestedFor.displayName
            link: ._links.web.href
          relations:
            project: .__project.id | 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 build object structure.
 
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your builds.
Mapping pipeline stagesโ
The following example demonstrates how to ingest your Azure DevOps pipeline stages to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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": {}
  }
Build blueprint (click to expand)
{
  "identifier": "build",
  "title": "Build",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "status": {
        "type": "string",
        "title": "Status"
      },
      "result": {
        "type": "string",
        "title": "Result"
      },
      "queueTime": {
        "type": "string",
        "format": "date-time",
        "title": "Queue Time"
      },
      "startTime": {
        "type": "string",
        "format": "date-time",
        "title": "Start Time"
      },
      "finishTime": {
        "type": "string",
        "format": "date-time",
        "title": "Finish Time"
      },
      "definitionName": {
        "type": "string",
        "title": "Definition Name"
      },
      "requestedFor": {
        "type": "string",
        "title": "Requested For"
      },
      "link": {
        "type": "string",
        "format": "url",
        "title": "Link"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "project",
      "required": true,
      "many": false
    }
  }
}
Pipeline-stage blueprint (click to expand)
{
  "identifier": "pipeline-stage",
  "title": "Pipeline Stage",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "state": {
        "type": "string",
        "title": "State"
      },
      "result": {
        "type": "string",
        "title": "Result"
      },
      "startTime": {
        "type": "string",
        "format": "date-time",
        "title": "Start Time"
      },
      "finishTime": {
        "type": "string",
        "format": "date-time",
        "title": "Finish Time"
      },
      "stageType": {
        "type": "string",
        "title": "Stage Type"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "project",
      "required": true,
      "many": false
    },
    "build": {
      "title": "Build",
      "target": "build",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: project
    selector:
      query: 'true'
      defaultTeam: 'false'
    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: build
    selector:
      query: "true"
    port:
      entity:
        mappings:
          identifier: .__project.id + "-" + (.id | tostring) | gsub(" "; "")
          title: .buildNumber
          blueprint: '"build"'
          properties:
            status: .status
            result: .result
            queueTime: .queueTime
            startTime: .startTime
            finishTime: .finishTime
            definitionName: .definition.name
            requestedFor: .requestedFor.displayName
            link: ._links.web.href
          relations:
            project: .__project.id | gsub(" "; "")
  - kind: pipeline-stage
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: >-
            .__project.id + "-" + (.__buildId | tostring) + "-" + (.id |
            tostring) | gsub(" "; "")
          title: .name
          blueprint: '"pipeline-stage"'
          properties:
            state: .state
            result: .result
            startTime: .startTime
            finishTime: .finishTime
            stageType: .type
          relations:
            project: .__project.id | gsub(" "; "")
            build: (.__project.id + "-" + (.__buildId | tostring)) | 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-stage object structure.
 
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your pipeline stages.
Mapping pipeline runsโ
The following example demonstrates how to ingest your Azure DevOps pipeline runs to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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-run blueprint (click to expand)
{
  "identifier": "pipeline-run",
  "title": "Pipeline Run",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "state": {
        "type": "string",
        "title": "State"
      },
      "result": {
        "type": "string",
        "title": "Result"
      },
      "createdDate": {
        "type": "string",
        "format": "date-time",
        "title": "Created Date"
      },
      "finishedDate": {
        "type": "string",
        "format": "date-time",
        "title": "Finished Date"
      },
      "pipelineName": {
        "type": "string",
        "title": "Pipeline Name"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "project",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: project
    selector:
      query: 'true'
      defaultTeam: 'false'
    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-run
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: >-
            .__project.id + "-" + (.__pipeline.id | tostring) + "-" + (.id |
            tostring) | gsub(" "; "")
          blueprint: '"pipeline-run"'
          properties:
            state: .state
            result: .result
            createdDate: .createdDate
            finishedDate: .finishedDate
            pipelineName: .pipeline.name
          relations:
            project: .__project.id | 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-run object structure.
 
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your pipeline runs.
Mapping iterationsโ
The following example demonstrates how to ingest your Azure DevOps iterations (sprints, releases, milestones) to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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": {}
  }
Iteration blueprint (click to expand)
{
  "identifier": "iteration",
  "title": "Iteration",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "name": {
        "title": "Name",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The name of the iteration"
      },
      "path": {
        "title": "Path",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The hierarchical path of the iteration"
      },
      "startDate": {
        "title": "Start Date",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The start date of the iteration"
      },
      "finishDate": {
        "title": "Finish Date",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The finish date of the iteration"
      },
      "timeFrame": {
        "title": "Time Frame",
        "type": "string",
        "icon": "Clock",
        "description": "The time frame of the iteration (past, current, future)"
      },
      "link": {
        "title": "Link",
        "type": "string",
        "icon": "AzureDevops",
        "description": "Link to the iteration in Azure DevOps"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "azureDevopsProject",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: project
    selector:
      query: 'true'
      defaultTeam: 'false'
    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: iteration
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .id | gsub(" "; "")
          title: .name
          blueprint: '"iteration"'
          properties:
            name: .name
            path: .path
            startDate: (.attributes.startDate // 0)
            finishDate: (.attributes.finishDate // 0)
            timeFrame: .attributes.timeFrame
            link: .url
          relations:
            project: .__project.id | 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 iteration object structure.
 
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your iterations.
Mapping branchesโ
The following example demonstrates how to ingest your Azure DevOps branches to Port.
You can use the following Port blueprint definitions and integration configuration:
Repository blueprint (click to expand)
  {
    "identifier": "service",
    "title": "Service",
    "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
      }
    }
  }
Branch blueprint (click to expand)
{
  "identifier": "branch",
  "title": "Branch",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "repositoryName": {
        "title": "Repository Name",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The name of the repository that contains this branch"
      },
      "projectName": {
        "title": "Project Name",
        "type": "string",
        "icon": "AzureDevops",
        "description": "The name of the project that contains this branch"
      },
      "link": {
        "title": "Link",
        "type": "string",
        "format": "url",
        "icon": "Link",
        "description": "Link to the branch in Azure DevOps"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "repository": {
      "title": "Repository",
      "target": "service",
      "required": false,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: repository
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: >-
            "\(.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.name | ascii_downcase | gsub("[ ();]"; ""))"
          title: .name
          blueprint: '"service"'
          properties:
            url: .remoteUrl
            readme: file://README.md
            id: .id
            last_activity: .project.lastUpdateTime
          relations:
            project: .project.id | gsub(" "; "")
  - kind: branch
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .objectId
          title: .name
          blueprint: '"branch"'
          properties:
            repositoryName: .__repository.name
            projectName: .__repository.project.name
            link: .__repository.webUrl + "?version=GB" + .name
          relations:
            repository: >-
              "\(.__repository.project.name | ascii_downcase | gsub("[ ();]";
              ""))/\(.__repository.name | ascii_downcase | 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 refs object structure.
 
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your branches.
Mapping test runsโ
- Include Results
 - Code Coverage
 
The includeResults selector allows you to enable fetching detailed test results for each test run. It is set to true by default.
Allowed values:
true: Enable test results for each test run.false: Disable test results for each test run.
  - kind: test-run
    selector:
      query: 'true'
      includeResults: true
The codeCoverage selector allows you to include code coverage data from AzureDevOps Test Runs. It extracts coverage information from pipeline artifacts.
Configuration options:
flags: Value of flags determine the level of code coverage details to be fetched.flagsvalues can benull,1for Modules,2for Functions,4for BlockData (https://learn.microsoft.com/en-us/rest/api/azure/devops/test/code-coverage/get-test-run-code-coverage?view=azure-devops-rest-7.1&tabs=HTTP#testruncoverage).
  - kind: test-run
    selector:
      query: 'true'
      codeCoverage:
        - flags: null
Enabling includeResults or codeCoverage on the test-run kind may significantly slow down your integration. These configs make additional API calls for each test run, which can be very resource-intensive. Consider disabling them to improve performance.
The following example demonstrates how to ingest Azure DevOps test runs to Port. Test runs track test execution results and can include detailed test results and code coverage data.
Project blueprint (click to expand)
  {
    "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": {}
  }
Test Run blueprint (click to expand)
{
  "identifier": "azureDevopsTestRun",
  "title": "Azure DevOps Test Run",
  "icon": "AzureDevops",
  "schema": {
    "properties": {
      "name": {
        "type": "string",
        "title": "Name"
      },
      "state": {
        "type": "string",
        "title": "State"
      },
      "isAutomated": {
        "type": "boolean",
        "title": "Is Automated",
        "description": "Whether the test run is automated"
      },
      "totalTests": {
        "type": "number",
        "title": "Total Tests",
        "description": "Total number of tests in the run"
      },
      "incompleteTests": {
        "type": "number",
        "title": "Incomplete Tests",
        "description": "Number of incomplete tests"
      },
      "notApplicableTests": {
        "type": "number",
        "title": "Not Applicable Tests",
        "description": "Number of not applicable tests"
      },
      "startedDate": {
        "type": "string",
        "format": "date-time",
        "title": "Started Date"
      },
      "completedDate": {
        "type": "string",
        "format": "date-time",
        "title": "Completed Date"
      },
      "totalTests": {
        "type": "number",
        "title": "Total Tests"
      },
      "passedTests": {
        "type": "number",
        "title": "Passed Tests"
      },
      "unanalyzedTests": {
        "type": "number",
        "title": "Unanalyzed Tests",
        "description": "Number of unanalyzed tests"
      },
      "revision": {
        "type": "number",
        "title": "Revision",
        "description": "Revision number of the test run"
      }
    },
    "required": [
      "name",
      "state"
    ]
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "project": {
      "title": "Project",
      "target": "project",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
resources:
  - kind: project
    selector:
      query: 'true'
      defaultTeam: 'false'
    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: test-run
    selector:
      query: 'true'
      includeResults: true  # Set to false to disable fetching detailed test results for each test run
      codeCoverage: 
          - flags: null  # Value of flags determine the level of code coverage details to be fetched. `flags` values can be null, 1 for Modules, 2 for Functions, 4 for BlockData 
            # (https://learn.microsoft.com/en-us/rest/api/azure/devops/test/code-coverage/get-test-run-code-coverage?view=azure-devops-rest-7.1&tabs=HTTP#testruncoverage).
    port:
      entity:
        mappings:
          identifier: .id | tostring
          title: .name
          blueprint: '"azureDevopsTestRun"'
          properties:
            name: .name
            state: .state
            isAutomated: .isAutomated
            totalTests: .totalTests
            incompleteTests: .incompleteTests
            notApplicableTests: .notApplicableTests
            passedTests: .passedTests
            unanalyzedTests: .unanalyzedTests
            revision: .revision
          relations:
            project: .project.id
Click here for the Azure DevOps test-run object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your test runs.
Mapping users and teamsโ
The user kind is only available for Azure DevOps Services. This integration relies on the User Entitlements API, which is not available in Azure DevOps Server.
The following example blueprints and integration configurations demonstrate how to ingest Azure Devops users and teams into Port:
Project blueprint (click to expand)
  {
    "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 (click to expand)
{
  "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 (click to expand)
{
  "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 (Click to expand)
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.
The following example demonstrates how to ingest your Azure Devops teams and their members to Port.
You can use the following Port blueprint definitions and integration configuration:
Project blueprint (click to expand)
  {
    "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 (click to expand)
  {
    "identifier": "service",
    "title": "Service",
    "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 (click to expand)
{
  "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 (click to expand)
{
  "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 (Click to expand)
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: '"service"'
          properties:
            url: .remoteUrl
            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 | ascii_downcase | gsub("[ ();]"; ""))/\(.__repository.name | ascii_downcase | gsub("[ ();]"; ""))"
          blueprint: '"service"'
          properties:
            minimumApproverCount: .settings.minimumApproverCount
  - kind: repository-policy
    selector:
      query: .type.displayName=="Work item linking"
    port:
      entity:
        mappings:
          identifier: >-
            "\(.__repository.project.name | ascii_downcase | gsub("[ ();]"; ""))/\(.__repository.name | ascii_downcase | gsub("[ ();]"; ""))"
          blueprint: '"service"'
          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โ
The following example demonstrates how to ingest your Azure Devops work items to Port.
You can use the following Port blueprint definitions and integration configuration:
Work item blueprint (click to expand)
{
  "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 (Click to expand)
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 (click to expand)
{
  "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 (click to expand)
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 (click to expand)
{
  "identifier": "column",
  "title": "Column",
  "icon": "AzureDevops",
  "schema": {
    "properties": {},
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "board": {
      "title": "board",
      "target": "board",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (Click to expand)
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 (click to expand)
  {
    "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 (click to expand)
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.
Configurationโ
You can use the following Port blueprint definitions and integration configuration:
File blueprint (click to expand)
{
  "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"
      },
      "isFolder": {
        "type": "boolean",
        "title": "Is Folder"
      },
      "extension": {
        "type": "string",
        "title": "Extension"
      }
    },
    "required": ["path"]
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "repository": {
      "title": "Repository",
      "target": "service",
      "required": true,
      "many": false
    }
  }
}
Integration mapping (click to expand)
The selector section within a file resource demonstrates how to configure file ingestion from Azure DevOps repositories. You can control:
- path: Supports both explicit paths (e.g., 
src/config.yaml) and glob patterns (e.g.,**/*.yaml) to ingest matching files. - repos: Target specific repositories or leave blank to scan all repositories.
 
resources:
  - kind: file
    selector:
      query: 'true'
      files:
        # You can use a single explicit path or glob pattern
        path: "src/config.yaml"  # or "src/**/*.yaml"
        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.raw
            link: .repo.remoteUrl + "?path=" + (.file.path)
            isFolder: .file.isFolder
            extension: .file.extension
          relations:
            repository: >-
              "\(.repo.project.name | ascii_downcase | gsub("[ ();]";
              ""))/\(.repo.name | ascii_downcase | gsub("[ ();]"; ""))"
  - kind: file
    selector:
      query: 'true'
      files:
        # You can use explicit paths or glob patterns in an array
        path: # Pass an array of explicit file paths
          - "deployment/helm/values.yaml"
          - "config/settings.json"
          - "docs/**/*.md" # Example: matches all .md files under docs/, including subdirectories
          - "**/package.json" # Example: match all package.json files across folders
    port:
      entity:
        mappings:
          identifier: .repo.name + "/" + .file.objectId
          title: .file.path
          blueprint: '"file"'
          properties:
            path: .file.path
            size: .file.size
            content: .file.content.raw
            link: .repo.remoteUrl + "?path=" + (.file.path)
            isFolder: .file.isFolder
            extension: .file.extension
          relations:
            repository: >-
              "\(.repo.project.name | ascii_downcase | gsub("[ ();]";
              ""))/\(.repo.name | ascii_downcase | gsub("[ ();]"; ""))"
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 repositories and monoreposโ
The following example shows how to ingest your Azure Devops repositories and their folders into Port. By following this example you can map your different repositories, packages and libraries from your monorepo into separate entities in Port.
Note that mapping is configured per project, so you need to create a separate mapping block for each project you want to ingest.
Repository blueprint (click to expand)
  {
    "identifier": "service",
    "title": "Service",
    "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
      }
    }
  }
Port port-app-config.yml (Click to expand)
resources:
  - kind: folder
    selector:
      project_name: 'project_001' # Project name in Azure DevOps that contains the repositories
      query: 'true' # JQ boolean query. If evaluated to false - skip syncing the object.
      folders: # Specify the repositories and folders to include under this relative path.
        - path: src/ # path to the folders within the repositories.
          repos: # List of repositories to include folders from.
            - name: sample_repo  
              branch: main
    port:
      entity:
        mappings:
          identifier: .objectId
          title: .path
          url: .__repository.remoteUrl
          blueprint: '"service"'
          properties:
            defaultBranch: .__repository.defaultBranch
          relations:
            project: .__repository.project.id | gsub(" "; "")
Mapping environmentsโ
The following example demonstrates how to ingest Azure DevOps environments to Port. Environments represent deployment targets in Azure DevOps and are used to track deployments across different stages.
Environment blueprint (click to expand)
  {
    "identifier": "azureDevopsEnvironment",
    "title": "Azure DevOps Environment",
    "icon": "AzureDevops",
    "schema": {
      "properties": {
        "description": {
          "title": "Description",
          "type": "string",
          "icon": "DefaultProperty",
          "description": "The description of the environment"
        },
        "createdOn": {
          "title": "Created On",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the environment was created"
        },
        "lastModifiedOn": {
          "title": "Last Modified On",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the environment was last modified"
        }
      },
      "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {
      "project": {
        "title": "Project",
        "target": "project",
        "required": true,
        "many": false
      }
    }
  }
Integration mapping (click to expand)
resources:
  - kind: environment
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .id | tostring
          title: .name | tostring
          blueprint: '"azureDevopsEnvironment"'
          properties:
            description: .description
            createdOn: .createdOn
            lastModifiedOn: .lastModifiedOn
          relations:
            project: .project.id
Mapping release deploymentsโ
The following example demonstrates how to ingest Azure DevOps release deployments to Port. Release deployments track the deployment of releases to specific environments, providing visibility into your Classic Release pipeline deployments.
Release Deployment blueprint (click to expand)
  {
    "identifier": "azureDevopsReleaseDeployment",
    "title": "Azure DevOps Release Deployment",
    "icon": "AzureDevops",
    "schema": {
      "properties": {
        "status": {
          "title": "Status",
          "type": "string",
          "icon": "DefaultProperty",
          "description": "The deployment status"
        },
        "url": {
          "title": "URL",
          "type": "string",
          "format": "url",
          "icon": "AzureDevops",
          "description": "Link to the deployment in Azure DevOps"
        },
        "reason": {
          "title": "Reason",
          "type": "string",
          "description": "The reason for the deployment"
        },
        "startedOn": {
          "title": "Started On",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the deployment started"
        },
        "completedOn": {
          "title": "Completed On",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the deployment completed"
        },
        "requestedBy": {
          "title": "Requested By",
          "type": "string",
          "icon": "User",
          "description": "The person who requested the deployment"
        },
        "operationStatus": {
          "title": "Operation Status",
          "type": "string",
          "description": "The operation status of the deployment"
        },
        "environment": {
          "title": "Environment",
          "type": "string",
          "description": "The target environment name"
        }
      },
      "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {
      "release": {
        "title": "Release",
        "target": "release",
        "required": true,
        "many": false
      }
    }
  }
Integration mapping (click to expand)
resources:
  - kind: release-deployment
    selector:
      query: 'true'
      includeRelease: true
    port:
      entity:
        mappings:
          identifier: .id | tostring
          title: .release.name + "-" + (.id | tostring) | gsub(" "; "")
          blueprint: '"azureDevopsReleaseDeployment"'
          properties:
            status: .deploymentStatus
            url: .url
            reason: .reason
            startedOn: .startedOn
            completedOn: .completedOn
            requestedBy: .requestedBy.displayName
            operationStatus: .operationStatus
            environment: .releaseEnvironment.name
          relations:
            release: .release.id | tostring
Mapping pipeline deploymentsโ
The following example demonstrates how to ingest Azure DevOps pipeline deployments to Port. Pipeline deployments track deployments from YAML pipelines to environments, providing visibility into your modern CI/CD pipeline deployments.
Pipeline Deployment blueprint (click to expand)
  {
    "identifier": "azureDevopsPipelineDeployment",
    "title": "Azure DevOps Pipeline Deployment",
    "icon": "AzureDevops",
    "schema": {
      "properties": {
        "planType": {
          "title": "Plan Type",
          "type": "string",
          "icon": "DefaultProperty",
          "description": "The type of deployment plan"
        },
        "stageName": {
          "title": "Stage Name",
          "type": "string",
          "description": "The name of the deployment stage"
        },
        "jobName": {
          "title": "Job Name",
          "type": "string",
          "description": "The name of the deployment job"
        },
        "result": {
          "title": "Result",
          "type": "string",
          "description": "The result of the deployment"
        },
        "startTime": {
          "title": "Start Time",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the deployment started"
        },
        "finishTime": {
          "title": "Finish Time",
          "type": "string",
          "format": "date-time",
          "description": "The date and time when the deployment finished"
        }
      },
      "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {
      "environment": {
        "title": "Environment",
        "target": "azureDevopsEnvironment",
        "required": true,
        "many": false
      }
    }
  }
Integration mapping (click to expand)
resources:
  - kind: pipeline-deployment
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .id | tostring
          title: .requestIdentifier | tostring
          blueprint: '"azureDevopsPipelineDeployment"'
          properties:
            planType: .planType
            stageName: .stageName
            jobName: .jobName
            result: .result
            startTime: .startTime
            finishTime: .finishTime
          relations:
            environment: .environment.id | tostring
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:
repositorybranchrepository-policyprojectpull-requestpipelinebuildpipeline-stage(Build timeline)pipeline-runiterationuserteammemberwork-itemboardreleaseenvironmentrelease-deploymentpipeline-deployment(Environment deployment records)test-runfile
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.