Files
dance-lessons-coach/scripts/validate-cicd-comprehensive.sh
Gabriel Radureau b391534f2d 🤖 feat: implement trunk-based CI/CD with local testing
- Designed trunk-based development workflow with branch protection
- Added workflow validation job to prevent main branch breaks
- Integrated act (GitHub Actions runner) for local Gitea workflow testing
- Created unified CI/CD script interface (scripts/cicd.sh)
- Added YAML lint configuration with practical limits (400 chars)
- Organized all CI/CD scripts under scripts/cicd/ directory
- Confirmed Gitea/GitHub Actions compatibility via local testing
- Updated ADR 0017 with implementation details and test results
- Enhanced documentation with local development workflow

See ADR-0017 for complete trunk-based development workflow documentation.
See ADR-0016 for CI/CD pipeline design.
2026-04-05 23:07:32 +02:00

175 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
# Comprehensive CI/CD validation script
# Validates workflow without requiring Docker for basic checks
set -e
echo "🔍 Comprehensive CI/CD Validation"
echo "==================================="
# 1. Check workflow file exists
if [ ! -f ".gitea/workflows/ci-cd.yaml" ]; then
echo "❌ Workflow file not found: .gitea/workflows/ci-cd.yaml"
exit 1
fi
echo "✅ Workflow file found"
# 2. Validate YAML syntax with Python (no Docker required)
echo ""
echo "🔍 Validating YAML syntax..."
python3 -c "import yaml; yaml.safe_load(open('.gitea/workflows/ci-cd.yaml'))" 2>&1
if [ $? -eq 0 ]; then
echo "✅ YAML syntax is valid"
else
echo "❌ YAML syntax error"
exit 1
fi
# 3. Check required fields using Python
echo ""
echo "📋 Checking required fields..."
python3 << 'PYTHON'
import yaml
try:
with open('.gitea/workflows/ci-cd.yaml') as f:
workflow = yaml.safe_load(f)
if not workflow:
print("❌ Workflow is empty or invalid")
exit(1)
# Check for required fields
has_name = 'name' in workflow
has_on = 'on' in workflow
has_jobs = 'jobs' in workflow
if not has_name:
print("❌ Missing 'name' field")
exit(1)
if not has_on:
print("❌ Missing 'on' field")
exit(1)
if not has_jobs:
print("❌ Missing 'jobs' field")
exit(1)
print("✅ All required fields present")
# Check jobs structure
jobs = workflow['jobs']
print(f"📋 Jobs defined: {', '.join(jobs.keys())}")
for job_name, job_config in jobs.items():
if not isinstance(job_config, dict):
print(f"❌ Job '{job_name}' is not properly formatted")
exit(1)
if 'steps' not in job_config:
print(f"❌ Job '{job_name}' has no steps")
exit(1)
steps = job_config['steps']
if not isinstance(steps, list):
print(f"❌ Job '{job_name}' steps are not a list")
exit(1)
steps_count = len(steps)
print(f" ✅ {job_name}: {steps_count} steps")
except Exception as e:
print(f"❌ Error parsing workflow: {e}")
exit(1)
PYTHON
# 4. Check Arcodange-specific configurations
echo ""
echo "🔧 Checking Arcodange configurations..."
python3 << 'PYTHON'
import yaml
with open('.gitea/workflows/ci-cd.yaml') as f:
workflow = yaml.safe_load(f)
# Check environment variables
if 'env' in workflow:
env_vars = workflow['env']
gitea_internal = env_vars.get('GITEA_INTERNAL', '')
gitea_external = env_vars.get('GITEA_EXTERNAL', '')
if gitea_internal and 'arcodange.lab' in gitea_internal:
print("✅ Arcodange internal URL configured")
else:
print("⚠️ Arcodange internal URL not found or incorrect")
if gitea_external and 'arcodange.fr' in gitea_external:
print("✅ Arcodange external URL configured")
else:
print("⚠️ Arcodange external URL not found or incorrect")
else:
print("⚠️ No environment variables configured")
# Check concurrency
if 'concurrency' in workflow:
print("✅ Concurrency control configured")
else:
print("⚠️ No concurrency control (consider adding)")
PYTHON
# 5. Check workflow structure
echo ""
echo "🏗️ Checking workflow structure..."
python3 << 'PYTHON'
import yaml
with open('.gitea/workflows/ci-cd.yaml') as f:
workflow = yaml.safe_load(f)
# Check triggers
if 'on' in workflow:
triggers = workflow['on']
has_push = 'push' in triggers if isinstance(triggers, dict) else any('push' in str(t) for t in triggers)
has_workflow_dispatch = 'workflow_dispatch' in triggers if isinstance(triggers, dict) else any('workflow_dispatch' in str(t) for t in triggers)
if has_push:
print("✅ Push trigger configured")
else:
print("⚠️ No push trigger")
if has_workflow_dispatch:
print("✅ Manual trigger (workflow_dispatch) configured")
else:
print("⚠️ No manual trigger")
# Check paths-ignore
if 'on' in workflow and isinstance(workflow['on'], dict) and 'push' in workflow['on']:
push_config = workflow['on']['push']
if isinstance(push_config, dict) and 'paths-ignore' in push_config:
ignored_paths = push_config['paths-ignore']
print(f"✅ Paths ignored: {', '.join(ignored_paths)}")
else:
print("⚠️ No paths-ignore configured")
PYTHON
# 6. Summary
echo ""
echo "🎉 Validation Complete!"
echo "================================"
echo "📁 Workflow: .gitea/workflows/ci-cd.yaml"
echo "✅ YAML syntax valid"
echo "✅ Required fields present"
echo "✅ Jobs structure valid"
echo "✅ Arcodange configurations checked"
echo "🎯 Ready for deployment"
echo ""
echo "💡 Next Steps:"
echo " 1. Test with Docker: ./scripts/test-cicd-simple.sh"
echo " 2. Commit changes: git commit -m '🤖 ci: validate workflow'"
echo " 3. Push to trigger: git push origin main"
echo " 4. Monitor pipeline: https://gitea.arcodange.lab/arcodange/DanceLessonsCoach/actions"