homelab/.github/workflows/docker-compose-validation.yml
Claude 1c3b7e53a1
feat: Add comprehensive GitHub Actions CI/CD pipeline
GitHub Actions Workflows:
- docker-compose-validation.yml: Validates all compose files
  - Syntax validation
  - Network configuration checks
  - Traefik label validation
  - Port exposure warnings
  - Domain consistency checks
  - File naming convention enforcement

- security-checks.yml: Security scanning and validation
  - Gitleaks secret detection
  - Environment file validation
  - Placeholder password checks
  - Container image vulnerability scanning with Trivy
  - Dependency review for pull requests
  - Security report generation

- yaml-lint.yml: YAML formatting and validation
  - yamllint with custom configuration
  - File extension consistency checks
  - YAML structure validation
  - Service naming convention checks
  - Docker Compose version validation

- documentation.yml: Documentation quality checks
  - Markdown linting
  - Link validation
  - README completeness verification
  - Service documentation checks
  - Domain URL validation

- auto-label.yml: Automated PR labeling
  - Category-based labeling (core/media/services)
  - File type detection
  - Size-based labeling
  - Security-related changes detection

Configuration Files:
- .yamllint.yml: YAML linting rules for Docker Compose
- .markdownlint.json: Markdown formatting rules
- .markdown-link-check.json: Link checking configuration
- .pre-commit-config.yaml: Pre-commit hooks setup
- .github/labeler.yml: Auto-labeler configuration
- .github/CODEOWNERS: Code ownership definitions

Templates:
- pull_request_template.md: Comprehensive PR checklist
- ISSUE_TEMPLATE/bug-report.md: Bug report template
- ISSUE_TEMPLATE/service-request.md: New service request template

Documentation:
- SECURITY.md: Security policy and best practices
- CONTRIBUTING.md: Contribution guidelines

Benefits:
- Automated validation of all compose files
- Security scanning on every PR
- Consistent code formatting
- Documentation quality assurance
- Automated issue/PR management
- Pre-commit hooks for local validation
- Comprehensive security policy
- Clear contribution guidelines
2025-11-05 20:09:33 +00:00

159 lines
5.8 KiB
YAML

name: Docker Compose Validation
on:
pull_request:
paths:
- 'compose/**/*.yaml'
- 'compose/**/*.yml'
- '.github/workflows/docker-compose-validation.yml'
push:
branches:
- main
paths:
- 'compose/**/*.yaml'
- 'compose/**/*.yml'
jobs:
validate-compose-files:
name: Validate Docker Compose Files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Find all compose files
id: find-files
run: |
echo "Finding all compose.yaml files..."
find compose -name "compose.yaml" -type f > compose-files.txt
cat compose-files.txt
echo "Found $(wc -l < compose-files.txt) compose files"
- name: Validate compose file syntax
run: |
echo "Validating Docker Compose files..."
exit_code=0
while IFS= read -r file; do
echo "Validating: $file"
if docker compose -f "$file" config > /dev/null 2>&1; then
echo "✅ Valid: $file"
else
echo "❌ Invalid: $file"
docker compose -f "$file" config
exit_code=1
fi
done < compose-files.txt
exit $exit_code
- name: Check for old .yml files
run: |
old_files=$(find compose -name "compose.yml" -o -name "docker-compose.yml" 2>/dev/null || true)
if [ -n "$old_files" ]; then
echo "❌ Found deprecated .yml files (should be .yaml):"
echo "$old_files"
exit 1
else
echo "✅ All compose files use .yaml extension"
fi
- name: Validate network references
run: |
echo "Checking network references..."
exit_code=0
while IFS= read -r file; do
# Check if file uses 'homelab' network
if grep -q "networks:" "$file"; then
if grep -q "homelab" "$file"; then
# Ensure it's marked as external
if grep -A 5 "^networks:" "$file" | grep -A 2 "homelab:" | grep -q "external: true"; then
echo "✅ $file: homelab network properly marked as external"
else
echo "⚠️ $file: homelab network should be marked as external: true"
exit_code=1
fi
fi
fi
done < compose-files.txt
exit $exit_code
- name: Check for exposed ports
run: |
echo "Checking for unnecessary port exposures..."
files_with_ports=$(grep -l "ports:" compose/**/compose.yaml || true)
if [ -n "$files_with_ports" ]; then
echo "⚠️ Files with exposed ports (consider using Traefik only):"
echo "$files_with_ports"
echo ""
echo "This is a warning, not an error. Review if these ports need to be exposed."
else
echo "✅ No ports exposed (using Traefik for all routing)"
fi
- name: Validate Traefik labels
run: |
echo "Validating Traefik labels..."
exit_code=0
while IFS= read -r file; do
if grep -q "traefik.enable: true" "$file"; then
# Check for required labels
has_router=$(grep -q "traefik.http.routers\." "$file" && echo "yes" || echo "no")
has_entrypoint=$(grep -q "entrypoints: websecure" "$file" && echo "yes" || echo "no")
has_tls=$(grep -q "tls.certresolver: letsencrypt" "$file" && echo "yes" || echo "no")
has_rule=$(grep -q "\.rule: Host" "$file" && echo "yes" || echo "no")
if [ "$has_router" = "yes" ] && [ "$has_entrypoint" = "yes" ] && [ "$has_tls" = "yes" ] && [ "$has_rule" = "yes" ]; then
echo "✅ $file: Complete Traefik configuration"
else
echo "⚠️ $file: Incomplete Traefik configuration"
[ "$has_router" = "no" ] && echo " - Missing router definition"
[ "$has_entrypoint" = "no" ] && echo " - Missing websecure entrypoint"
[ "$has_tls" = "no" ] && echo " - Missing TLS/Let's Encrypt config"
[ "$has_rule" = "no" ] && echo " - Missing Host rule"
exit_code=1
fi
fi
done < compose-files.txt
exit $exit_code
- name: Check domain consistency
run: |
echo "Checking domain consistency..."
# Extract all domains from Traefik rules
domains=$(grep -h "rule: Host" compose/**/compose.yaml | grep -oP '`\K[^`]+' | sort -u)
echo "Configured domains:"
echo "$domains"
# Check that both fig.systems and edfig.dev are used
fig_systems_count=$(echo "$domains" | grep -c "fig.systems" || true)
edfig_dev_count=$(echo "$domains" | grep -c "edfig.dev" || true)
echo ""
echo "fig.systems domains: $fig_systems_count"
echo "edfig.dev domains: $edfig_dev_count"
# Check for services that don't have both domains
while IFS= read -r file; do
if grep -q "traefik.enable: true" "$file"; then
has_fig_systems=$(grep "rule: Host" "$file" | grep -c "fig.systems" || true)
has_edfig_dev=$(grep "rule: Host" "$file" | grep -c "edfig.dev" || true)
if [ "$has_fig_systems" -gt 0 ] && [ "$has_edfig_dev" -eq 0 ]; then
echo "⚠️ $file: Has fig.systems but missing edfig.dev"
elif [ "$has_edfig_dev" -gt 0 ] && [ "$has_fig_systems" -eq 0 ]; then
echo "⚠️ $file: Has edfig.dev but missing fig.systems"
fi
fi
done < compose-files.txt