> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Azure DevOps Pipelines

Azure DevOps integration actions allow workflows to trigger pipelines and manage pull requests directly using your installed Azure DevOps integration.

Prerequisites

  • An Azure DevOps integration installed in your Port organization in Single Account mode.
  • Actions processing must be enabled on your integration:
    • Hosted by Port / UI installations: actions processing is enabled automatically.
    • Self-hosted (Helm or Docker): actions processing is disabled by default and must be explicitly enabled. See Enable actions processing (self-hosted) below.
  • Your Azure DevOps credentials must be able to perform the operations you invoke:
    • Pipeline actions: queue pipeline runs and manage service hooks (webhooks) used for status reporting.
    • Pull request actions: read and write code in the target repository.
  • For pipeline actions, the pipeline you want to trigger must exist in the target Azure DevOps project.

Enable actions processing (self-hosted)

If you installed the Azure DevOps Ocean integration as hosted by Port (via the UI), actions processing is enabled automatically and you can skip to Configuration.

For self-hosted deployments (Kubernetes/Helm or Docker), the actions processor is disabled by default. You need to enable it explicitly using the flags below, depending on how you deployed the integration:

Pass the following flags when installing or upgrading the Helm chart:

helm upgrade --install azure-devops port-labs/port-ocean \
--set actionsProcessor.enabled=true \
--set liveEvents.baseUrl=<YOUR_INTEGRATION_BASE_URL> \
# ... rest of your values
  • actionsProcessor.enabled=true - enables the actions processor so the integration can receive and execute Azure DevOps pipeline trigger requests from Port.
  • liveEvents.baseUrl=<YOUR_INTEGRATION_BASE_URL> - sets OCEAN__BASE_URL, which is required when reportPipelineStatus is enabled (the default). Port uses this URL to receive webhook events from Azure DevOps and update the action run status in real time. The URL must be reachable from Azure DevOps.
What is reportPipelineStatus?

By default, Port automatically updates the workflow node status when the triggered Azure DevOps pipeline finishes. This requires Azure DevOps to send a pipeline run-state-changed webhook event back to the integration. If the integration's base URL is not set, Port cannot receive this callback and the run status will not be updated automatically.

To disable this behavior, set reportPipelineStatus: false in the execution properties of your action node, or turn off the Report pipeline status toggle in the UI.

Configuration

All Azure DevOps integration actions share the same node structure:

FieldTypeDescription
typestringRequired. Must be "INTEGRATION_ACTION"
installationIdstringRequired. Your Azure DevOps integration installation ID
integrationProviderstringRequired. Must be "azure-devops"
integrationInvocationTypeenumRequired. One of the values listed in available actions
integrationActionExecutionPropertiesobjectRequired. Properties for the selected action

The remaining sections describe the execution properties of each action.

Property value types

Execution properties are validated strictly. Pass strings to string properties (including pullRequestId and line) and booleans to boolean properties. A boolean property that receives the string "true" is rejected.

Available actions

Each action is selected with the integrationInvocationType field:

ActionInvocation typeDescription
Trigger a pipelinetrigger_pipelineQueue a pipeline run and optionally wait for its result
Manage a pull requestcreate_pull_requestOpen a pull request between two branches
Manage a pull requestupdate_pull_requestChange a pull request's title, description, status, target branch, or completion options
Manage a pull requestclose_pull_requestAbandon a pull request without merging it
Manage a pull requestmerge_pull_requestComplete a pull request by merging its source branch
Add a pull request labelupdate_pull_request_labelsAdd a label to a pull request
Create a pull request comment threadcreate_pull_request_threadAdd a comment thread to a pull request, optionally anchored to a file and line

The remaining sections describe the execution properties of each action.

Pipeline actions

Trigger a pipeline

Queues a run of an existing Azure DevOps pipeline. Set integrationInvocationType to trigger_pipeline.

Execution properties

FieldTypeDescription
projectstringRequired. Azure DevOps project name or ID that contains the pipeline
pipelineIdstringRequired. Numeric pipeline ID (for example, 12 from https://dev.azure.com/org/project/_build?definitionId=12)
branchstringBranch (ref) to run the pipeline on (for example, main). When omitted, the pipeline's default branch is used
templateParametersobjectRuntime template parameters declared in the pipeline YAML
variablesobjectQueue-time variables to pass to the pipeline run
reportPipelineStatusbooleanWhether to report pipeline completion status back to Port (default: true)

Basic example

Trigger an Azure DevOps pipeline (click to expand)

Trigger an Azure DevOps pipeline, passing environment and version from the trigger inputs:

{
"identifier": "trigger-azure-devops-pipeline",
"title": "Trigger Azure DevOps Pipeline",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "your-installation-id",
"integrationProvider": "azure-devops",
"integrationInvocationType": "trigger_pipeline",
"integrationActionExecutionProperties": {
"project": "My Project",
"pipelineId": "12",
"branch": "{{ .outputs.trigger.branch }}",
"templateParameters": {
"environment": "{{ .outputs.trigger.environment }}",
"version": "{{ .outputs.trigger.version }}"
}
}
}
}

Template parameters and variables

Template parameters and variables (click to expand)

Pass runtime values into your pipeline with templateParameters and variables. Values can be static or dynamically resolved from workflow outputs:

{
"integrationActionExecutionProperties": {
"project": "My Project",
"pipelineId": "12",
"branch": "main",
"templateParameters": {
"environment": "{{ .outputs.trigger.environment }}",
"version": "{{ .outputs.trigger.version }}"
},
"variables": {
"DRY_RUN": "{{ .outputs.trigger.dryRun | tostring }}"
}
}
}
  • templateParameters map to parameters declared in your Azure Pipelines YAML (parameters:).
  • variables are queue-time variables sent to the Azure DevOps Run Pipeline API.

Status reporting

Status reporting (click to expand)

By default, Port monitors the triggered pipeline and updates the workflow node status when it completes. To opt out:

{
"integrationActionExecutionProperties": {
"project": "My Project",
"pipelineId": "12",
"reportPipelineStatus": false
}
}

When reportPipelineStatus is false, Port does not track the pipeline's completion at all: the node is left in progress after the pipeline is queued, and it is up to you to report its outcome back to Port (for example, from a step in your Azure Pipelines YAML that calls the Port API).

When reportPipelineStatus is true (the default), Port correlates the Azure DevOps ms.vss-pipelines.run-state-changed-event webhook back to the workflow node and reports success or failure when the run completes.

Pull request actions

Manage a pull request

Create, update, close, or merge a pull request.

Opens a pull request between two branches. Set integrationInvocationType to create_pull_request.

Execution properties

FieldTypeDescription
organizationstringRequired. Azure DevOps organization name. Must match the organization configured on the integration
projectstringRequired. Project name or ID that contains the repository
repositoryIdstringRequired. Repository name or ID
titlestringRequired. Title of the new pull request
sourceRefNamestringRequired. Branch to merge from (for example, feature/add-caching or refs/heads/feature/add-caching)
targetRefNamestringRequired. Branch to merge into (for example, main or refs/heads/main)
descriptionstringDescription of the pull request

Branch names are normalized for you, so main and refs/heads/main are equivalent.

Basic example

Create a pull request (click to expand)

Open a pull request from a feature branch into main:

{
"identifier": "open-pull-request",
"title": "Open Pull Request",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "your-installation-id",
"integrationProvider": "azure-devops",
"integrationInvocationType": "create_pull_request",
"integrationActionExecutionProperties": {
"organization": "my-org",
"project": "My Project",
"repositoryId": "my-service",
"title": "{{ .outputs.trigger.title }}",
"sourceRefName": "{{ .outputs.trigger.branch }}",
"targetRefName": "main",
"description": "Opened from Port by {{ .trigger.by.user.email }}"
}
}
}

Add a pull request label

Adds a label to an existing pull request. Set integrationInvocationType to update_pull_request_labels.

Each run adds one label. To apply several labels, use multiple action nodes or run the action more than once.

Execution properties

FieldTypeDescription
organizationstringRequired. Azure DevOps organization name. Must match the organization configured on the integration
projectstringRequired. Project name or ID that contains the repository
repositoryIdstringRequired. Repository name or ID
pullRequestIdstringRequired. ID of the pull request to label
labelstringRequired. Name of the label to add

Basic example

Add a pull request label (click to expand)
{
"identifier": "label-pull-request",
"title": "Add Pull Request Label",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "your-installation-id",
"integrationProvider": "azure-devops",
"integrationInvocationType": "update_pull_request_labels",
"integrationActionExecutionProperties": {
"organization": "my-org",
"project": "My Project",
"repositoryId": "my-service",
"pullRequestId": "{{ .outputs.trigger.pullRequestId }}",
"label": "approved"
}
}
}

Create a pull request comment thread

Adds a comment thread to a pull request. Set integrationInvocationType to create_pull_request_thread.

Execution properties

FieldTypeDescription
projectstringRequired. Project name or ID that contains the repository
repositoryIdstringRequired. Repository name or ID
pullRequestIdstringRequired. ID of the pull request to comment on
contentstringRequired. Body of the first comment in the thread. Supports Markdown
statusstringThread status: active, fixed, wontFix, closed, byDesign, or pending (default: active)
filePathstringPath of the file to anchor the thread to (for example, /src/main.py). When omitted, the thread is not anchored
linestringLine number in filePath to anchor the thread to, starting at 1. Requires filePath. When omitted, the thread is anchored to the file as a whole

Each run creates a new thread, so a node that runs more than once on the same pull request adds a comment each time rather than editing an existing one.

Basic example

Create a pull request comment thread (click to expand)

Post a review summary produced by an earlier AI node, anchored to the file it refers to:

{
"identifier": "comment-on-pull-request",
"title": "Comment on Pull Request",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "your-installation-id",
"integrationProvider": "azure-devops",
"integrationInvocationType": "create_pull_request_thread",
"integrationActionExecutionProperties": {
"project": "My Project",
"repositoryId": "my-service",
"pullRequestId": "{{ .outputs.trigger.pullRequestId }}",
"content": "{{ .outputs.review.summary }}",
"status": "active",
"filePath": "/src/main.py",
"line": "42"
}
}
}

Complete workflow examples

Deploy a service with a pipeline (click to expand)

A self-service deployment workflow that triggers an Azure DevOps pipeline and updates the service entity on completion:

{
"identifier": "deploy-with-azure-devops",
"title": "Deploy Service with Azure DevOps",
"icon": "AzureDevops",
"description": "Trigger a deployment pipeline using Azure DevOps",
"nodes": [
{
"identifier": "trigger",
"title": "Request Deployment",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"service": {
"type": "string",
"format": "entity",
"blueprint": "service",
"title": "Service"
},
"environment": {
"type": "string",
"title": "Environment",
"enum": ["staging", "production"]
},
"version": {
"type": "string",
"title": "Version",
"description": "Git tag or commit SHA"
}
},
"required": ["service", "environment", "version"]
}
}
},
{
"identifier": "trigger-pipeline",
"title": "Trigger Azure DevOps Pipeline",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "ado-integration-123",
"integrationProvider": "azure-devops",
"integrationInvocationType": "trigger_pipeline",
"integrationActionExecutionProperties": {
"project": "My Project",
"pipelineId": "12",
"branch": "{{ .outputs.trigger.version }}",
"templateParameters": {
"environment": "{{ .outputs.trigger.environment }}",
"version": "{{ .outputs.trigger.version }}"
},
"reportPipelineStatus": true
}
}
},
{
"identifier": "update-entity",
"title": "Update Service Status",
"config": {
"type": "UPSERT_ENTITY",
"blueprintIdentifier": "service",
"mapping": {
"identifier": "{{ .outputs.trigger.service }}",
"properties": {
"lastDeployedVersion": "{{ .outputs.trigger.version }}",
"lastDeployedEnvironment": "{{ .outputs.trigger.environment }}",
"lastDeployedAt": "{{ now | todateiso8601 }}"
}
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "trigger-pipeline"
},
{
"sourceIdentifier": "trigger-pipeline",
"targetIdentifier": "update-entity"
}
]
}
Open and announce a pull request (click to expand)

A self-service workflow that opens a pull request and adds a comment thread linking back to the requester:

{
"identifier": "open-pull-request-with-azure-devops",
"title": "Open Pull Request with Azure DevOps",
"icon": "AzureDevops",
"description": "Open a pull request and announce who requested it",
"nodes": [
{
"identifier": "trigger",
"title": "Request Pull Request",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"repository": {
"type": "string",
"title": "Repository"
},
"branch": {
"type": "string",
"title": "Source branch"
},
"title": {
"type": "string",
"title": "Pull request title"
}
},
"required": ["repository", "branch", "title"]
}
}
},
{
"identifier": "create-pr",
"title": "Create Pull Request",
"config": {
"type": "INTEGRATION_ACTION",
"installationId": "ado-integration-123",
"integrationProvider": "azure-devops",
"integrationInvocationType": "create_pull_request",
"integrationActionExecutionProperties": {
"organization": "my-org",
"project": "My Project",
"repositoryId": "{{ .outputs.trigger.repository }}",
"title": "{{ .outputs.trigger.title }}",
"sourceRefName": "{{ .outputs.trigger.branch }}",
"targetRefName": "main",
"description": "Opened from Port by {{ .trigger.by.user.email }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "create-pr"
}
]
}

Limitations

  • Single Account mode only: Azure DevOps integration actions are supported when the integration is configured in Single Account mode. Multi-account (service principal across many organizations) is not supported for these actions yet.
  • Run expiry: Runs that remain unprocessed for more than 3 hours are automatically expired and will not be executed.