#!/bin/bash # Validate CI/CD workflow syntax and structure set -e echo "🔍 Validating CI/CD Workflow" echo "================================" # 1. Check workflow files exist WORKFLOW_FILES=( ".gitea/workflows/go-ci-cd.yaml" ".gitea/workflows/dockerimage.yaml" ) for file in "${WORKFLOW_FILES[@]}"; do if [ ! -f "$file" ]; then echo "❌ Workflow file not found: $file" exit 1 fi echo "✅ Workflow file found: $file" done # 2. Validate YAML syntax for all workflows if command -v yq >/dev/null 2>&1; then for file in "${WORKFLOW_FILES[@]}"; do if ! yq eval '.' "$file" > /dev/null 2>&1; then echo "❌ Invalid YAML syntax in: $file" yq eval '.' "$file" || true exit 1 fi echo "✅ YAML syntax valid: $file" done else echo "⚠️ yq not installed, skipping YAML validation" fi # 3. YAML Linting with custom config for all workflows if command -v yamllint >/dev/null 2>&1; then for file in "${WORKFLOW_FILES[@]}"; do if [ -f ".yamllint.yaml" ]; then yamllint -c "$(pwd)/.yamllint.yaml" "$file" else yamllint "$file" fi done elif docker info >/dev/null 2>&1; then for file in "${WORKFLOW_FILES[@]}"; do if [ -f ".yamllint.yaml" ]; then docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \ yamllint -c /workspace/.yamllint.yaml "$file" else docker run --rm -v $(pwd):/workspace -w /workspace pipelinecomponents/yamllint:latest \ yamllint "$file" fi done else echo "⚠️ Neither yamllint nor docker available, skipping linting" fi # 3. Check required fields for all workflows for file in "${WORKFLOW_FILES[@]}"; do MISSING_FIELDS=() if command -v yq >/dev/null 2>&1; then workflow_name=$(basename "$file" .yaml) if [ -z "$(yq eval '.name' "$file" 2>/dev/null)" ]; then MISSING_FIELDS+=("name") fi if [ -z "$(yq eval '.on' "$file" 2>/dev/null)" ]; then MISSING_FIELDS+=("on") fi if [ -z "$(yq eval '.jobs' "$file" 2>/dev/null)" ]; then MISSING_FIELDS+=("jobs") fi if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then echo "❌ Missing required fields in $workflow_name: ${MISSING_FIELDS[*]}" exit 1 fi echo "✅ All required fields present in $workflow_name" else echo "⚠️ yq not installed, skipping field validation for $file" fi done # 4. Check jobs structure if command -v yq >/dev/null 2>&1; then JOBS=$(yq eval '.jobs | keys' .gitea/workflows/ci-cd.yaml 2>/dev/null) echo "📋 Jobs defined: $JOBS" for job in $JOBS; do job_str=$(echo $job | tr -d '"') # Check job has steps if [ -z "$(yq eval ".jobs.$job_str.steps" .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then echo "❌ Job $job_str has no steps" exit 1 fi steps_count=$(yq eval ".jobs.$job_str.steps | length" .gitea/workflows/ci-cd.yaml 2>/dev/null) echo " ✅ $job_str: $steps_count steps" done else echo "⚠️ yq not installed, skipping job structure validation" fi # 5. Check Arcodange-specific configurations if command -v yq >/dev/null 2>&1; then if [ -n "$(yq eval '.env.GITEA_INTERNAL' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then echo "✅ Arcodange internal URL configured" else echo "⚠️ Arcodange internal URL not found" fi if [ -n "$(yq eval '.env.GITEA_EXTERNAL' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then echo "✅ Arcodange external URL configured" else echo "⚠️ Arcodange external URL not found" fi # 6. Check concurrency settings if [ -n "$(yq eval '.concurrency' .gitea/workflows/ci-cd.yaml 2>/dev/null)" ]; then echo "✅ Concurrency control configured" else echo "⚠️ No concurrency control (consider adding)" fi else echo "⚠️ yq not installed, skipping Arcodange-specific validations" fi echo "" echo "🎉 Workflow Validation Successful!" echo "================================" echo "📁 Workflows validated:" for file in "${WORKFLOW_FILES[@]}"; do echo " - $file" done if command -v yq >/dev/null 2>&1; then echo "🔧 Summary:" for file in "${WORKFLOW_FILES[@]}"; do workflow_name=$(basename "$file" .yaml) JOBS=$(yq eval '.jobs | keys | join(", ")' "$file" 2>/dev/null || echo 'Unable to parse') echo " - $workflow_name: $JOBS" done else echo "🔧 Jobs: yq not installed" fi echo "🎯 Ready for deployment"