Trigger Azure DevOps pipelines in non-default branch
By default, Azure DevOps pipelines triggered through Port self-service actions run from the repository's default branch (typically main
or master
).
We will demonstrate how to configure your action to trigger pipelines from a specific non-default branch.
Understanding the challenge
- Azure DevOps webhook triggers don't automatically handle branch specification like GitHub.
- The pipeline YAML file location and the branch to run from need to be explicitly defined.
- The API payload structure requires specific
refName
formatting.
Solution overview
To trigger Azure DevOps pipelines in a non-default branch, you need to:
- Add a branch input to your self-service action (optional - for user selection).
- Configure the webhook payload to include the correct
refName
parameter. - Ensure your pipeline YAML exists in the target branch.
Implementation methods
- Fixed branch
- User-selectable branch
- Dynamic branch selection
Use this approach when you always want to trigger from a specific branch.
Step 1: Configure the action backend
In your self-service action configuration, use the webhook backend with a payload that specifies the target branch:
{
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://dev.azure.com/{{.secrets.AZURE_DEVOPS_ORG}}/{{.secrets.AZURE_DEVOPS_PROJECT}}/_apis/pipelines/{{.secrets.PIPELINE_ID}}/runs?api-version=7.1",
"agent": false,
"synchronized": true,
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic {{.secrets.AZURE_DEVOPS_PAT_BASE64}}"
},
"body": {
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/feature/my-feature-branch"
}
}
},
"templateParameters": {
"{{ spreadValue() }}": "{{ .inputs }}"
},
"variables": {
"PORT_RUN_ID": {
"value": "{{ .run.id }}"
}
}
}
}
}
Step 2: Set up secrets
Add the following secrets to your Port organization:
AZURE_DEVOPS_ORG
: Your Azure DevOps organization name.AZURE_DEVOPS_PROJECT
: Your project name.PIPELINE_ID
: The numeric ID of your pipeline.AZURE_DEVOPS_PAT_BASE64
: Base64 encoded Personal Access Token.
You can find your pipeline ID in the Azure DevOps URL when viewing the pipeline:
https://dev.azure.com/{org}/{project}/_build?definitionId={PIPELINE_ID}
Use this approach when you want users to choose which branch to trigger.
Step 1: Add branch input to your action
Add a branch selection input to your action's user interface:
{
"userInputs": {
"properties": {
"target_branch": {
"title": "Target Branch",
"type": "string",
"enum": [
"main",
"develop",
"feature/deployment",
"hotfix/critical-fix"
],
"default": "main",
"description": "Select the branch to run the pipeline from"
}
// ... other inputs
}
}
}
Step 2: Use the input in the webhook payload
Reference the user input in your webhook body:
{
"body": {
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/{{ .inputs.target_branch }}"
}
}
},
"templateParameters": {
"{{ spreadValue() }}": "{{ .inputs }}"
}
}
}
For advanced use cases, you can use JQ expressions to dynamically determine the branch:
{
"body": {
"resources": {
"repositories": {
"self": {
"refName": "{{ if .trigger.operation == \"CREATE\" then \"refs/heads/main\" elif .inputs.environment == \"staging\" then \"refs/heads/develop\" else \"refs/heads/feature/\" + .inputs.feature_name end }}"
}
}
}
}
}
This approach is useful when you need to:
- Route different operations to different branches.
- Use environment-specific branches (staging → develop, production → main).
- Create dynamic branch names based on user inputs.
Complete example
Here's a complete self-service action that allows users to deploy from different branches:
Complete action JSON
{
"identifier": "deploy_to_environment",
"title": "Deploy to Environment",
"icon": "Azure",
"description": "Deploy application to specified environment from selected branch",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {
"environment": {
"title": "Environment",
"type": "string",
"enum": ["staging", "production"],
"enumColors": {
"staging": "orange",
"production": "red"
}
},
"target_branch": {
"title": "Branch",
"type": "string",
"enum": ["main", "develop", "feature/latest"],
"default": "main"
},
"deployment_notes": {
"title": "Deployment Notes",
"type": "string",
"description": "Optional notes for this deployment"
}
},
"required": ["environment", "target_branch"],
"order": ["environment", "target_branch", "deployment_notes"]
},
"blueprintIdentifier": "service"
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://dev.azure.com/{{.secrets.AZURE_DEVOPS_ORG}}/{{.secrets.AZURE_DEVOPS_PROJECT}}/_apis/pipelines/{{.secrets.DEPLOYMENT_PIPELINE_ID}}/runs?api-version=7.1",
"agent": false,
"synchronized": true,
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic {{.secrets.AZURE_DEVOPS_PAT_BASE64}}"
},
"body": {
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/{{ .inputs.target_branch }}"
}
}
},
"templateParameters": {
"environment": "{{ .inputs.environment }}",
"deployment_notes": "{{ .inputs.deployment_notes }}",
"triggered_by": "{{ .trigger.by.user.email }}",
"port_run_id": "{{ .run.id }}"
},
"variables": {
"ENVIRONMENT": {
"value": "{{ .inputs.environment }}"
},
"PORT_RUN_ID": {
"value": "{{ .run.id }}"
}
}
}
},
"requiredApproval": false
}
Pipeline YAML considerations
Ensure your pipeline YAML file exists in the target branch and is configured to handle webhook triggers:
# Disable automatic CI triggers since we're using webhooks
trigger: none
# Define the webhook resource
resources:
webhooks:
- webhook: port_trigger
connection: port_trigger # Your service connection name
# Pipeline parameters (optional)
parameters:
- name: environment
type: string
default: 'staging'
- name: deployment_notes
type: string
default: ''
variables:
- name: targetEnvironment
value: ${{ parameters.environment }}
stages:
- stage: Deploy
jobs:
- job: DeployJob
steps:
- script: |
echo "Deploying to: $(targetEnvironment)"
echo "Branch: $(Build.SourceBranch)"
echo "Notes: ${{ parameters.deployment_notes }}"
echo "Port Run ID: $(PORT_RUN_ID)"
displayName: 'Deploy Application'
# Add your actual deployment steps here
- script: |
# Your deployment logic
echo "Deployment completed successfully"
displayName: 'Run Deployment'
Troubleshoot
You can find more information on how to troubleshoot Azure DevOps pipelines in our troubleshooting guide.