diff --git a/azure-devops-trigger-pipeline/README.md b/azure-devops-trigger-pipeline/README.md index d786acb..f96b24a 100644 --- a/azure-devops-trigger-pipeline/README.md +++ b/azure-devops-trigger-pipeline/README.md @@ -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 diff --git a/azure-devops-trigger-pipeline/action.yml b/azure-devops-trigger-pipeline/action.yml index f4a13c5..b38f775 100644 --- a/azure-devops-trigger-pipeline/action.yml +++ b/azure-devops-trigger-pipeline/action.yml @@ -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! ๐Ÿ") diff --git a/azure-devops-trigger-pipeline/params.json b/azure-devops-trigger-pipeline/params.json new file mode 100644 index 0000000..c57604e --- /dev/null +++ b/azure-devops-trigger-pipeline/params.json @@ -0,0 +1,6 @@ +{ + "APPS_TOP": "[one-color]", + "ARGOCD_TARGET_BRANCH": "tmp", + "POSTMAN_BRANCH": "develop1", + "TRIGGER_MESSAGE": "p4pa-auth" +} diff --git a/azure-devops-trigger-pipeline/trigger-azdo.sh b/azure-devops-trigger-pipeline/trigger-azdo.sh new file mode 100755 index 0000000..d6e8d24 --- /dev/null +++ b/azure-devops-trigger-pipeline/trigger-azdo.sh @@ -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 < /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"