Skip to content

Commit cad3035

Browse files
feat: azdo trigger changed from sdk to api call (#72)
* converted action trigger azdo into python * added check for pat into azure devops trigger
1 parent b825ee1 commit cad3035

File tree

4 files changed

+343
-32
lines changed

4 files changed

+343
-32
lines changed

azure-devops-trigger-pipeline/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ the PAT which is personal to a user (we still can't have a bot) and must have th
1212

1313
## how to use
1414

15+
* `azure_template_parameters` is a json string that will be passed to the Azure DevOps pipeline as parameters.
16+
1517
```yaml
1618
azure-devops-trigger:
1719
name: 🅰️ Azure DevOps Pipeline Trigger
Lines changed: 147 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,160 @@
1-
name: 🅰️ Azure Devops pipeline trigger
2-
description: 🅰️ Azure Devops pipeline trigger
3-
1+
# action.yml
2+
name: 'Azure DevOps Pipeline Trigger'
3+
description: 'Triggers an Azure DevOps pipeline with template parameters'
44
inputs:
55
enable_azure_devops_step:
6-
description: Are azure devops triggers enabled?
7-
default: "false"
6+
description: 'Enable or disable the Azure DevOps step'
7+
required: true
8+
default: 'true'
89
azure_devops_project_url:
9-
description: Azure devops project url like (e.g. `https://dev.azure.com/pagopaspa/arc-projects``)
10+
description: 'Azure DevOps project URL'
11+
required: true
1012
azure_devops_pipeline_name:
11-
description: Pipeline name inside the project (e.g. `arc-cittadini-deploy-aks.deploy`)
13+
description: 'Name of the Azure DevOps pipeline to trigger'
14+
required: true
1215
azure_devops_pat:
13-
description: Personal secret azure devops PAT
14-
default: ''
16+
description: 'Azure DevOps Personal Access Token'
17+
required: true
1518
azure_template_parameters:
16-
description: Json attribute with all the parameters that must be send to the pipeline. See README for example (⚠️ this parameters must exists)
19+
description: 'Template parameters in JSON format'
20+
required: false
21+
default: '{}'
1722

1823
runs:
19-
using: "composite"
24+
using: 'composite'
2025
steps:
21-
22-
#
23-
# AZDO
24-
#
25-
- name: 🤔 Check azure_devops_pat
26-
if: ${{ inputs.enable_azure_devops_step == 'true' }}
26+
- name: Set up Python
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: '3.10'
30+
31+
- name: Install dependencies
2732
shell: bash
33+
run: pip install requests
34+
35+
- name: Run Pipeline Trigger
36+
shell: python
37+
env:
38+
INPUT_ENABLE_AZURE_DEVOPS_STEP: ${{ inputs.enable_azure_devops_step }}
39+
INPUT_AZURE_DEVOPS_PROJECT_URL: ${{ inputs.azure_devops_project_url }}
40+
INPUT_AZURE_DEVOPS_PIPELINE_NAME: ${{ inputs.azure_devops_pipeline_name }}
41+
INPUT_AZURE_DEVOPS_PAT: ${{ inputs.azure_devops_pat }}
42+
INPUT_AZURE_TEMPLATE_PARAMETERS: ${{ inputs.azure_template_parameters }}
2843
run: |
29-
if [ -z "${{ inputs.azure_devops_pat }}" ]; then
30-
echo "Error: azure_devops_pat is empty. This is required for triggering the Azure DevOps pipeline."
31-
exit 1
32-
fi
44+
import os
45+
import json
46+
import sys
47+
from urllib.parse import urlparse
48+
import requests
49+
import base64
50+
51+
def log_info(message): print(f"ℹ️ {message}")
52+
def log_success(message): print(f"✅ {message}")
53+
def log_warning(message): print(f"⚠️ {message}")
54+
def log_error(message): print(f"❌ {message}")
55+
def log_start(message): print(f"🚀 {message}")
56+
def log_config(message): print(f"⚙️ {message}")
57+
def log_api(message): print(f"🔌 {message}")
3358
34-
echo "🔨 Start launch trigger with Azure Devops"
59+
def get_project_info(project_url):
60+
"""Extract organization and project from Azure DevOps URL"""
61+
log_info(f"Parsing project URL: {project_url}")
62+
parts = urlparse(project_url).path.strip('/').split('/')
63+
org, project = parts[0], parts[1]
64+
log_success(f"Found organization: {org} and project: {project}")
65+
return org, project
3566
36-
- name: 🚂 Trigger Azure DevOps pipeline
37-
if: inputs.enable_azure_devops_step == 'true'
38-
# https://github.com/pagopa/azure-pipelines/releases/tag/v2.0.0
39-
uses: pagopa/azure-pipelines@51d971651241601a348e4e2ed2431b8b7576d4f0
40-
with:
41-
azure-devops-project-url: ${{ inputs.azure_devops_project_url }}
42-
azure-pipeline-name: ${{ inputs.azure_devops_pipeline_name }}
43-
azure-devops-token: ${{ inputs.azure_devops_pat }}
44-
azure-pipeline-variables: '{"system.debug": "true"}'
45-
azure-template-parameters: ${{ inputs.azure_template_parameters }}
67+
def get_pipeline_id(org, project, pipeline_name, auth_header):
68+
"""Get pipeline ID from name"""
69+
log_api(f"Getting pipeline ID for: {pipeline_name}")
70+
url = f"https://dev.azure.com/{org}/{project}/_apis/pipelines?api-version=7.1"
71+
72+
response = requests.get(url, headers=auth_header)
73+
if response.status_code != 200:
74+
log_error(f"Failed to get pipeline list: {response.text}")
75+
sys.exit(1)
76+
77+
pipelines = response.json()['value']
78+
for pipeline in pipelines:
79+
if pipeline['name'] == pipeline_name:
80+
log_success(f"Found pipeline ID: {pipeline['id']}")
81+
return pipeline['id']
82+
83+
log_error(f"Pipeline {pipeline_name} not found")
84+
sys.exit(1)
85+
86+
def trigger_pipeline(org, project, pipeline_id, template_params, auth_header):
87+
"""Trigger the pipeline with template parameters"""
88+
log_start("Triggering pipeline...")
89+
url = f"https://dev.azure.com/{org}/{project}/_apis/pipelines/{pipeline_id}/runs?api-version=7.1"
90+
91+
# Pretty print template parameters for logging
92+
log_config("Template parameters:")
93+
print(json.dumps(template_params, indent=2))
94+
95+
body = {
96+
"templateParameters": template_params,
97+
"resources": {
98+
"repositories": {
99+
"self": {
100+
"refName": "refs/heads/main"
101+
}
102+
}
103+
}
104+
}
105+
106+
log_api("Making API request to Azure DevOps...")
107+
response = requests.post(url, headers=auth_header, json=body)
108+
return response
109+
110+
# Main execution
111+
log_start("Starting Azure DevOps Pipeline Trigger")
112+
113+
# Check if step is enabled
114+
if os.environ['INPUT_ENABLE_AZURE_DEVOPS_STEP'].lower() != 'true':
115+
log_warning("Step is disabled. Skipping...")
116+
sys.exit(0)
117+
118+
try:
119+
# Get inputs
120+
project_url = os.environ['INPUT_AZURE_DEVOPS_PROJECT_URL']
121+
pipeline_name = os.environ['INPUT_AZURE_DEVOPS_PIPELINE_NAME']
122+
pat = os.environ['INPUT_AZURE_DEVOPS_PAT']
123+
124+
# Validate PAT token
125+
if not pat or pat.isspace():
126+
log_error("Azure DevOps PAT token cannot be empty or null")
127+
sys.exit(1)
128+
129+
template_params = json.loads(os.environ['INPUT_AZURE_TEMPLATE_PARAMETERS'])
130+
131+
# Create auth header
132+
auth_token = base64.b64encode(f":{pat}".encode()).decode()
133+
auth_header = {
134+
"Authorization": f"Basic {auth_token}",
135+
"Content-Type": "application/json"
136+
}
137+
log_config("Authentication configured")
138+
139+
# Get organization and project
140+
org, project = get_project_info(project_url)
141+
142+
# Get pipeline ID
143+
pipeline_id = get_pipeline_id(org, project, pipeline_name, auth_header)
144+
145+
# Trigger pipeline
146+
response = trigger_pipeline(org, project, pipeline_id, template_params, auth_header)
147+
148+
if response.status_code == 200:
149+
log_success("Pipeline triggered successfully! 🎉")
150+
print("\nPipeline details:")
151+
print(json.dumps(response.json(), indent=2))
152+
else:
153+
log_error(f"Failed to trigger pipeline: {response.text}")
154+
sys.exit(1)
155+
156+
except Exception as e:
157+
log_error(f"An error occurred: {str(e)}")
158+
sys.exit(1)
159+
160+
log_success("Pipeline trigger completed successfully! 🏁")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"APPS_TOP": "[one-color]",
3+
"ARGOCD_TARGET_BRANCH": "tmp",
4+
"POSTMAN_BRANCH": "develop1",
5+
"TRIGGER_MESSAGE": "p4pa-auth"
6+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/bin/bash
2+
3+
# ======================================
4+
# Azure DevOps Pipeline Trigger Script
5+
# ======================================
6+
#
7+
# DESCRIZIONE:
8+
# Questo script si occupa di triggerare una pipeline Azure DevOps tramite API REST.
9+
#
10+
# PREREQUISITI:
11+
# - curl installato
12+
# - jq installato (opzionale, per formattare l'output JSON)
13+
#
14+
# CONFIGURAZIONE:
15+
# 1. Genera un Personal Access Token (PAT) in Azure DevOps:
16+
# - Vai su https://dev.azure.com/{organization}/_usersSettings/tokens
17+
# - Crea un nuovo token con i permessi "Build (read and execute)"
18+
#
19+
# 2. Esporta il PAT come variabile d'ambiente:
20+
# export AZDO_PAT="il-tuo-pat-token"
21+
#
22+
# 3. Configura i template parameters in uno dei seguenti modi:
23+
#
24+
# A) Usando un file JSON (params.json):
25+
# {
26+
# "APPS_TOP": "[one-color]",
27+
# "ARGOCD_TARGET_BRANCH": "tmp",
28+
# "POSTMAN_BRANCH": "develop",
29+
# "TRIGGER_MESSAGE": "p4pa-auth"
30+
# }
31+
#
32+
# B) Tramite variabile d'ambiente:
33+
# export AZDO_TEMPLATE_PARAMETERS='{"APPS_TOP":"[one-color]"}'
34+
#
35+
# 4. Modifica le variabili di configurazione sotto secondo le tue necessità
36+
#
37+
# UTILIZZO:
38+
# ./trigger-pipeline.sh [path/to/params.json]
39+
#
40+
# ======================================
41+
42+
# Exit on error
43+
set -e
44+
45+
# ===================
46+
# CONFIGURAZIONE
47+
# ===================
48+
AZDO_ORGANIZATION="pagopaspa"
49+
AZDO_PROJECT="p4pa-projects"
50+
AZDO_PIPELINE_ID="2111"
51+
AZDO_BRANCH="main" # Branch da utilizzare per il trigger
52+
53+
# Logging function
54+
log() {
55+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
56+
echo "[$timestamp] $1"
57+
}
58+
59+
# Function to load template parameters
60+
load_template_parameters() {
61+
# Se viene fornito un file come argomento
62+
if [ -n "$1" ]; then
63+
if [ ! -f "$1" ]; then
64+
log "ERROR: File $1 non trovato"
65+
exit 1
66+
fi
67+
68+
# Verifica che il file contenga JSON valido
69+
if ! jq . "$1" >/dev/null 2>&1; then
70+
log "ERROR: Il file $1 non contiene JSON valido"
71+
exit 1
72+
fi
73+
74+
AZDO_TEMPLATE_PARAMETERS=$(cat "$1")
75+
log "Template parameters caricati dal file: $1"
76+
else
77+
# Se non c'è un file, verifica la variabile d'ambiente
78+
if [ -z "$AZDO_TEMPLATE_PARAMETERS" ]; then
79+
log "ERROR: Nessun template parameter fornito. Puoi fornirli in due modi:"
80+
log "1. Passando un file JSON come argomento: ./trigger-pipeline.sh params.json"
81+
log "2. Impostando la variabile d'ambiente AZDO_TEMPLATE_PARAMETERS"
82+
exit 1
83+
fi
84+
85+
# Verifica che la variabile d'ambiente contenga JSON valido
86+
if ! echo "$AZDO_TEMPLATE_PARAMETERS" | jq . >/dev/null 2>&1; then
87+
log "ERROR: AZDO_TEMPLATE_PARAMETERS non contiene JSON valido"
88+
exit 1
89+
fi
90+
91+
log "Template parameters caricati da variabile d'ambiente"
92+
fi
93+
94+
# Mostra i parameters caricati
95+
log "Parameters configurati:"
96+
echo "$AZDO_TEMPLATE_PARAMETERS" | jq .
97+
}
98+
99+
# Function to check required variables
100+
check_pat() {
101+
if [ -z "$AZDO_PAT" ]; then
102+
log "ERROR: AZDO_PAT non impostato. Per favore impostalo usando:"
103+
log "export AZDO_PAT=your-pat-token"
104+
exit 1
105+
fi
106+
}
107+
108+
# Function to trigger pipeline
109+
trigger_pipeline() {
110+
local api_version="7.1"
111+
112+
# Create auth token
113+
local auth_token=$(echo -n ":$AZDO_PAT" | base64)
114+
115+
# Log execution start
116+
log "Triggering pipeline sul branch: $AZDO_BRANCH"
117+
118+
# Prepare API URL
119+
local api_url="https://dev.azure.com/$AZDO_ORGANIZATION/$AZDO_PROJECT/_apis/pipelines/$AZDO_PIPELINE_ID/runs?api-version=$api_version"
120+
121+
# Prepare request body
122+
# Template parameters example:
123+
# {
124+
# "APPS_TOP": "[one-color]",
125+
# "ARGOCD_TARGET_BRANCH": "tmp",
126+
# "POSTMAN_BRANCH": "develop",
127+
# "TRIGGER_MESSAGE": "p4pa-auth"
128+
# }
129+
local request_body=$(cat <<EOF
130+
{
131+
"templateParameters": $AZDO_TEMPLATE_PARAMETERS,
132+
"resources": {
133+
"repositories": {
134+
"self": {
135+
"refName": "refs/heads/$AZDO_BRANCH"
136+
}
137+
}
138+
}
139+
}
140+
EOF
141+
)
142+
143+
# Make API call
144+
log "Chiamata API Azure DevOps in corso..."
145+
local response=$(curl -s -w "\n%{http_code}" \
146+
-X POST "$api_url" \
147+
-H "Authorization: Basic $auth_token" \
148+
-H "Content-Type: application/json" \
149+
-d "$request_body")
150+
151+
# Extract status code and response body
152+
local status_code=$(echo "$response" | tail -n1)
153+
local response_body=$(echo "$response" | sed '$d')
154+
155+
# Check response
156+
if [ "$status_code" -eq 200 ]; then
157+
log "SUCCESS: Pipeline triggerata con successo"
158+
# Check if jq is available for JSON formatting
159+
if command -v jq &> /dev/null; then
160+
echo "$response_body" | jq .
161+
else
162+
echo "$response_body"
163+
fi
164+
else
165+
log "ERROR: Errore durante il trigger della pipeline. Status code: $status_code"
166+
log "Response: $response_body"
167+
exit 1
168+
fi
169+
}
170+
171+
# Main script execution
172+
main() {
173+
log "Avvio script trigger pipeline"
174+
175+
# Check PAT token
176+
check_pat
177+
178+
# Load template parameters
179+
load_template_parameters "$1"
180+
181+
# Trigger pipeline
182+
trigger_pipeline
183+
184+
log "Esecuzione script completata"
185+
}
186+
187+
# Execute main function with first argument
188+
main "$1"

0 commit comments

Comments
 (0)