1+ # ==============================================================================
2+ # IRC.ATL.CHAT - DOCKER INFRASTRUCTURE LINTING
3+ # ==============================================================================
4+ #
5+ # This workflow handles Docker and infrastructure validation for the IRC server
6+ # project. It runs comprehensive linting on Dockerfiles, Docker Compose files,
7+ # and performs security scanning to ensure infrastructure quality.
8+ #
9+ # WORKFLOW FEATURES:
10+ # ------------------
11+ # 1. Smart file change detection to skip unnecessary jobs
12+ # 2. Parallel execution for different linting categories
13+ # 3. Comprehensive Docker linting with Hadolint
14+ # 4. Docker Compose syntax validation with modern docker compose
15+ # 5. Security vulnerability scanning with Trivy
16+ # 6. Efficient execution with conditional job running
17+ #
18+ # SECURITY FEATURES:
19+ # ------------------
20+ # - Minimal permissions following principle of least privilege
21+ # - Security scanning only on pull requests to avoid resource waste
22+ # - SARIF output integration with GitHub Security tab
23+ # - No sensitive data exposure in logs
24+ #
25+ # ==============================================================================
26+
27+ name : Docker Infrastructure CI
28+
29+ # TRIGGER CONFIGURATION
30+ # Runs on pushes to main/develop and all pull requests
31+ # Manual trigger available for testing workflow changes
32+ on :
33+ push :
34+ branches : [ main, develop ]
35+ pull_request :
36+ branches : [ main, develop ]
37+ # Manual trigger for debugging and testing workflow changes
38+ workflow_dispatch :
39+
40+ # CONCURRENCY CONTROL
41+ # Prevents multiple CI runs on the same branch to save resources
42+ # Cancels in-progress runs for PRs but allows main branch runs to complete
43+ concurrency :
44+ group : ${{ github.workflow }}-${{ github.ref }}
45+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
46+
47+ jobs :
48+ # ============================================================================
49+ # DOCKERFILE LINTING - Static Analysis and Best Practices
50+ # ============================================================================
51+ # Purpose: Ensures Docker best practices and security through Hadolint
52+ # Tools: Hadolint with SARIF output for GitHub Security integration
53+ # Optimization: Only runs when Docker files change or on manual trigger
54+ # ============================================================================
55+ dockerfile-lint :
56+ name : Dockerfile Linting
57+ runs-on : ubuntu-latest
58+ permissions :
59+ contents : read # Required for checkout
60+ security-events : write # Required for SARIF upload
61+ actions : read # Required for GitHub token
62+
63+ steps :
64+ # REPOSITORY CHECKOUT
65+ # Full history not needed for linting current state
66+ - name : Checkout Repository
67+ uses : actions/checkout@v4
68+
69+ # SMART CHANGE DETECTION
70+ # Detects Docker file changes to skip unnecessary runs
71+ # Includes all Dockerfile variants and related files
72+ - name : Detect Docker file changes
73+ uses : tj-actions/changed-files@v44
74+ id : docker_changes
75+ with :
76+ files : |
77+ **/Dockerfile*
78+ **/.dockerignore
79+ docker-compose*.yml
80+ docker-compose*.yaml
81+
82+ # EARLY TERMINATION FOR UNCHANGED FILES
83+ # Skips Hadolint setup if no relevant files changed
84+ # workflow_dispatch always runs for manual testing
85+ - name : Skip if no Docker changes
86+ if : steps.docker_changes.outputs.any_changed != 'true' && github.event_name != 'workflow_dispatch'
87+ run : |
88+ echo "✅ No Docker files changed, skipping Dockerfile linting"
89+ echo "💡 To force run checks, use workflow_dispatch trigger"
90+
91+ # DOCKERFILE DISCOVERY
92+ # Finds all Dockerfiles in the repository for comprehensive linting
93+ - name : Find Dockerfiles
94+ if : steps.docker_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
95+ id : dockerfiles
96+ run : |
97+ # Find all Dockerfiles in the repository
98+ dockerfiles=$(find . -name "Dockerfile*" -type f | grep -v ".git")
99+ if [ -n "$dockerfiles" ]; then
100+ echo "found=true" >> $GITHUB_OUTPUT
101+ echo "files<<EOF" >> $GITHUB_OUTPUT
102+ echo "$dockerfiles" >> $GITHUB_OUTPUT
103+ echo "EOF" >> $GITHUB_OUTPUT
104+ echo "Found Dockerfiles:"
105+ echo "$dockerfiles"
106+ else
107+ echo "found=false" >> $GITHUB_OUTPUT
108+ echo "No Dockerfiles found"
109+ fi
110+
111+ # HADOLINT SECURITY ANALYSIS
112+ # Comprehensive linting with SARIF output for GitHub Security
113+ # Ignores specific rules that may conflict with multi-stage builds
114+ - name : Lint Dockerfiles with Hadolint (Security Report)
115+ if : steps.dockerfiles.outputs.found == 'true'
116+ 117+ with :
118+ dockerfile : ' ./Dockerfile'
119+ failure-threshold : warning
120+ format : sarif
121+ output-file : hadolint-results.sarif
122+
123+ # SECURITY INTEGRATION
124+ # Uploads results to GitHub Security tab for centralized view
125+ # Always runs if Dockerfiles found, even if linting fails
126+ - name : Upload Hadolint results to GitHub Security
127+ if : steps.dockerfiles.outputs.found == 'true' && always()
128+ uses : github/codeql-action/upload-sarif@v3
129+ with :
130+ sarif_file : hadolint-results.sarif
131+
132+ # CONSOLE OUTPUT FOR IMMEDIATE FEEDBACK
133+ # Provides immediate feedback in workflow logs
134+ # Helps developers see issues without navigating to Security tab
135+ - name : Lint Dockerfiles with Hadolint (Console Output)
136+ if : steps.dockerfiles.outputs.found == 'true'
137+ 138+ with :
139+ dockerfile : ' ./Dockerfile'
140+ failure-threshold : warning
141+
142+ # ============================================================================
143+ # DOCKER COMPOSE LINTING - Syntax and Configuration Validation
144+ # ============================================================================
145+ # Purpose: Ensures Docker Compose files are syntactically correct and follow best practices
146+ # Tools: Docker Compose config validation and yamllint for YAML syntax
147+ # Optimization: Only runs when Compose files change or on manual trigger
148+ # ============================================================================
149+ docker-compose-lint :
150+ name : Docker Compose Linting
151+ runs-on : ubuntu-latest
152+ permissions :
153+ contents : read
154+
155+ steps :
156+ # REPOSITORY CHECKOUT
157+ # Shallow clone sufficient for validation current state
158+ - name : Checkout Repository
159+ uses : actions/checkout@v4
160+
161+ # SMART CHANGE DETECTION
162+ # Only runs when Docker Compose files change
163+ # Improves CI performance for non-compose changes
164+ - name : Detect Docker Compose changes
165+ uses : tj-actions/changed-files@v44
166+ id : compose_changes
167+ with :
168+ files : |
169+ docker-compose*.yml
170+ docker-compose*.yaml
171+ compose*.yml
172+ compose*.yaml
173+
174+ # EARLY TERMINATION FOR UNCHANGED FILES
175+ # Skips validation setup if no compose files changed
176+ - name : Skip if no Docker Compose changes
177+ if : steps.compose_changes.outputs.any_changed != 'true' && github.event_name != 'workflow_dispatch'
178+ run : |
179+ echo "✅ No Docker Compose files changed, skipping Docker Compose linting"
180+ echo "💡 To force run checks, use workflow_dispatch trigger"
181+
182+ # DOCKER COMPOSE FILE DISCOVERY
183+ # Finds all Docker Compose files in the repository
184+ - name : Find Docker Compose files
185+ if : steps.compose_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
186+ id : compose-files
187+ run : |
188+ # Find all docker-compose files in the repository
189+ compose_files=$(find . -name "docker-compose*.yml" -o -name "docker-compose*.yaml" -o -name "compose*.yml" -o -name "compose*.yaml" | grep -v ".git")
190+ if [ -n "$compose_files" ]; then
191+ echo "found=true" >> $GITHUB_OUTPUT
192+ echo "files<<EOF" >> $GITHUB_OUTPUT
193+ echo "$compose_files" >> $GITHUB_OUTPUT
194+ echo "EOF" >> $GITHUB_OUTPUT
195+ echo "Found Docker Compose files:"
196+ echo "$compose_files"
197+ else
198+ echo "found=false" >> $GITHUB_OUTPUT
199+ echo "No Docker Compose files found"
200+ fi
201+
202+ # DOCKER COMPOSE SYNTAX VALIDATION
203+ # Uses modern docker compose v2 for syntax validation
204+ # Validates without starting services using --quiet flag
205+ - name : Validate Docker Compose syntax
206+ if : steps.compose-files.outputs.found == 'true'
207+ run : |
208+ # Validate each docker-compose file using modern docker compose
209+ echo "${{ steps.compose-files.outputs.files }}" | while IFS= read -r file; do
210+ if [ -n "$file" ]; then
211+ echo "Validating $file..."
212+ if docker compose -f "$file" config --quiet; then
213+ echo "✅ $file is valid"
214+ else
215+ echo "❌ $file has syntax errors"
216+ exit 1
217+ fi
218+ fi
219+ done
220+
221+ # YAML LINTING FOR BEST PRACTICES
222+ # Uses yamllint for comprehensive YAML syntax checking
223+ # Provides additional validation beyond Docker Compose syntax
224+ - name : YAML linting with yamllint
225+ if : steps.compose-files.outputs.found == 'true'
226+ run : |
227+ # Install yamllint for YAML syntax validation
228+ sudo apt-get update && sudo apt-get install -y yamllint
229+
230+ # Create yamllint config for Docker Compose specifics
231+ cat > .yamllint.yml << EOF
232+ extends: default
233+ rules:
234+ line-length:
235+ max: 120 # Longer lines acceptable for Docker commands
236+ comments-indentation: disable # Docker Compose has specific comment styles
237+ truthy:
238+ allowed-values: ['true', 'false', 'yes', 'no'] # Docker Compose uses various boolean formats
239+ EOF
240+
241+ # Validate each docker-compose file with yamllint
242+ echo "${{ steps.compose-files.outputs.files }}" | while IFS= read -r file; do
243+ if [ -n "$file" ]; then
244+ echo "Running yamllint on $file..."
245+ yamllint -c .yamllint.yml "$file"
246+ fi
247+ done
248+
249+ # ============================================================================
250+ # DOCKER SECURITY SCANNING - Vulnerability Assessment
251+ # ============================================================================
252+ # Purpose: Scans Docker images for security vulnerabilities using Trivy
253+ # Scope: Only runs on pull requests to avoid unnecessary resource usage
254+ # Tools: Trivy scanner with SARIF output for GitHub Security integration
255+ # ============================================================================
256+ docker-security-scan :
257+ name : Docker Security Scanning
258+ runs-on : ubuntu-latest
259+ permissions :
260+ contents : read # Required for checkout
261+ security-events : write # Required for SARIF upload
262+ actions : read # Required for GitHub token
263+ # EXECUTION CONTROL
264+ # Only run on pull requests to avoid resource waste on every push
265+ # Manual trigger available for security audits
266+ if : github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
267+
268+ steps :
269+ # REPOSITORY CHECKOUT
270+ # Full history not needed for security scanning
271+ - name : Checkout Repository
272+ uses : actions/checkout@v4
273+
274+ # SMART CHANGE DETECTION FOR DOCKER FILES
275+ # Only scan if Docker-related files changed
276+ - name : Detect Docker changes for security scan
277+ uses : tj-actions/changed-files@v44
278+ id : security_changes
279+ with :
280+ files : |
281+ **/Dockerfile*
282+ docker-compose*.yml
283+ docker-compose*.yaml
284+
285+ # EARLY TERMINATION FOR UNCHANGED DOCKER FILES
286+ # Skip security scan if no Docker files changed (unless manual trigger)
287+ - name : Skip if no Docker changes
288+ if : steps.security_changes.outputs.any_changed != 'true' && github.event_name != 'workflow_dispatch'
289+ run : |
290+ echo "✅ No Docker files changed, skipping security scan"
291+ echo "💡 To force run security scan, use workflow_dispatch trigger"
292+
293+ # DOCKER IMAGE BUILD
294+ # Build image for security scanning with proper error handling
295+ - name : Build Docker image for security scanning
296+ if : steps.security_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
297+ run : |
298+ if [ -f "Dockerfile" ]; then
299+ echo "Building Docker image for security scanning..."
300+ docker build -t irc-security-scan:latest .
301+ echo "✅ Docker image built successfully"
302+ else
303+ echo "❌ No Dockerfile found in root directory"
304+ echo "Security scan requires a Dockerfile to analyze"
305+ exit 1
306+ fi
307+
308+ # TRIVY SECURITY SCAN WITH SARIF OUTPUT
309+ # Comprehensive vulnerability scanning with GitHub Security integration
310+ - name : Run Trivy vulnerability scanner (SARIF)
311+ if : steps.security_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
312+ uses : aquasecurity/trivy-action@master
313+ with :
314+ image-ref : ' irc-security-scan:latest'
315+ format : ' sarif'
316+ output : ' trivy-results.sarif'
317+
318+ # SECURITY RESULTS UPLOAD
319+ # Upload security findings to GitHub Security tab
320+ # Always runs if scan executed, even if vulnerabilities found
321+ - name : Upload Trivy scan results to GitHub Security
322+ if : (steps.security_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch') && always()
323+ uses : github/codeql-action/upload-sarif@v3
324+ with :
325+ sarif_file : ' trivy-results.sarif'
326+
327+ # CONSOLE OUTPUT FOR IMMEDIATE FEEDBACK
328+ # Provides immediate feedback in workflow logs with severity filtering
329+ # Focuses on actionable vulnerabilities (CRITICAL, HIGH with fixes available)
330+ - name : Run Trivy vulnerability scanner (Console Output)
331+ if : steps.security_changes.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch'
332+ uses : aquasecurity/trivy-action@master
333+ with :
334+ image-ref : ' irc-security-scan:latest'
335+ format : ' table'
336+ exit-code : ' 1'
337+ ignore-unfixed : true
338+ vuln-type : ' os,library'
339+ severity : ' CRITICAL,HIGH'
340+
341+ # ==============================================================================
342+ # WORKFLOW BEST PRACTICES IMPLEMENTED
343+ # ==============================================================================
344+ #
345+ # 1. PERFORMANCE OPTIMIZATION:
346+ # - Smart change detection to skip unnecessary work
347+ # - Parallel job execution across linting categories
348+ # - Early termination for unchanged files
349+ # - Conditional security scanning only on PRs
350+ #
351+ # 2. SECURITY & PERMISSIONS:
352+ # - Minimal required permissions for each job
353+ # - SARIF integration with GitHub Security tab
354+ # - No sensitive data exposure in validation
355+ # - Comprehensive vulnerability scanning
356+ #
357+ # 3. MAINTAINABILITY:
358+ # - Clear job names and comprehensive documentation
359+ # - Consistent error handling and reporting
360+ # - Version pinning for reproducible builds
361+ # - Configurable yamllint rules for Docker Compose
362+ #
363+ # 4. DEVELOPER EXPERIENCE:
364+ # - Clear skip messages explaining why jobs didn't run
365+ # - Both Security tab and console output for findings
366+ # - Manual trigger option for debugging and testing
367+ # - Comprehensive validation across all Docker files
368+ #
369+ # 5. INFRASTRUCTURE FOCUS:
370+ # - Docker best practices enforcement with Hadolint
371+ # - Modern docker compose v2 validation
372+ # - YAML syntax validation for configuration files
373+ # - Security vulnerability assessment for images
374+ #
375+ # USAGE EXAMPLES:
376+ # ---------------
377+ # Manual trigger:
378+ # GitHub UI → Actions → Docker Infrastructure CI → Run workflow
379+ #
380+ # Force run all checks:
381+ # Uses workflow_dispatch trigger to bypass change detection
382+ #
383+ # View security results:
384+ # Check Security tab for vulnerability reports and SARIF data
385+ #
386+ # View linting results:
387+ # Check Actions tab for detailed logs and console output
388+ #
389+ # ==============================================================================
0 commit comments