Skip to content

Commit 6b39d91

Browse files
committed
ci: enforce strict quality gates in CI/CD pipeline
- Add explicit exit codes for lint, type-check, prettier, and build failures - Add coverage threshold validation that fails on unmet targets - Enhance security audit with clear warning messages - Fix ESLint warnings with proper disable comments for dynamic images - Format all files with Prettier All checks now properly fail the workflow if quality standards are not met: ✅ ESLint must pass (0 errors, 0 warnings) ✅ Prettier formatting must be correct ✅ TypeScript type check must pass ✅ All tests must pass ✅ Coverage thresholds must be met (80% statements, 70% branches, 68% functions, 80% lines) ✅ Build must succeed Deployment to Vercel will only occur after ALL checks pass.
1 parent c98467c commit 6b39d91

File tree

3 files changed

+92
-9
lines changed

3 files changed

+92
-9
lines changed

.github/workflows/ci.yml

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,34 @@ jobs:
3333
run: npm ci
3434

3535
- name: Run ESLint
36-
run: npm run lint
36+
run: |
37+
echo "Running ESLint..."
38+
npm run lint
39+
if [ $? -ne 0 ]; then
40+
echo "❌ ESLint check failed!"
41+
exit 1
42+
fi
43+
echo "✅ ESLint passed"
3744
3845
- name: Run Prettier check
39-
run: npm run format:check
46+
run: |
47+
echo "Running Prettier check..."
48+
npm run format:check
49+
if [ $? -ne 0 ]; then
50+
echo "❌ Prettier check failed!"
51+
exit 1
52+
fi
53+
echo "✅ Prettier check passed"
4054
4155
- name: Run type check
42-
run: npm run type-check
56+
run: |
57+
echo "Running TypeScript type check..."
58+
npm run type-check
59+
if [ $? -ne 0 ]; then
60+
echo "❌ Type check failed!"
61+
exit 1
62+
fi
63+
echo "✅ Type check passed"
4364
4465
test:
4566
name: Test & Coverage
@@ -63,7 +84,51 @@ jobs:
6384
run: npm ci
6485

6586
- name: Run tests with coverage
66-
run: npm run test:coverage
87+
run: |
88+
echo "Running tests with coverage..."
89+
npm run test:coverage
90+
if [ $? -ne 0 ]; then
91+
echo "❌ Tests failed!"
92+
exit 1
93+
fi
94+
echo "✅ All tests passed"
95+
96+
- name: Check coverage thresholds
97+
run: |
98+
echo "Checking coverage thresholds..."
99+
node -e "
100+
const coverage = require('./coverage/coverage-summary.json');
101+
const total = coverage.total;
102+
const thresholds = {
103+
statements: 80,
104+
branches: 70,
105+
functions: 68,
106+
lines: 80
107+
};
108+
109+
let failed = false;
110+
Object.keys(thresholds).forEach(key => {
111+
const actual = total[key].pct;
112+
const required = thresholds[key];
113+
if (actual < required) {
114+
console.log(\`❌ ${key}: ${actual.toFixed(2)}% < ${required}% (threshold)\`);
115+
failed = true;
116+
} else {
117+
console.log(\`✅ ${key}: ${actual.toFixed(2)}% >= ${required}%\`);
118+
}
119+
});
120+
121+
if (failed) {
122+
console.log('\\n❌ Coverage thresholds not met!');
123+
process.exit(1);
124+
} else {
125+
console.log('\\n✅ All coverage thresholds met!');
126+
}
127+
"
128+
if [ $? -ne 0 ]; then
129+
echo "❌ Coverage check failed!"
130+
exit 1
131+
fi
67132
68133
- name: Upload coverage to Codecov
69134
uses: codecov/codecov-action@v4
@@ -139,7 +204,14 @@ jobs:
139204
run: npm ci
140205

141206
- name: Build application
142-
run: npm run build
207+
run: |
208+
echo "Building Next.js application..."
209+
npm run build
210+
if [ $? -ne 0 ]; then
211+
echo "❌ Build failed!"
212+
exit 1
213+
fi
214+
echo "✅ Build successful"
143215
env:
144216
NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL || 'https://rudrasahoo.live' }}
145217

@@ -163,8 +235,17 @@ jobs:
163235
with:
164236
node-version: "20"
165237

238+
- name: Install dependencies
239+
run: npm ci
240+
166241
- name: Run security audit
167-
run: npm audit --audit-level=moderate
242+
run: |
243+
echo "Running npm security audit..."
244+
npm audit --audit-level=moderate
245+
if [ $? -ne 0 ]; then
246+
echo "⚠️ Security vulnerabilities found!"
247+
echo "Note: This won't block deployment but should be reviewed"
248+
fi
168249
continue-on-error: true
169250

170251
- name: Check for outdated packages
@@ -178,7 +259,7 @@ jobs:
178259
# 2. All tests and checks passed
179260
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
180261
needs: [lint-and-type-check, test, build, security-audit]
181-
262+
182263
steps:
183264
- name: Checkout code
184265
uses: actions/checkout@v4
@@ -189,7 +270,7 @@ jobs:
189270
vercel-token: ${{ secrets.VERCEL_TOKEN }}
190271
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
191272
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
192-
vercel-args: '--prod'
273+
vercel-args: "--prod"
193274
working-directory: ./
194275

195276
- name: Comment deployment success
@@ -211,7 +292,7 @@ jobs:
211292
# Deploy preview for PRs after all checks pass
212293
if: github.event_name == 'pull_request'
213294
needs: [lint-and-type-check, test, build, security-audit]
214-
295+
215296
steps:
216297
- name: Checkout code
217298
uses: actions/checkout@v4

src/components/projects/ReadmeViewer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ const ReadmeViewer: React.FC<ReadmeViewerProps> = ({ content }) => {
109109
) => {
110110
const { src, alt, width, ...restProps } = props;
111111
return (
112+
// eslint-disable-next-line @next/next/no-img-element
112113
<img
113114
src={src}
114115
alt={alt}

src/components/ui/compare.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export const Compare = ({
193193
}}
194194
transition={{ duration: 0 }}
195195
>
196+
{/* eslint-disable-next-line @next/next/no-img-element */}
196197
<img
197198
alt="first image"
198199
src={firstImage}

0 commit comments

Comments
 (0)