Some checks failed
CI / lint-and-test (pull_request) Successful in 56s
CI / ansible-validation (pull_request) Successful in 2m19s
CI / secret-scanning (pull_request) Successful in 55s
CI / dependency-scan (pull_request) Successful in 1m0s
CI / sast-scan (pull_request) Successful in 2m7s
CI / license-check (pull_request) Successful in 54s
CI / vault-check (pull_request) Successful in 2m0s
CI / playbook-test (pull_request) Successful in 1m58s
CI / container-scan (pull_request) Successful in 1m32s
CI / sonar-analysis (pull_request) Failing after 50s
CI / workflow-summary (pull_request) Successful in 50s
329 lines
12 KiB
YAML
329 lines
12 KiB
YAML
---
|
|
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: |
|
|
# Skip vault-encrypted files and playbooks that require vault passwords
|
|
ansible-lint --skip-list vault,internal-error || true
|
|
continue-on-error: true
|
|
|
|
secret-scanning:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: zricethezav/gitleaks:latest
|
|
steps:
|
|
- name: Install Node.js for checkout action
|
|
run: |
|
|
apk add --no-cache nodejs npm curl
|
|
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Scan for secrets
|
|
run: gitleaks detect --source . --no-banner --redact --exit-code 0
|
|
continue-on-error: true
|
|
|
|
dependency-scan:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: aquasec/trivy:latest
|
|
steps:
|
|
- name: Install Node.js for checkout action
|
|
run: |
|
|
apk add --no-cache nodejs npm curl
|
|
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Scan dependencies
|
|
run: trivy fs --scanners vuln,secret --exit-code 0 .
|
|
|
|
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
|
|
failed=0
|
|
for vault_file in $vault_files; do
|
|
echo "Checking $vault_file..."
|
|
# Check if file starts with ANSIBLE_VAULT header (doesn't require password)
|
|
if head -n 1 "$vault_file" | grep -q "^\$ANSIBLE_VAULT"; then
|
|
echo "✓ $vault_file is properly encrypted (has vault header)"
|
|
else
|
|
echo "✗ ERROR: $vault_file does not have ANSIBLE_VAULT header - may be unencrypted!"
|
|
failed=1
|
|
fi
|
|
done
|
|
if [ $failed -eq 1 ]; then
|
|
echo "Some vault files are not encrypted. Please encrypt them with: ansible-vault encrypt <file>"
|
|
exit 1
|
|
fi
|
|
echo "All vault files are properly encrypted!"
|
|
|
|
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 tar
|
|
# Try multiple download methods for reliability
|
|
echo "Downloading Trivy..."
|
|
if wget -q "https://github.com/aquasecurity/trivy/releases/latest/download/trivy_linux_amd64.tar.gz" -O /tmp/trivy.tar.gz 2>&1; then
|
|
echo "Downloaded tar.gz, extracting..."
|
|
tar -xzf /tmp/trivy.tar.gz -C /tmp/ trivy
|
|
mv /tmp/trivy /usr/local/bin/trivy
|
|
elif wget -q "https://github.com/aquasecurity/trivy/releases/latest/download/trivy_linux_amd64" -O /usr/local/bin/trivy 2>&1; then
|
|
echo "Downloaded binary directly"
|
|
else
|
|
echo "Failed to download Trivy, trying with version detection..."
|
|
TRIVY_VERSION=$(curl -s https://api.github.com/repos/aquasecurity/trivy/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//')
|
|
wget -q "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" -O /tmp/trivy.tar.gz
|
|
tar -xzf /tmp/trivy.tar.gz -C /tmp/ trivy
|
|
mv /tmp/trivy /usr/local/bin/trivy
|
|
fi
|
|
chmod +x /usr/local/bin/trivy
|
|
/usr/local/bin/trivy --version
|
|
trivy --version
|
|
|
|
- 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 <image:tag>"
|
|
trivy fs --scanners vuln --severity HIGH,CRITICAL --format table . || true
|
|
else
|
|
echo "No Dockerfiles found, skipping container image scan"
|
|
exit 0
|
|
fi
|
|
continue-on-error: true
|
|
|
|
sonar-analysis:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
image: sonarsource/sonar-scanner-cli:latest
|
|
env:
|
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
steps:
|
|
- name: Install Node.js for checkout action
|
|
run: |
|
|
apk add --no-cache nodejs npm curl
|
|
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Run SonarScanner
|
|
run: |
|
|
sonar-scanner \
|
|
-Dsonar.projectKey=ansible-infra \
|
|
-Dsonar.sources=. \
|
|
-Dsonar.host.url=${SONAR_HOST_URL} \
|
|
-Dsonar.login=${SONAR_TOKEN}
|
|
continue-on-error: true
|
|
|
|
workflow-summary:
|
|
runs-on: ubuntu-latest
|
|
needs: [lint-and-test, ansible-validation, secret-scanning, dependency-scan, sast-scan, license-check, vault-check, playbook-test, container-scan, sonar-analysis]
|
|
if: always()
|
|
steps:
|
|
- name: Generate workflow summary
|
|
run: |
|
|
echo "## 🔍 CI Workflow Summary" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "### Job Results" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 📝 Markdown Linting | ${{ needs.lint-and-test.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🔧 Ansible Validation | ${{ needs.ansible-validation.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🔐 Secret Scanning | ${{ needs.secret-scanning.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 📦 Dependency Scan | ${{ needs.dependency-scan.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🔍 SAST Scan | ${{ needs.sast-scan.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 📄 License Check | ${{ needs.license-check.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🔒 Vault Check | ${{ needs.vault-check.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 📋 Playbook Test | ${{ needs.playbook-test.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🐳 Container Scan | ${{ needs.container-scan.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "| 🔍 SonarQube Analysis | ${{ needs.sonar-analysis.result }} |" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "### 📊 Summary" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "All security and validation checks have completed." >> $GITHUB_STEP_SUMMARY || true
|
|
echo "" >> $GITHUB_STEP_SUMMARY || true
|
|
echo "**Note:** Artifact uploads are not supported in Gitea Actions. Check individual job logs for detailed reports." >> $GITHUB_STEP_SUMMARY || true
|
|
continue-on-error: true
|