Sanitized mirror from private repository - 2026-03-24 12:45:58 UTC
Some checks failed
Documentation / Deploy to GitHub Pages (push) Has been cancelled
Documentation / Build Docusaurus (push) Has been cancelled

This commit is contained in:
Gitea Mirror Bot
2026-03-24 12:45:58 +00:00
commit c727d0bfb1
1265 changed files with 311415 additions and 0 deletions

177
scripts/validate-compose.sh Executable file
View File

@@ -0,0 +1,177 @@
#!/bin/bash
# Docker Compose Validation Script
# Validates Docker Compose files before commit to prevent broken deployments
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to log messages
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if Docker is available
if ! command -v docker &> /dev/null; then
log_warn "Docker not found. Skipping Docker Compose validation."
exit 0
fi
# Check if docker-compose is available
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
log_warn "Docker Compose not found. Skipping validation."
exit 0
fi
# Determine docker-compose command
if command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose"
else
COMPOSE_CMD="docker compose"
fi
# Validation function
validate_compose_file() {
local file="$1"
local filename=$(basename "$file")
# Skip non-Docker Compose files
if [[ "$file" == *".pre-commit-config.yaml" ]] || \
[[ "$file" == *".yamllint" ]] || \
[[ "$file" == *".gitea/workflows/"* ]] || \
[[ "$file" == *"secret_key.yaml" ]] || \
[[ "$file" == *"config.yml" ]] || \
[[ "$file" == *"snmp.yml" ]] || \
[[ "$file" == *"homeserver.yaml" ]]; then
log_info "Skipping non-Docker Compose file: $file"
return 0
fi
# Skip files that don't have a 'services:' block (not Docker Compose files)
if ! grep -q "^services:" "$file" 2>/dev/null; then
log_info "Skipping non-Docker Compose file: $file"
return 0
fi
# Skip compose files with env_file references to files that don't exist locally
if grep -q "env_file:" "$file" 2>/dev/null; then
local compose_dir
compose_dir=$(dirname "$file")
local missing_env=0
while IFS= read -r env_line; do
local env_file
env_file=$(echo "$env_line" | sed 's/.*-\s*//' | tr -d ' "')
if [[ -n "$env_file" ]] && [[ "$env_file" != "~" ]] && \
[[ ! -f "$compose_dir/$env_file" ]]; then
missing_env=1
break
fi
done < <(grep -A1 "env_file:" "$file" | grep "^.*-")
if [[ $missing_env -eq 1 ]]; then
log_warn "$file: Skipping validation - missing env_file dependencies"
return 0
fi
fi
log_info "Validating $file"
# Check if file exists and is readable
if [[ ! -r "$file" ]]; then
log_error "Cannot read file: $file"
return 1
fi
# Skip if not a compose file
if [[ ! "$filename" =~ \.(yml|yaml)$ ]]; then
log_info "Skipping non-YAML file: $file"
return 0
fi
# Skip certain directories and files
if [[ "$file" =~ ^(archive/|ansible/|docs/|\.git/) ]]; then
log_info "Skipping excluded path: $file"
return 0
fi
# Validate Docker Compose syntax
if ! $COMPOSE_CMD -f "$file" config > /dev/null 2>&1; then
log_error "Docker Compose validation failed for: $file"
log_error "Run '$COMPOSE_CMD -f $file config' to see detailed errors"
return 1
fi
# Check for common issues
local warnings=0
# Check for missing version (Docker Compose v2 doesn't require it, but good practice)
if ! grep -q "^version:" "$file" 2>/dev/null; then
log_warn "$file: Consider adding 'version' field for clarity"
((warnings++))
fi
# Check for hardcoded localhost references (should use service names)
if grep -q "localhost\|127\.0\.0\.1" "$file" 2>/dev/null; then
log_warn "$file: Found localhost references - consider using service names"
((warnings++))
fi
# Check for missing restart policies on long-running services
if grep -q "image:" "$file" && ! grep -q "restart:" "$file" 2>/dev/null; then
log_warn "$file: Consider adding restart policy for production services"
((warnings++))
fi
if [[ $warnings -eq 0 ]]; then
log_info "$file passed validation"
else
log_info "$file passed validation with $warnings warnings"
fi
return 0
}
# Main execution
main() {
local exit_code=0
local files_processed=0
# If no arguments provided, validate all YAML files
if [[ $# -eq 0 ]]; then
log_info "No files specified, validating all Docker Compose files..."
while IFS= read -r -d '' file; do
((files_processed++))
if ! validate_compose_file "$file"; then
exit_code=1
fi
done < <(find . -name "*.yml" -o -name "*.yaml" -print0 | grep -zv -E '^(archive/|ansible/|docs/|\.git/)')
else
# Validate specified files
for file in "$@"; do
((files_processed++))
if ! validate_compose_file "$file"; then
exit_code=1
fi
done
fi
if [[ $exit_code -eq 0 ]]; then
log_info "All $files_processed files passed validation!"
else
log_error "Some files failed validation. Please fix the errors before committing."
fi
exit $exit_code
}
# Run main function with all arguments
main "$@"