name: CI on: push: branches: [ master ] pull_request: jobs: lint-and-test: runs-on: ubuntu-latest container: image: node:20-bullseye steps: - name: Check out code uses: actions/checkout@v4 - name: Install dependencies run: npm ci - name: Lint markdown run: npm run test:markdown - name: Check markdown links run: npm run test:links continue-on-error: true ansible-validation: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Python and dependencies run: | apt-get update && apt-get install -y python3 python3-pip - name: Install Ansible and linting tools run: pip3 install --no-cache-dir ansible ansible-lint yamllint - name: Validate YAML syntax run: | echo "Checking YAML syntax..." find . -name "*.yml" -o -name "*.yaml" | grep -v ".git" | while read file; do python3 -c "import yaml; yaml.safe_load(open('$file'))" || exit 1 done - name: Run ansible-lint run: ansible-lint continue-on-error: true secret-scanning: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Gitleaks run: | apt-get update && apt-get install -y wget curl GITLEAKS_VERSION=$(curl -s https://api.github.com/repos/gitleaks/gitleaks/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//') wget -q "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" -O /tmp/gitleaks.tar.gz tar -xzf /tmp/gitleaks.tar.gz -C /usr/local/bin/ gitleaks chmod +x /usr/local/bin/gitleaks gitleaks version - name: Run Gitleaks secret scan run: | gitleaks detect --source . --verbose --no-banner --exit-code 1 dependency-scan: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Trivy run: | apt-get update && apt-get install -y wget curl wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - || true echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | tee -a /etc/apt/sources.list.d/trivy.list apt-get update && apt-get install -y trivy || \ (wget -qO /usr/local/bin/trivy https://github.com/aquasecurity/trivy/releases/latest/download/trivy_linux_amd64 && chmod +x /usr/local/bin/trivy) - name: Scan npm dependencies run: | if [ -f "package.json" ]; then echo "Scanning npm dependencies..." trivy fs --security-checks vuln --severity HIGH,CRITICAL --format table --exit-code 0 . else echo "No package.json found, skipping npm scan" fi continue-on-error: true - name: Scan Python dependencies run: | if [ -f "requirements.txt" ]; then echo "Scanning Python dependencies..." trivy fs --security-checks vuln --severity HIGH,CRITICAL --format table --exit-code 0 . else echo "No requirements.txt found, skipping Python scan" fi continue-on-error: true - name: Generate dependency scan report run: | echo "Generating comprehensive scan report..." trivy fs --security-checks vuln --format json --output trivy-report.json . || true trivy fs --security-checks vuln --format table . || true - name: Upload Trivy report uses: actions/upload-artifact@v4 if: always() with: name: trivy-report path: trivy-report.json sast-scan: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Semgrep run: | apt-get update && apt-get install -y python3 python3-pip pip3 install semgrep - name: Run Semgrep scan run: semgrep --config=auto --error continue-on-error: true license-check: runs-on: ubuntu-latest container: image: node:20-bullseye steps: - name: Check out code uses: actions/checkout@v4 - name: Install license-checker run: npm install -g license-checker - name: Check npm licenses run: | if [ -f "package.json" ]; then license-checker --onlyAllow 'MIT;Apache-2.0;BSD-3-Clause;ISC;BSD-2-Clause' || true else echo "No package.json found, skipping license check" fi continue-on-error: true vault-check: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Python and dependencies run: | apt-get update && apt-get install -y python3 python3-pip - name: Install Ansible run: pip3 install --no-cache-dir ansible - name: Validate vault files are encrypted run: | echo "Checking for Ansible Vault files..." vault_files=$(find . -name "*vault*.yml" -o -name "*vault*.yaml" | grep -v ".git" || true) if [ -z "$vault_files" ]; then echo "No vault files found" exit 0 fi for vault_file in $vault_files; do echo "Checking $vault_file..." if ansible-vault view "$vault_file" > /dev/null 2>&1; then echo "✓ $vault_file is properly encrypted" else echo "✗ ERROR: $vault_file appears to be unencrypted or invalid" exit 1 fi done playbook-test: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Python and dependencies run: | apt-get update && apt-get install -y python3 python3-pip - name: Install Ansible run: pip3 install --no-cache-dir ansible - name: Dry-run playbooks run: | echo "Running dry-run tests on playbooks..." failed=0 for playbook in playbooks/*.yml; do if [ -f "$playbook" ]; then echo "Testing $playbook..." if ansible-playbook "$playbook" --syntax-check --list-tasks > /dev/null 2>&1; then echo "✓ $playbook syntax is valid" else echo "✗ $playbook has syntax errors" failed=1 fi fi done if [ $failed -eq 1 ]; then echo "Some playbooks have errors (this is expected without inventory/vault)" exit 0 fi continue-on-error: true container-scan: runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install Node.js for checkout action run: | apt-get update && apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs - name: Check out code uses: actions/checkout@v4 - name: Install Trivy run: | apt-get update && apt-get install -y wget curl wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - || true echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | tee -a /etc/apt/sources.list.d/trivy.list apt-get update && apt-get install -y trivy || \ (wget -qO /usr/local/bin/trivy https://github.com/aquasecurity/trivy/releases/latest/download/trivy_linux_amd64 && chmod +x /usr/local/bin/trivy) - name: Scan for Dockerfiles and container configs run: | if [ -f "Dockerfile" ] || [ -f "docker-compose.yml" ] || find . -name "Dockerfile*" -o -name "*.dockerfile" 2>/dev/null | grep -v ".git" | head -1 > /dev/null; then echo "Dockerfiles found. Scanning filesystem for container-related vulnerabilities..." echo "Note: This scans filesystem, not built images." echo "To scan actual images, build them first and use: trivy image " trivy fs --security-checks vuln --severity HIGH,CRITICAL --format table . || true else echo "No Dockerfiles found, skipping container image scan" exit 0 fi continue-on-error: true