Test CI Templates / validate-syntax (push) Successful in 11s
Test CI Templates / test-python-code-quality (3.11) (push) Failing after 5s
Test CI Templates / test-python-pytest (true, 3.12) (push) Failing after 4s
Test CI Templates / test-web-formatting (true, false, 20) (push) Failing after 5s
Test CI Templates / test-python-code-quality (3.10) (push) Failing after 5s
Test CI Templates / test-python-code-quality (3.12) (push) Failing after 5s
Test CI Templates / test-python-code-quality (false, false, basic) (push) Failing after 5s
Test CI Templates / test-python-code-quality (false, true, skip-pyupgrade) (push) Failing after 5s
Test CI Templates / test-python-pytest (false, 3.11) (push) Failing after 5s
Test CI Templates / test-python-pytest (false, 3.12) (push) Failing after 5s
Test CI Templates / test-python-pytest (true, 3.11) (push) Failing after 5s
Test CI Templates / test-web-formatting (false, false, 20) (push) Failing after 5s
Test CI Templates / test-web-formatting (false, true, 18) (push) Failing after 5s
Test CI Templates / test-web-formatting (false, true, 20) (push) Failing after 5s
Test CI Templates / test-web-formatting (true, false, 18) (push) Failing after 5s
Test CI Templates / test-monorepo (push) Failing after 5s
Test CI Templates / test-web-formatting (true, true, 18) (push) Failing after 5s
Test CI Templates / test-web-formatting (true, true, 20) (push) Failing after 5s
Test CI Templates / test-results (push) Successful in 2s
Test CI Templates / test-python-code-quality (true, false, skip-mypy) (push) Failing after 5s
Test CI Templates / test-web-formatting (false, false, 18) (push) Failing after 5s
Test CI Templates / test-edge-cases (push) Failing after 5s
718 lines
20 KiB
Bash
Executable File
718 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
||
set -e
|
||
|
||
# CI Template Validation Script
|
||
# This script validates the syntax and structure of Gitea Actions workflow templates
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Configuration
|
||
WORKFLOW_DIR=".gitea/workflows"
|
||
REQUIRED_FIELDS=("name" "on" "jobs")
|
||
REUSABLE_TRIGGER="workflow_call"
|
||
|
||
# Counters
|
||
TOTAL_FILES=0
|
||
VALID_FILES=0
|
||
WARNINGS=0
|
||
|
||
# Helper functions
|
||
log_info() {
|
||
echo -e "${BLUE}[INFO]${NC} $1"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
((WARNINGS++))
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
# Check if required tools are installed
|
||
check_dependencies() {
|
||
log_info "Checking dependencies..."
|
||
|
||
if ! command -v yamllint &> /dev/null; then
|
||
log_warning "yamllint not found. Install with: pip install yamllint"
|
||
log_info "Will skip YAML syntax validation"
|
||
SKIP_YAMLLINT=true
|
||
else
|
||
log_success "yamllint found"
|
||
fi
|
||
|
||
if ! command -v yq &> /dev/null; then
|
||
log_warning "yq not found. Install with: brew install yq (macOS) or apt install yq (Ubuntu)"
|
||
log_info "Will use basic grep validation instead"
|
||
SKIP_YQ=true
|
||
else
|
||
log_success "yq found"
|
||
fi
|
||
}
|
||
|
||
# Validate YAML syntax
|
||
validate_yaml_syntax() {
|
||
local file="$1"
|
||
|
||
if [[ "$SKIP_YAMLLINT" == "true" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
if yamllint "$file" 2>/dev/null; then
|
||
return 0
|
||
else
|
||
log_error "YAML syntax validation failed for $file"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Check if file is a reusable workflow
|
||
is_reusable_workflow() {
|
||
local file="$1"
|
||
|
||
if [[ "$SKIP_YQ" == "true" ]]; then
|
||
# Fallback to grep
|
||
if grep -q "workflow_call" "$file"; then
|
||
return 0
|
||
fi
|
||
else
|
||
# Use yq for precise checking
|
||
if yq eval '.on | has("workflow_call")' "$file" 2>/dev/null | grep -q "true"; then
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
# Validate required workflow fields
|
||
validate_workflow_structure() {
|
||
local file="$1"
|
||
local valid=true
|
||
|
||
for field in "${REQUIRED_FIELDS[@]}"; do
|
||
if [[ "$SKIP_YQ" == "true" ]]; then
|
||
# Fallback to grep
|
||
if ! grep -q "^${field}:" "$file"; then
|
||
log_error "Missing required field '$field' in $file"
|
||
valid=false
|
||
fi
|
||
else
|
||
# Use yq for precise checking
|
||
if ! yq eval "has(\"$field\")" "$file" 2>/dev/null | grep -q "true"; then
|
||
log_error "Missing required field '$field' in $file"
|
||
valid=false
|
||
fi
|
||
fi
|
||
done
|
||
|
||
if [[ "$valid" == "true" ]]; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Validate workflow inputs (for reusable workflows)
|
||
validate_workflow_inputs() {
|
||
local file="$1"
|
||
|
||
if ! is_reusable_workflow "$file"; then
|
||
return 0
|
||
fi
|
||
|
||
if [[ "$SKIP_YQ" == "true" ]]; then
|
||
# Basic check with grep
|
||
if grep -q "inputs:" "$file"; then
|
||
log_success "Inputs section found in $file"
|
||
else
|
||
log_warning "No inputs section found in reusable workflow $file"
|
||
fi
|
||
else
|
||
# Detailed validation with yq
|
||
local inputs_count
|
||
inputs_count=$(yq eval '.on.workflow_call.inputs | length' "$file" 2>/dev/null || echo "0")
|
||
|
||
if [[ "$inputs_count" -gt 0 ]]; then
|
||
log_success "Found $inputs_count input(s) in $file"
|
||
|
||
# Validate each input has required fields
|
||
local input_names
|
||
input_names=$(yq eval '.on.workflow_call.inputs | keys | .[]' "$file" 2>/dev/null || echo "")
|
||
|
||
while IFS= read -r input_name; do
|
||
if [[ -n "$input_name" ]]; then
|
||
# Check for description
|
||
if ! yq eval ".on.workflow_call.inputs.${input_name} | has(\"description\")" "$file" 2>/dev/null | grep -q "true"; then
|
||
log_warning "Input '$input_name' missing description in $file"
|
||
fi
|
||
|
||
# Check for type
|
||
if ! yq eval ".on.workflow_call.inputs.${input_name} | has(\"type\")" "$file" 2>/dev/null | grep -q "true"; then
|
||
log_warning "Input '$input_name' missing type in $file"
|
||
fi
|
||
fi
|
||
done <<< "$input_names"
|
||
else
|
||
log_warning "No inputs found in reusable workflow $file"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# Validate a single workflow file
|
||
validate_workflow_file() {
|
||
local file="$1"
|
||
local filename
|
||
filename=$(basename "$file")
|
||
|
||
log_info "Validating $file..."
|
||
((TOTAL_FILES++))
|
||
|
||
# Check if file exists and is readable
|
||
if [[ ! -r "$file" ]]; then
|
||
log_error "Cannot read file: $file"
|
||
return 1
|
||
fi
|
||
|
||
# Validate YAML syntax
|
||
if ! validate_yaml_syntax "$file"; then
|
||
return 1
|
||
fi
|
||
|
||
# Validate workflow structure
|
||
if ! validate_workflow_structure "$file"; then
|
||
return 1
|
||
fi
|
||
|
||
# Additional validations for reusable workflows
|
||
if is_reusable_workflow "$file"; then
|
||
log_success "$filename is a reusable workflow"
|
||
validate_workflow_inputs "$file"
|
||
else
|
||
# Skip warning for test files
|
||
if [[ "$filename" != *"test-"* ]]; then
|
||
log_warning "$filename is not a reusable workflow (missing workflow_call trigger)"
|
||
fi
|
||
fi
|
||
|
||
# Check for common issues
|
||
if grep -q "uses: \./\|uses: \.\\\\" "$file"; then
|
||
# Skip warning for test files - they intentionally use relative paths to test local workflows
|
||
if [[ "$filename" != *"test-"* ]]; then
|
||
log_warning "Found relative path in 'uses' field in $file - this may cause issues"
|
||
fi
|
||
fi
|
||
|
||
# Check for hardcoded values that should be inputs
|
||
if grep -q "python-version: [\"']3\." "$file"; then
|
||
# Skip warning for test files
|
||
if [[ "$filename" != *"test-"* ]]; then
|
||
log_warning "Found hardcoded Python version in $file - consider making it an input"
|
||
fi
|
||
fi
|
||
|
||
((VALID_FILES++))
|
||
log_success "$filename validation completed"
|
||
return 0
|
||
}
|
||
|
||
# Validate all workflow files
|
||
validate_all_workflows() {
|
||
log_info "Starting workflow validation..."
|
||
|
||
if [[ ! -d "$WORKFLOW_DIR" ]]; then
|
||
log_error "Workflow directory '$WORKFLOW_DIR' not found"
|
||
exit 1
|
||
fi
|
||
|
||
# Find all YAML files in workflow directory
|
||
local workflow_files
|
||
workflow_files=$(find "$WORKFLOW_DIR" -name "*.yml" -o -name "*.yaml" 2>/dev/null)
|
||
|
||
if [[ -z "$workflow_files" ]]; then
|
||
log_error "No workflow files found in '$WORKFLOW_DIR'"
|
||
exit 1
|
||
fi
|
||
|
||
# Validate each file
|
||
local failed_files=0
|
||
while IFS= read -r file; do
|
||
if [[ -n "$file" ]]; then
|
||
if ! validate_workflow_file "$file"; then
|
||
((failed_files++))
|
||
fi
|
||
fi
|
||
done <<< "$workflow_files"
|
||
|
||
# Print summary
|
||
echo
|
||
log_info "=== Validation Summary ==="
|
||
log_info "Total files: $TOTAL_FILES"
|
||
log_success "Valid files: $VALID_FILES"
|
||
|
||
if [[ $WARNINGS -gt 0 ]]; then
|
||
log_warning "Warnings: $WARNINGS"
|
||
fi
|
||
|
||
if [[ $failed_files -gt 0 ]]; then
|
||
log_error "Failed files: $failed_files"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ $WARNINGS -gt 0 ]]; then
|
||
log_warning "Validation completed with warnings"
|
||
exit 0
|
||
fi
|
||
|
||
log_success "All workflows validated successfully!"
|
||
}
|
||
|
||
# Validate documentation files
|
||
validate_documentation() {
|
||
log_info "Validating documentation..."
|
||
|
||
local readme_files=("README.md" "README-python-code-quality.md" "README-python-pytest.md" "README-web-formatting.md")
|
||
|
||
for readme in "${readme_files[@]}"; do
|
||
if [[ -f "$readme" ]]; then
|
||
log_success "Found $readme"
|
||
|
||
# Check for basic sections
|
||
if ! grep -q "^# " "$readme"; then
|
||
log_warning "$readme missing main heading"
|
||
fi
|
||
|
||
if ! grep -q "## Usage" "$readme"; then
|
||
log_warning "$readme missing Usage section"
|
||
fi
|
||
|
||
else
|
||
log_warning "Missing documentation file: $readme"
|
||
fi
|
||
done
|
||
}
|
||
|
||
# Generate workflow file list
|
||
list_workflows() {
|
||
log_info "Available workflow templates:"
|
||
echo
|
||
|
||
if [[ -d "$WORKFLOW_DIR" ]]; then
|
||
find "$WORKFLOW_DIR" -name "*.yml" -o -name "*.yaml" | while read -r file; do
|
||
local relative_path
|
||
relative_path=$(echo "$file" | sed "s|^$WORKFLOW_DIR/||")
|
||
|
||
if is_reusable_workflow "$file"; then
|
||
echo -e " ${GREEN}✓${NC} $relative_path (reusable)"
|
||
else
|
||
echo -e " ${YELLOW}○${NC} $relative_path (not reusable)"
|
||
fi
|
||
done
|
||
else
|
||
log_error "Workflow directory not found"
|
||
fi
|
||
echo
|
||
}
|
||
|
||
# Main function
|
||
main() {
|
||
echo -e "${BLUE}CI Template Validator${NC}"
|
||
echo "======================"
|
||
echo
|
||
|
||
# Parse command line arguments
|
||
case "${1:-validate}" in
|
||
"validate")
|
||
check_dependencies
|
||
validate_all_workflows
|
||
validate_documentation
|
||
;;
|
||
"list")
|
||
list_workflows
|
||
;;
|
||
"help"|"-h"|"--help")
|
||
echo "Usage: $0 [command]"
|
||
echo
|
||
echo "Commands:"
|
||
echo " validate Validate all workflow files (default)"
|
||
echo " list List all workflow templates"
|
||
echo " help Show this help message"
|
||
echo
|
||
echo "Examples:"
|
||
echo " $0 # Validate all workflows"
|
||
echo " $0 validate # Same as above"
|
||
echo " $0 list # List all available templates"
|
||
;;
|
||
*)
|
||
log_error "Unknown command: $1"
|
||
echo "Use '$0 help' for usage information"
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# Run main function with all arguments
|
||
main "$@"
|
||
|
||
echo -e "${BLUE}🔍 CI Template Validation Script${NC}"
|
||
echo "=================================="
|
||
|
||
# Function to print status
|
||
print_status() {
|
||
if [ $1 -eq 0 ]; then
|
||
echo -e "${GREEN}✅ $2${NC}"
|
||
else
|
||
echo -e "${RED}❌ $2${NC}"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to print warning
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||
}
|
||
|
||
# Function to print info
|
||
print_info() {
|
||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||
}
|
||
|
||
# Check if required tools are installed
|
||
check_dependencies() {
|
||
echo -e "\n${BLUE}Checking dependencies...${NC}"
|
||
|
||
local missing_deps=()
|
||
|
||
if ! command -v yamllint &> /dev/null; then
|
||
missing_deps+=("yamllint")
|
||
fi
|
||
|
||
if ! command -v python3 &> /dev/null; then
|
||
missing_deps+=("python3")
|
||
fi
|
||
|
||
if [ ${#missing_deps[@]} -gt 0 ]; then
|
||
echo -e "${RED}Missing dependencies: ${missing_deps[*]}${NC}"
|
||
echo "Install with:"
|
||
for dep in "${missing_deps[@]}"; do
|
||
case $dep in
|
||
yamllint)
|
||
echo " pip install yamllint"
|
||
;;
|
||
python3)
|
||
echo " Install Python 3.x"
|
||
;;
|
||
esac
|
||
done
|
||
return 1
|
||
fi
|
||
|
||
print_status 0 "All dependencies available"
|
||
}
|
||
|
||
# Validate YAML syntax
|
||
validate_yaml_syntax() {
|
||
echo -e "\n${BLUE}Validating YAML syntax...${NC}"
|
||
|
||
local yaml_files=()
|
||
while IFS= read -r -d $'\0'; do
|
||
yaml_files+=("$REPLY")
|
||
done < <(find .gitea/workflows -name "*.yml" -print0 2>/dev/null)
|
||
|
||
if [ ${#yaml_files[@]} -eq 0 ]; then
|
||
print_warning "No YAML files found in .gitea/workflows/"
|
||
return 1
|
||
fi
|
||
|
||
local errors=0
|
||
for file in "${yaml_files[@]}"; do
|
||
if yamllint "$file" > /dev/null 2>&1; then
|
||
print_status 0 "YAML syntax valid: $file"
|
||
else
|
||
print_status 1 "YAML syntax error: $file"
|
||
yamllint "$file"
|
||
((errors++))
|
||
fi
|
||
done
|
||
|
||
if [ $errors -eq 0 ]; then
|
||
print_status 0 "All YAML files have valid syntax"
|
||
else
|
||
print_status 1 "$errors YAML files have syntax errors"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Validate workflow structure
|
||
validate_workflow_structure() {
|
||
echo -e "\n${BLUE}Validating workflow structure...${NC}"
|
||
|
||
local workflow_files=()
|
||
while IFS= read -r -d $'\0'; do
|
||
workflow_files+=("$REPLY")
|
||
done < <(find .gitea/workflows -name "*.yml" -print0 2>/dev/null)
|
||
|
||
local errors=0
|
||
for file in "${workflow_files[@]}"; do
|
||
echo -e "\nChecking $file..."
|
||
|
||
# Check for workflow_call trigger
|
||
if grep -q "workflow_call" "$file"; then
|
||
print_status 0 "Has workflow_call trigger"
|
||
else
|
||
print_status 1 "Missing workflow_call trigger"
|
||
((errors++))
|
||
fi
|
||
|
||
# Check for inputs section
|
||
if grep -q "inputs:" "$file"; then
|
||
print_status 0 "Has inputs section"
|
||
else
|
||
print_warning "No inputs section (may be intentional)"
|
||
fi
|
||
|
||
# Check for jobs section
|
||
if grep -q "jobs:" "$file"; then
|
||
print_status 0 "Has jobs section"
|
||
else
|
||
print_status 1 "Missing jobs section"
|
||
((errors++))
|
||
fi
|
||
|
||
# Check for runs-on
|
||
if grep -q "runs-on:" "$file"; then
|
||
print_status 0 "Has runs-on specified"
|
||
else
|
||
print_status 1 "Missing runs-on specification"
|
||
((errors++))
|
||
fi
|
||
|
||
# Check for checkout action
|
||
if grep -q "actions/checkout" "$file"; then
|
||
print_status 0 "Uses checkout action"
|
||
else
|
||
print_warning "No checkout action (may be intentional)"
|
||
fi
|
||
done
|
||
|
||
if [ $errors -eq 0 ]; then
|
||
print_status 0 "All workflows have valid structure"
|
||
else
|
||
print_status 1 "$errors workflows have structure issues"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Validate input parameters
|
||
validate_input_parameters() {
|
||
echo -e "\n${BLUE}Validating input parameters...${NC}"
|
||
|
||
local workflow_files=()
|
||
while IFS= read -r -d $'\0'; do
|
||
workflow_files+=("$REPLY")
|
||
done < <(find .gitea/workflows -name "*.yml" -print0 2>/dev/null)
|
||
|
||
for file in "${workflow_files[@]}"; do
|
||
echo -e "\nChecking inputs in $file..."
|
||
|
||
# Extract input definitions and usage
|
||
local input_definitions=()
|
||
while IFS= read -r line; do
|
||
if [[ $line =~ ^[[:space:]]*([a-zA-Z0-9_-]+):[[:space:]]*$ ]]; then
|
||
input_name="${BASH_REMATCH[1]}"
|
||
if [[ ! $input_name =~ ^(description|required|type|default)$ ]]; then
|
||
input_definitions+=("$input_name")
|
||
fi
|
||
fi
|
||
done < <(sed -n '/inputs:/,/^[[:space:]]*[a-zA-Z]/p' "$file" | head -n -1)
|
||
|
||
# Check if inputs are used in the workflow
|
||
for input in "${input_definitions[@]}"; do
|
||
if grep -q "\${{ inputs\.$input }}" "$file"; then
|
||
print_status 0 "Input '$input' is used in workflow"
|
||
else
|
||
print_warning "Input '$input' is defined but not used"
|
||
fi
|
||
done
|
||
done
|
||
}
|
||
|
||
# Create test project structure
|
||
create_test_project() {
|
||
echo -e "\n${BLUE}Creating test project structure...${NC}"
|
||
|
||
local test_dir="test-validation-project"
|
||
|
||
if [ -d "$test_dir" ]; then
|
||
print_info "Removing existing test project"
|
||
rm -rf "$test_dir"
|
||
fi
|
||
|
||
mkdir -p "$test_dir/src/test_package"
|
||
cd "$test_dir"
|
||
|
||
# Create pyproject.toml
|
||
cat > pyproject.toml << 'EOF'
|
||
[build-system]
|
||
requires = ["hatchling"]
|
||
build-backend = "hatchling.build"
|
||
|
||
[project]
|
||
name = "test-validation-package"
|
||
version = "0.1.0"
|
||
description = "Test package for CI template validation"
|
||
dependencies = []
|
||
|
||
[project.optional-dependencies]
|
||
dev = [
|
||
"mypy>=1.0.0",
|
||
"ruff>=0.1.0",
|
||
"pyupgrade>=3.0.0",
|
||
"pytest>=7.0.0",
|
||
"pytest-cov>=4.0.0",
|
||
]
|
||
|
||
[tool.ruff]
|
||
line-length = 88
|
||
target-version = "py310"
|
||
|
||
[tool.mypy]
|
||
python_version = "3.10"
|
||
warn_return_any = true
|
||
warn_unused_configs = true
|
||
EOF
|
||
|
||
# Create source code
|
||
mkdir -p src/test_package
|
||
cat > src/test_package/__init__.py << 'EOF'
|
||
"""Test package for validation."""
|
||
__version__ = "0.1.0"
|
||
|
||
def hello_world() -> str:
|
||
"""Return a greeting message."""
|
||
return "Hello, World!"
|
||
EOF
|
||
|
||
cat > src/test_package/math_utils.py << 'EOF'
|
||
"""Math utility functions."""
|
||
from typing import List
|
||
|
||
def add_numbers(numbers: List[float]) -> float:
|
||
"""Add a list of numbers."""
|
||
return sum(numbers)
|
||
|
||
def multiply_numbers(numbers: List[float]) -> float:
|
||
"""Multiply a list of numbers."""
|
||
result = 1.0
|
||
for num in numbers:
|
||
result *= num
|
||
return result
|
||
EOF
|
||
|
||
# Create tests
|
||
mkdir -p tests
|
||
cat > tests/test_math_utils.py << 'EOF'
|
||
"""Tests for math utilities."""
|
||
import pytest
|
||
from test_package.math_utils import add_numbers, multiply_numbers
|
||
|
||
def test_add_numbers():
|
||
assert add_numbers([1, 2, 3]) == 6
|
||
assert add_numbers([]) == 0
|
||
assert add_numbers([5.5, 2.5]) == 8.0
|
||
|
||
def test_multiply_numbers():
|
||
assert multiply_numbers([2, 3, 4]) == 24
|
||
assert multiply_numbers([1]) == 1
|
||
assert multiply_numbers([2.5, 2]) == 5.0
|
||
EOF
|
||
|
||
cd ..
|
||
print_status 0 "Test project created at $test_dir"
|
||
}
|
||
|
||
# Generate validation report
|
||
generate_report() {
|
||
echo -e "\n${BLUE}Generating validation report...${NC}"
|
||
|
||
local report_file="validation-report.md"
|
||
|
||
cat > "$report_file" << 'EOF'
|
||
# CI Template Validation Report
|
||
|
||
Generated on: $(date)
|
||
|
||
## Summary
|
||
|
||
This report contains the validation results for the CI template workflows.
|
||
|
||
## Workflow Files
|
||
|
||
EOF
|
||
|
||
# Add workflow file information
|
||
find .gitea/workflows -name "*.yml" 2>/dev/null | while read -r file; do
|
||
echo "### $file" >> "$report_file"
|
||
echo "" >> "$report_file"
|
||
echo "- **Size:** $(wc -c < "$file") bytes" >> "$report_file"
|
||
echo "- **Lines:** $(wc -l < "$file") lines" >> "$report_file"
|
||
|
||
if grep -q "workflow_call" "$file"; then
|
||
echo "- **Type:** Reusable workflow ✅" >> "$report_file"
|
||
else
|
||
echo "- **Type:** Standard workflow ⚠️" >> "$report_file"
|
||
fi
|
||
|
||
local input_count=$(grep -c "^[[:space:]]*[a-zA-Z0-9_-]*:[[:space:]]*$" "$file" | head -n 1)
|
||
echo "- **Input parameters:** $input_count" >> "$report_file"
|
||
echo "" >> "$report_file"
|
||
done
|
||
|
||
print_status 0 "Validation report generated: $report_file"
|
||
}
|
||
|
||
# Main execution
|
||
main() {
|
||
echo -e "${BLUE}Starting CI template validation...${NC}"
|
||
|
||
local exit_code=0
|
||
|
||
# Run all validation steps
|
||
check_dependencies || exit_code=1
|
||
validate_yaml_syntax || exit_code=1
|
||
validate_workflow_structure || exit_code=1
|
||
validate_input_parameters || exit_code=1
|
||
create_test_project || exit_code=1
|
||
generate_report || exit_code=1
|
||
|
||
echo -e "\n${BLUE}Validation Summary${NC}"
|
||
echo "=================="
|
||
|
||
if [ $exit_code -eq 0 ]; then
|
||
echo -e "${GREEN}🎉 All validations passed!${NC}"
|
||
echo -e "${GREEN}Your CI templates are ready for use.${NC}"
|
||
else
|
||
echo -e "${RED}💥 Some validations failed.${NC}"
|
||
echo -e "${RED}Please review the errors above and fix them.${NC}"
|
||
fi
|
||
|
||
echo -e "\n${BLUE}Next steps:${NC}"
|
||
echo "1. Review the validation report"
|
||
echo "2. Test the templates with the created test project"
|
||
echo "3. Run the automated test workflow: .gitea/workflows/test-templates.yml"
|
||
|
||
return $exit_code
|
||
}
|
||
|
||
# Run the main function
|
||
main "$@" |