Skip to content

🔧 fix(matrix-synapse): refactor MAS argument handling to use escapeSh… #617

🔧 fix(matrix-synapse): refactor MAS argument handling to use escapeSh…

🔧 fix(matrix-synapse): refactor MAS argument handling to use escapeSh… #617

name: Configuration Compliance Check
on:
workflow_dispatch:
pull_request:
paths:
- "**.nix"
push:
branches: [main]
schedule:
- cron: "0 9 * * 1"
concurrency:
group: compliance-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
jobs:
compliance-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v21
- name: Setup Nix cache
uses: DeterminateSystems/magic-nix-cache-action@v13
with:
use-flakehub: false
- name: Run dead code detection
id: deadnix
run: |
echo "## 🔍 Dead Code Analysis" > compliance-report.md
echo "" >> compliance-report.md
# Capture deadnix output
if deadnix_output=$(nix run nixpkgs#deadnix -- --no-lambda-arg --no-lambda-pattern-names . 2>&1); then
echo "✅ No dead code found" >> compliance-report.md
echo "dead_code=clean" >> $GITHUB_OUTPUT
else
echo "⚠️ Dead code detected:" >> compliance-report.md
echo "" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
echo "$deadnix_output" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
echo "dead_code=found" >> $GITHUB_OUTPUT
fi
echo "" >> compliance-report.md
- name: Run static analysis
id: statix
run: |
echo "## 🔎 Static Analysis (Statix)" >> compliance-report.md
echo "" >> compliance-report.md
# Capture statix output
if statix_output=$(nix run nixpkgs#statix -- check . 2>&1); then
echo "✅ No static analysis issues found" >> compliance-report.md
echo "static_analysis=clean" >> $GITHUB_OUTPUT
else
echo "⚠️ Static analysis issues detected:" >> compliance-report.md
echo "" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
echo "$statix_output" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
echo "static_analysis=issues" >> $GITHUB_OUTPUT
fi
echo "" >> compliance-report.md
- name: Check configuration patterns
id: patterns
run: |
echo "## 📋 Configuration Best Practices" >> compliance-report.md
echo "" >> compliance-report.md
patterns_failed=0
# Check for hardcoded secrets
echo "### Security Checks" >> compliance-report.md
# Use a more robust approach to avoid broken pipe errors
password_matches=$(grep -r "password.*=" --include="*.nix" . 2>/dev/null | grep -v "passwordAuthentication\|passwordFile\|hashedPassword" || true)
if [ -n "$password_matches" ]; then
echo "❌ **Hardcoded passwords detected**" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
echo "$password_matches" >> compliance-report.md
echo "\`\`\`" >> compliance-report.md
patterns_failed=1
else
echo "✅ No hardcoded passwords found" >> compliance-report.md
fi
# Check for proper module structure
echo "" >> compliance-report.md
echo "### Module Structure" >> compliance-report.md
# Check if modules have proper enable options
module_issues=0
for module_dir in modules/*/; do
if [ -d "$module_dir" ]; then
module_name=$(basename "$module_dir")
has_enable=$(grep -Erl "mkEnableOption|enable.*mkOption.*bool" "$module_dir" --include="*.nix" 2>/dev/null | head -1)
if [ -z "$has_enable" ]; then
echo "⚠️ Module \`$module_name\` may be missing enable option" >> compliance-report.md
module_issues=1
fi
fi
done
if [ $module_issues -eq 0 ]; then
echo "✅ Module structure looks good" >> compliance-report.md
fi
# Check for documentation
echo "" >> compliance-report.md
echo "### Documentation" >> compliance-report.md
if [ ! -f "README.md" ] || [ $(wc -l < "README.md") -lt 10 ]; then
echo "⚠️ README.md is missing or too short" >> compliance-report.md
patterns_failed=1
else
echo "✅ README.md exists and has content" >> compliance-report.md
fi
# Check for version pinning
echo "" >> compliance-report.md
echo "### Dependency Management" >> compliance-report.md
has_unstable=$(grep -c "nixos-unstable" flake.nix 2>/dev/null || echo "0")
has_stable_version=$(grep -c "nixos-[0-9][0-9]\.[0-9][0-9]" flake.nix 2>/dev/null || echo "0")
if [ "$has_unstable" -gt 0 ] && [ "$has_stable_version" -eq 0 ]; then
echo "ℹ️ Using unstable channel - consider pinning stable versions for production" >> compliance-report.md
else
echo "✅ Good use of version pinning" >> compliance-report.md
fi
# Check host naming consistency
echo "" >> compliance-report.md
echo "### Naming Conventions" >> compliance-report.md
host_names=$(ls hosts/ 2>/dev/null | grep -v "README" || true)
consistent_naming=true
naming_issues=""
for host in $host_names; do
# Check if host name follows kebab-case (lowercase, with hyphens, no leading/trailing hyphens)
if [[ ! "$host" =~ ^[a-z]([a-z0-9-]*[a-z0-9])?$ ]]; then
naming_issues="${naming_issues}⚠️ Host name '$host' doesn't follow kebab-case convention\n"
consistent_naming=false
fi
done
if [ "$consistent_naming" = true ]; then
echo "✅ Host naming follows conventions" >> compliance-report.md
else
echo -e "$naming_issues" >> compliance-report.md
fi
echo "patterns_result=$patterns_failed" >> $GITHUB_OUTPUT
- name: Check configuration completeness
run: |
echo "" >> compliance-report.md
echo "## 🎯 Configuration Completeness" >> compliance-report.md
echo "" >> compliance-report.md
for host in $(grep -oP '^\s+\K\w+(?=\s*=\s*mkHost)' flake.nix); do
echo "### Host: $host" >> compliance-report.md
# Check required files exist (files are named after the host)
required_files=(
"hosts/$host/$host.nix"
"hosts/$host/hardware-configuration.nix"
)
missing_files=0
for file in "${required_files[@]}"; do
if [ ! -f "$file" ]; then
echo "❌ Missing: $file" >> compliance-report.md
missing_files=1
fi
done
if [ $missing_files -eq 0 ]; then
echo "✅ All required files present" >> compliance-report.md
fi
# Check for common configurations (uses host-named file)
if [ -f "hosts/$host/$host.nix" ]; then
config_file="hosts/$host/$host.nix"
# Check for hostname setting (looks for hostName anywhere in the file)
if grep -q "hostName\s*=.*\(lib\.mkForce\|lib\.mkDefault\|\"\)" "$config_file"; then
echo "✅ Hostname configured" >> compliance-report.md
else
echo "⚠️ Missing explicit hostname setting" >> compliance-report.md
fi
# Check for timezone setting (either in host file or global locale module)
has_local_timezone=$(grep -q "time\.timeZone" "$config_file" && echo "true" || echo "false")
has_global_timezone=$(grep -q "time\.timeZone" modules/core/locale.nix 2>/dev/null && echo "true" || echo "false")
if [ "$has_local_timezone" = "true" ] || [ "$has_global_timezone" = "true" ]; then
echo "✅ Timezone configured" >> compliance-report.md
else
echo "⚠️ Missing timezone configuration" >> compliance-report.md
fi
if ! grep -q "services.openssh" "$config_file" && ! grep -rq "services.openssh" modules/ hosts/ 2>/dev/null; then
echo "ℹ️ No SSH configuration found (may be intentional)" >> compliance-report.md
fi
fi
echo "" >> compliance-report.md
done
- name: Generate compliance score
run: |
echo "" >> compliance-report.md
echo "## 📊 Compliance Score" >> compliance-report.md
echo "" >> compliance-report.md
# Calculate score based on checks
score=100
if [ "${{ steps.deadnix.outputs.dead_code }}" = "found" ]; then
score=$((score - 10))
echo "- Dead code found: -10 points" >> compliance-report.md
fi
if [ "${{ steps.statix.outputs.static_analysis }}" = "issues" ]; then
score=$((score - 15))
echo "- Static analysis issues: -15 points" >> compliance-report.md
fi
if [ "${{ steps.patterns.outputs.patterns_result }}" = "1" ]; then
score=$((score - 20))
echo "- Pattern violations: -20 points" >> compliance-report.md
fi
echo "" >> compliance-report.md
echo "**Overall Score: $score/100**" >> compliance-report.md
if [ $score -ge 90 ]; then
echo "🏆 **Grade: Excellent** - Configuration follows best practices" >> compliance-report.md
elif [ $score -ge 80 ]; then
echo "🥈 **Grade: Good** - Minor improvements recommended" >> compliance-report.md
elif [ $score -ge 70 ]; then
echo "🥉 **Grade: Fair** - Several areas need attention" >> compliance-report.md
else
echo "📝 **Grade: Needs Improvement** - Multiple issues to address" >> compliance-report.md
fi
- name: Upload compliance report
uses: actions/upload-artifact@v6
with:
name: compliance-report
path: compliance-report.md
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const comment = require('.github/scripts/comment');
const report = fs.readFileSync('compliance-report.md', 'utf8');
const header = '## 📋 Configuration Compliance Check';
const body = report;
await comment({ github, context, header, body });