Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions azure-devops-trigger-pipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ the PAT which is personal to a user (we still can't have a bot) and must have th

## how to use

* `azure_template_parameters` is a json string that will be passed to the Azure DevOps pipeline as parameters.

```yaml
azure-devops-trigger:
name: 🅰️ Azure DevOps Pipeline Trigger
Expand Down
179 changes: 147 additions & 32 deletions azure-devops-trigger-pipeline/action.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,160 @@
name: 🅰️ Azure Devops pipeline trigger
description: 🅰️ Azure Devops pipeline trigger

# action.yml
name: 'Azure DevOps Pipeline Trigger'
description: 'Triggers an Azure DevOps pipeline with template parameters'
inputs:
enable_azure_devops_step:
description: Are azure devops triggers enabled?
default: "false"
description: 'Enable or disable the Azure DevOps step'
required: true
default: 'true'
azure_devops_project_url:
description: Azure devops project url like (e.g. `https://dev.azure.com/pagopaspa/arc-projects``)
description: 'Azure DevOps project URL'
required: true
azure_devops_pipeline_name:
description: Pipeline name inside the project (e.g. `arc-cittadini-deploy-aks.deploy`)
description: 'Name of the Azure DevOps pipeline to trigger'
required: true
azure_devops_pat:
description: Personal secret azure devops PAT
default: ''
description: 'Azure DevOps Personal Access Token'
required: true
azure_template_parameters:
description: Json attribute with all the parameters that must be send to the pipeline. See README for example (⚠️ this parameters must exists)
description: 'Template parameters in JSON format'
required: false
default: '{}'

runs:
using: "composite"
using: 'composite'
steps:

#
# AZDO
#
- name: 🤔 Check azure_devops_pat
if: ${{ inputs.enable_azure_devops_step == 'true' }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
shell: bash
run: pip install requests

- name: Run Pipeline Trigger
shell: python
env:
INPUT_ENABLE_AZURE_DEVOPS_STEP: ${{ inputs.enable_azure_devops_step }}
INPUT_AZURE_DEVOPS_PROJECT_URL: ${{ inputs.azure_devops_project_url }}
INPUT_AZURE_DEVOPS_PIPELINE_NAME: ${{ inputs.azure_devops_pipeline_name }}
INPUT_AZURE_DEVOPS_PAT: ${{ inputs.azure_devops_pat }}
INPUT_AZURE_TEMPLATE_PARAMETERS: ${{ inputs.azure_template_parameters }}
run: |
if [ -z "${{ inputs.azure_devops_pat }}" ]; then
echo "Error: azure_devops_pat is empty. This is required for triggering the Azure DevOps pipeline."
exit 1
fi
import os
import json
import sys
from urllib.parse import urlparse
import requests
import base64

def log_info(message): print(f"ℹ️ {message}")
def log_success(message): print(f"✅ {message}")
def log_warning(message): print(f"⚠️ {message}")
def log_error(message): print(f"❌ {message}")
def log_start(message): print(f"🚀 {message}")
def log_config(message): print(f"⚙️ {message}")
def log_api(message): print(f"🔌 {message}")

echo "🔨 Start launch trigger with Azure Devops"
def get_project_info(project_url):
"""Extract organization and project from Azure DevOps URL"""
log_info(f"Parsing project URL: {project_url}")
parts = urlparse(project_url).path.strip('/').split('/')
org, project = parts[0], parts[1]
log_success(f"Found organization: {org} and project: {project}")
return org, project

- name: 🚂 Trigger Azure DevOps pipeline
if: inputs.enable_azure_devops_step == 'true'
# https://github.com/pagopa/azure-pipelines/releases/tag/v2.0.0
uses: pagopa/azure-pipelines@51d971651241601a348e4e2ed2431b8b7576d4f0
with:
azure-devops-project-url: ${{ inputs.azure_devops_project_url }}
azure-pipeline-name: ${{ inputs.azure_devops_pipeline_name }}
azure-devops-token: ${{ inputs.azure_devops_pat }}
azure-pipeline-variables: '{"system.debug": "true"}'
azure-template-parameters: ${{ inputs.azure_template_parameters }}
def get_pipeline_id(org, project, pipeline_name, auth_header):
"""Get pipeline ID from name"""
log_api(f"Getting pipeline ID for: {pipeline_name}")
url = f"https://dev.azure.com/{org}/{project}/_apis/pipelines?api-version=7.1"

response = requests.get(url, headers=auth_header)
if response.status_code != 200:
log_error(f"Failed to get pipeline list: {response.text}")
sys.exit(1)

pipelines = response.json()['value']
for pipeline in pipelines:
if pipeline['name'] == pipeline_name:
log_success(f"Found pipeline ID: {pipeline['id']}")
return pipeline['id']

log_error(f"Pipeline {pipeline_name} not found")
sys.exit(1)

def trigger_pipeline(org, project, pipeline_id, template_params, auth_header):
"""Trigger the pipeline with template parameters"""
log_start("Triggering pipeline...")
url = f"https://dev.azure.com/{org}/{project}/_apis/pipelines/{pipeline_id}/runs?api-version=7.1"

# Pretty print template parameters for logging
log_config("Template parameters:")
print(json.dumps(template_params, indent=2))

body = {
"templateParameters": template_params,
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/main"
}
}
}
}

log_api("Making API request to Azure DevOps...")
response = requests.post(url, headers=auth_header, json=body)
return response

# Main execution
log_start("Starting Azure DevOps Pipeline Trigger")

# Check if step is enabled
if os.environ['INPUT_ENABLE_AZURE_DEVOPS_STEP'].lower() != 'true':
log_warning("Step is disabled. Skipping...")
sys.exit(0)

try:
# Get inputs
project_url = os.environ['INPUT_AZURE_DEVOPS_PROJECT_URL']
pipeline_name = os.environ['INPUT_AZURE_DEVOPS_PIPELINE_NAME']
pat = os.environ['INPUT_AZURE_DEVOPS_PAT']

# Validate PAT token
if not pat or pat.isspace():
log_error("Azure DevOps PAT token cannot be empty or null")
sys.exit(1)

template_params = json.loads(os.environ['INPUT_AZURE_TEMPLATE_PARAMETERS'])

# Create auth header
auth_token = base64.b64encode(f":{pat}".encode()).decode()
auth_header = {
"Authorization": f"Basic {auth_token}",
"Content-Type": "application/json"
}
log_config("Authentication configured")

# Get organization and project
org, project = get_project_info(project_url)

# Get pipeline ID
pipeline_id = get_pipeline_id(org, project, pipeline_name, auth_header)

# Trigger pipeline
response = trigger_pipeline(org, project, pipeline_id, template_params, auth_header)

if response.status_code == 200:
log_success("Pipeline triggered successfully! 🎉")
print("\nPipeline details:")
print(json.dumps(response.json(), indent=2))
else:
log_error(f"Failed to trigger pipeline: {response.text}")
sys.exit(1)

except Exception as e:
log_error(f"An error occurred: {str(e)}")
sys.exit(1)

log_success("Pipeline trigger completed successfully! 🏁")
6 changes: 6 additions & 0 deletions azure-devops-trigger-pipeline/params.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"APPS_TOP": "[one-color]",
"ARGOCD_TARGET_BRANCH": "tmp",
"POSTMAN_BRANCH": "develop1",
"TRIGGER_MESSAGE": "p4pa-auth"
}
188 changes: 188 additions & 0 deletions azure-devops-trigger-pipeline/trigger-azdo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#!/bin/bash

# ======================================
# Azure DevOps Pipeline Trigger Script
# ======================================
#
# DESCRIZIONE:
# Questo script si occupa di triggerare una pipeline Azure DevOps tramite API REST.
#
# PREREQUISITI:
# - curl installato
# - jq installato (opzionale, per formattare l'output JSON)
#
# CONFIGURAZIONE:
# 1. Genera un Personal Access Token (PAT) in Azure DevOps:
# - Vai su https://dev.azure.com/{organization}/_usersSettings/tokens
# - Crea un nuovo token con i permessi "Build (read and execute)"
#
# 2. Esporta il PAT come variabile d'ambiente:
# export AZDO_PAT="il-tuo-pat-token"
#
# 3. Configura i template parameters in uno dei seguenti modi:
#
# A) Usando un file JSON (params.json):
# {
# "APPS_TOP": "[one-color]",
# "ARGOCD_TARGET_BRANCH": "tmp",
# "POSTMAN_BRANCH": "develop",
# "TRIGGER_MESSAGE": "p4pa-auth"
# }
#
# B) Tramite variabile d'ambiente:
# export AZDO_TEMPLATE_PARAMETERS='{"APPS_TOP":"[one-color]"}'
#
# 4. Modifica le variabili di configurazione sotto secondo le tue necessità
#
# UTILIZZO:
# ./trigger-pipeline.sh [path/to/params.json]
#
# ======================================

# Exit on error
set -e

# ===================
# CONFIGURAZIONE
# ===================
AZDO_ORGANIZATION="pagopaspa"
AZDO_PROJECT="p4pa-projects"
AZDO_PIPELINE_ID="2111"
AZDO_BRANCH="main" # Branch da utilizzare per il trigger

# Logging function
log() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] $1"
}

# Function to load template parameters
load_template_parameters() {
# Se viene fornito un file come argomento
if [ -n "$1" ]; then
if [ ! -f "$1" ]; then
log "ERROR: File $1 non trovato"
exit 1
fi

# Verifica che il file contenga JSON valido
if ! jq . "$1" >/dev/null 2>&1; then
log "ERROR: Il file $1 non contiene JSON valido"
exit 1
fi

AZDO_TEMPLATE_PARAMETERS=$(cat "$1")
log "Template parameters caricati dal file: $1"
else
# Se non c'è un file, verifica la variabile d'ambiente
if [ -z "$AZDO_TEMPLATE_PARAMETERS" ]; then
log "ERROR: Nessun template parameter fornito. Puoi fornirli in due modi:"
log "1. Passando un file JSON come argomento: ./trigger-pipeline.sh params.json"
log "2. Impostando la variabile d'ambiente AZDO_TEMPLATE_PARAMETERS"
exit 1
fi

# Verifica che la variabile d'ambiente contenga JSON valido
if ! echo "$AZDO_TEMPLATE_PARAMETERS" | jq . >/dev/null 2>&1; then
log "ERROR: AZDO_TEMPLATE_PARAMETERS non contiene JSON valido"
exit 1
fi

log "Template parameters caricati da variabile d'ambiente"
fi

# Mostra i parameters caricati
log "Parameters configurati:"
echo "$AZDO_TEMPLATE_PARAMETERS" | jq .
}

# Function to check required variables
check_pat() {
if [ -z "$AZDO_PAT" ]; then
log "ERROR: AZDO_PAT non impostato. Per favore impostalo usando:"
log "export AZDO_PAT=your-pat-token"
exit 1
fi
}

# Function to trigger pipeline
trigger_pipeline() {
local api_version="7.1"

# Create auth token
local auth_token=$(echo -n ":$AZDO_PAT" | base64)

# Log execution start
log "Triggering pipeline sul branch: $AZDO_BRANCH"

# Prepare API URL
local api_url="https://dev.azure.com/$AZDO_ORGANIZATION/$AZDO_PROJECT/_apis/pipelines/$AZDO_PIPELINE_ID/runs?api-version=$api_version"

# Prepare request body
# Template parameters example:
# {
# "APPS_TOP": "[one-color]",
# "ARGOCD_TARGET_BRANCH": "tmp",
# "POSTMAN_BRANCH": "develop",
# "TRIGGER_MESSAGE": "p4pa-auth"
# }
local request_body=$(cat <<EOF
{
"templateParameters": $AZDO_TEMPLATE_PARAMETERS,
"resources": {
"repositories": {
"self": {
"refName": "refs/heads/$AZDO_BRANCH"
}
}
}
}
EOF
)

# Make API call
log "Chiamata API Azure DevOps in corso..."
local response=$(curl -s -w "\n%{http_code}" \
-X POST "$api_url" \
-H "Authorization: Basic $auth_token" \
-H "Content-Type: application/json" \
-d "$request_body")

# Extract status code and response body
local status_code=$(echo "$response" | tail -n1)
local response_body=$(echo "$response" | sed '$d')

# Check response
if [ "$status_code" -eq 200 ]; then
log "SUCCESS: Pipeline triggerata con successo"
# Check if jq is available for JSON formatting
if command -v jq &> /dev/null; then
echo "$response_body" | jq .
else
echo "$response_body"
fi
else
log "ERROR: Errore durante il trigger della pipeline. Status code: $status_code"
log "Response: $response_body"
exit 1
fi
}

# Main script execution
main() {
log "Avvio script trigger pipeline"

# Check PAT token
check_pat

# Load template parameters
load_template_parameters "$1"

# Trigger pipeline
trigger_pipeline

log "Esecuzione script completata"
}

# Execute main function with first argument
main "$1"