1+ name : CI/CD Pipeline
2+
3+ on :
4+ push :
5+ branches : [ main, develop ]
6+ pull_request :
7+ branches : [ main ]
8+
9+ env :
10+ DOCKER_IMAGE : ${{ secrets.DOCKERHUB_USERNAME }}/nodejs-k8s-app
11+ NODE_VERSION : ' 20'
12+
13+ jobs :
14+ lint :
15+ name : Lint & Format Check
16+ runs-on : ubuntu-latest
17+
18+ steps :
19+ - uses : actions/checkout@v4
20+
21+ - name : Setup Node.js
22+ uses : actions/setup-node@v4
23+ with :
24+ node-version : ${{ env.NODE_VERSION }}
25+ cache : ' npm'
26+
27+ - name : Install dependencies
28+ run : npm ci
29+
30+ - name : Run ESLint
31+ run : npm run lint
32+
33+ - name : Check formatting
34+ run : npx prettier --check "src/**/*.js" "specs/**/*.js"
35+
36+ test :
37+ name : Tests unitaires
38+ runs-on : ubuntu-latest
39+ needs : lint
40+
41+ strategy :
42+ matrix :
43+ node-version : [20, 22]
44+
45+ steps :
46+ - uses : actions/checkout@v4
47+
48+ - name : Setup Node.js ${{ matrix.node-version }}
49+ uses : actions/setup-node@v4
50+ with :
51+ node-version : ${{ matrix.node-version }}
52+ cache : ' npm'
53+
54+ - name : Install dependencies
55+ run : npm ci
56+
57+ - name : Run tests
58+ run : npm test -- --coverage
59+
60+ - name : Upload coverage to Codecov
61+ if : matrix.node-version == 20
62+ uses : codecov/codecov-action@v3
63+ with :
64+ file : ./coverage/coverage-final.json
65+ flags : unittests
66+ fail_ci_if_error : false
67+
68+ build-and-push :
69+ name : Build et Push Docker Image
70+ needs : test
71+ runs-on : ubuntu-latest
72+ if : github.event_name == 'push' && github.ref == 'refs/heads/main'
73+
74+ outputs :
75+ image-digest : ${{ steps.build.outputs.digest }}
76+
77+ steps :
78+ - uses : actions/checkout@v4
79+
80+ - name : Set up QEMU
81+ uses : docker/setup-qemu-action@v3
82+
83+ - name : Set up Docker Buildx
84+ uses : docker/setup-buildx-action@v3
85+
86+ - name : Login to DockerHub
87+ uses : docker/login-action@v3
88+ with :
89+ username : ${{ secrets.DOCKERHUB_USERNAME }}
90+ password : ${{ secrets.DOCKERHUB_TOKEN }}
91+
92+ - name : Extract metadata
93+ id : meta
94+ uses : docker/metadata-action@v5
95+ with :
96+ images : ${{ env.DOCKER_IMAGE }}
97+ tags : |
98+ type=ref,event=branch
99+ type=sha,prefix={{branch}}-
100+ type=semver,pattern={{version}}
101+ type=raw,value=latest,enable={{is_default_branch}}
102+
103+ - name : Build and push
104+ id : build
105+ uses : docker/build-push-action@v5
106+ with :
107+ context : .
108+ platforms : linux/amd64,linux/arm64
109+ push : true
110+ tags : ${{ steps.meta.outputs.tags }}
111+ labels : ${{ steps.meta.outputs.labels }}
112+ cache-from : type=registry,ref=${{ env.DOCKER_IMAGE }}:buildcache
113+ cache-to : type=registry,ref=${{ env.DOCKER_IMAGE }}:buildcache,mode=max
114+
115+ - name : Image digest
116+ run : echo ${{ steps.build.outputs.digest }}
117+
118+ security-scan :
119+ name : Security Scan
120+ needs : build-and-push
121+ runs-on : ubuntu-latest
122+ if : github.event_name == 'push' && github.ref == 'refs/heads/main'
123+
124+ steps :
125+ - name : Run Trivy vulnerability scanner
126+ uses : aquasecurity/trivy-action@master
127+ with :
128+ image-ref : ${{ env.DOCKER_IMAGE }}:latest
129+ format : ' sarif'
130+ output : ' trivy-results.sarif'
131+ severity : ' CRITICAL,HIGH'
132+
133+ - name : Upload Trivy results to GitHub Security
134+ uses : github/codeql-action/upload-sarif@v2
135+ if : always()
136+ with :
137+ sarif_file : ' trivy-results.sarif'
138+
139+ - name : Run npm audit
140+ uses : actions/checkout@v4
141+
142+ - name : Setup Node.js
143+ uses : actions/setup-node@v4
144+ with :
145+ node-version : ${{ env.NODE_VERSION }}
146+
147+ - name : NPM Audit
148+ run : |
149+ npm audit --audit-level=high
150+ continue-on-error : true
151+
152+ notify :
153+ name : Notification
154+ needs : [build-and-push, security-scan]
155+ runs-on : ubuntu-latest
156+ if : always()
157+
158+ steps :
159+ - name : Success notification
160+ if : needs.build-and-push.result == 'success'
161+ run : |
162+ echo "✅ Build and deployment successful!"
163+ echo "Image: ${{ env.DOCKER_IMAGE }}:latest"
164+
165+ - name : Failure notification
166+ if : needs.build-and-push.result == 'failure'
167+ run : |
168+ echo "❌ Build or deployment failed!"
169+ exit 1
0 commit comments