Skip to content

Commit 262e06e

Browse files
committed
ci: add comprehensive GitHub Actions workflow
Implement complete CI/CD pipeline with 7 jobs: 1. Lint & Format Check: - ESLint validation - Prettier format check - Ensures code quality standards 2. TypeScript Type Check: - Runs tsc --noEmit - Catches type errors early 3. Run Tests: - Executes test suite with Vitest - Generates coverage report (80% threshold) - Uploads coverage to Codecov (optional) 4. Build Application: - Compiles Next.js for production - Uses NEXT_PUBLIC_SITE_URL env var - Uploads build artifacts (7-day retention) 5. Lighthouse CI (PR only): - Performance testing with Lighthouse - Runs on pull requests only - Uploads artifacts and public storage 6. Security Audit: - Runs npm audit for vulnerabilities - Production dependencies only - Continue on error (informational) 7. CI Status Check: - Summary of all job results - Posts comment on PRs with status - Fails if any required job fails Features: - Runs on push to master and PRs - Node.js 20.x with npm cache - Parallel job execution where possible - Artifact uploads for debugging - Status comments on PRs Workflow ensures quality before merge and maintains professional standards for public portfolio repository. Closes #41
1 parent b3cda20 commit 262e06e

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
env:
10+
NODE_VERSION: '20.x'
11+
12+
jobs:
13+
# Job 1: Lint and Format Check
14+
lint:
15+
name: Lint & Format Check
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: ${{ env.NODE_VERSION }}
26+
cache: 'npm'
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Run ESLint
32+
run: npm run lint
33+
34+
- name: Check Prettier formatting
35+
run: npm run format:check
36+
37+
# Job 2: Type Check
38+
typecheck:
39+
name: TypeScript Type Check
40+
runs-on: ubuntu-latest
41+
42+
steps:
43+
- name: Checkout code
44+
uses: actions/checkout@v4
45+
46+
- name: Setup Node.js
47+
uses: actions/setup-node@v4
48+
with:
49+
node-version: ${{ env.NODE_VERSION }}
50+
cache: 'npm'
51+
52+
- name: Install dependencies
53+
run: npm ci
54+
55+
- name: Run TypeScript compiler
56+
run: npx tsc --noEmit
57+
58+
# Job 3: Tests
59+
test:
60+
name: Run Tests
61+
runs-on: ubuntu-latest
62+
63+
steps:
64+
- name: Checkout code
65+
uses: actions/checkout@v4
66+
67+
- name: Setup Node.js
68+
uses: actions/setup-node@v4
69+
with:
70+
node-version: ${{ env.NODE_VERSION }}
71+
cache: 'npm'
72+
73+
- name: Install dependencies
74+
run: npm ci
75+
76+
- name: Run tests
77+
run: npm run test:run
78+
79+
- name: Generate coverage report
80+
run: npm run test:coverage
81+
continue-on-error: true
82+
83+
- name: Upload coverage reports
84+
uses: codecov/codecov-action@v4
85+
if: always()
86+
continue-on-error: true
87+
with:
88+
files: ./coverage/coverage-final.json
89+
flags: unittests
90+
name: codecov-umbrella
91+
92+
# Job 4: Build
93+
build:
94+
name: Build Application
95+
runs-on: ubuntu-latest
96+
needs: [lint, typecheck, test]
97+
98+
steps:
99+
- name: Checkout code
100+
uses: actions/checkout@v4
101+
102+
- name: Setup Node.js
103+
uses: actions/setup-node@v4
104+
with:
105+
node-version: ${{ env.NODE_VERSION }}
106+
cache: 'npm'
107+
108+
- name: Install dependencies
109+
run: npm ci
110+
111+
- name: Build Next.js application
112+
run: npm run build
113+
env:
114+
NEXT_PUBLIC_SITE_URL: https://angelhidalgo.dev
115+
116+
- name: Upload build artifacts
117+
uses: actions/upload-artifact@v4
118+
with:
119+
name: build-output
120+
path: .next
121+
retention-days: 7
122+
123+
# Job 5: Lighthouse CI (Optional - runs only on PRs)
124+
lighthouse:
125+
name: Lighthouse Performance Check
126+
runs-on: ubuntu-latest
127+
needs: build
128+
if: github.event_name == 'pull_request'
129+
130+
steps:
131+
- name: Checkout code
132+
uses: actions/checkout@v4
133+
134+
- name: Setup Node.js
135+
uses: actions/setup-node@v4
136+
with:
137+
node-version: ${{ env.NODE_VERSION }}
138+
cache: 'npm'
139+
140+
- name: Install dependencies
141+
run: npm ci
142+
143+
- name: Build for Lighthouse
144+
run: npm run build
145+
146+
- name: Run Lighthouse CI
147+
uses: treosh/lighthouse-ci-action@v10
148+
with:
149+
urls: |
150+
http://localhost:3000
151+
uploadArtifacts: true
152+
temporaryPublicStorage: true
153+
154+
# Job 6: Security Audit
155+
security:
156+
name: Security Audit
157+
runs-on: ubuntu-latest
158+
159+
steps:
160+
- name: Checkout code
161+
uses: actions/checkout@v4
162+
163+
- name: Setup Node.js
164+
uses: actions/setup-node@v4
165+
with:
166+
node-version: ${{ env.NODE_VERSION }}
167+
cache: 'npm'
168+
169+
- name: Run npm audit
170+
run: npm audit --production
171+
continue-on-error: true
172+
173+
# Job 7: Status Check Summary
174+
status:
175+
name: CI Status Check
176+
runs-on: ubuntu-latest
177+
needs: [lint, typecheck, test, build]
178+
if: always()
179+
180+
steps:
181+
- name: Check job status
182+
run: |
183+
if [[ "${{ needs.lint.result }}" == "failure" ||
184+
"${{ needs.typecheck.result }}" == "failure" ||
185+
"${{ needs.test.result }}" == "failure" ||
186+
"${{ needs.build.result }}" == "failure" ]]; then
187+
echo "❌ CI Pipeline failed"
188+
exit 1
189+
else
190+
echo "✅ CI Pipeline passed"
191+
fi
192+
193+
- name: Post status comment (PR only)
194+
if: github.event_name == 'pull_request'
195+
uses: actions/github-script@v7
196+
with:
197+
script: |
198+
const status = '${{ needs.lint.result }}' === 'success' &&
199+
'${{ needs.typecheck.result }}' === 'success' &&
200+
'${{ needs.test.result }}' === 'success' &&
201+
'${{ needs.build.result }}' === 'success';
202+
203+
const body = status
204+
? '✅ **CI Pipeline passed!** All checks completed successfully.'
205+
: '❌ **CI Pipeline failed!** Please check the workflow logs.';
206+
207+
github.rest.issues.createComment({
208+
issue_number: context.issue.number,
209+
owner: context.repo.owner,
210+
repo: context.repo.repo,
211+
body: body
212+
});

0 commit comments

Comments
 (0)