🔧 fix(matrix-synapse): refactor MAS argument handling to use escapeSh… #617
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 }); |