Skip to content

Commit 6bb5d56

Browse files
authored
Merge pull request #7606 from sonalgaud12/ci-codecov
ci: consolidate workflows and add commitlint + husky hooks
2 parents 2660a61 + 1487952 commit 6bb5d56

11 files changed

Lines changed: 1023 additions & 2671 deletions

File tree

.github/workflows/ci.yml

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
name: CI
2+
3+
# Unified CI pipeline.
4+
# Consolidates: Smoke Test (build), ESLint & Prettier (lint),
5+
# Jest Tests, Cypress E2E, and Security Scans into a single workflow,
6+
# plus commit-message linting (commitlint).
7+
#
8+
# Trigger note: uses `pull_request` (NOT pull_request_target) so untrusted
9+
# fork code is never executed with repository secrets or a write-scoped token.
10+
# See the Codecov note in ci.yml's `test` job re: fork PRs.
11+
12+
on:
13+
push:
14+
branches: [master]
15+
pull_request:
16+
branches: [master]
17+
18+
# One in-flight run per PR / ref; newer pushes cancel older runs.
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
21+
cancel-in-progress: true
22+
23+
# Least privilege by default; individual jobs do not need more.
24+
permissions:
25+
contents: read
26+
27+
jobs:
28+
# ----------------------------------------------------------------------
29+
# Commit message linting (conventional commits)
30+
# ----------------------------------------------------------------------
31+
commitlint:
32+
name: Lint commit messages
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 30
35+
steps:
36+
- name: Checkout code
37+
uses: actions/checkout@v4
38+
with:
39+
fetch-depth: 0
40+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
41+
42+
- name: Set up Node.js
43+
uses: actions/setup-node@v5
44+
with:
45+
node-version: '22'
46+
cache: 'npm'
47+
48+
- name: Install dependencies
49+
run: npm ci
50+
51+
- name: Lint PR commits
52+
if: github.event_name == 'pull_request'
53+
run: >-
54+
npx commitlint
55+
--from ${{ github.event.pull_request.base.sha }}
56+
--to ${{ github.event.pull_request.head.sha }}
57+
--verbose
58+
59+
# ----------------------------------------------------------------------
60+
# ESLint + Prettier on changed JS files only
61+
# ----------------------------------------------------------------------
62+
lint:
63+
name: Lint & format-check changed JS files
64+
runs-on: ubuntu-latest
65+
timeout-minutes: 30
66+
steps:
67+
- name: Checkout code
68+
uses: actions/checkout@v4
69+
with:
70+
fetch-depth: 0
71+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
72+
73+
- name: Set up Node.js
74+
uses: actions/setup-node@v5
75+
with:
76+
node-version: '22.x'
77+
cache: 'npm'
78+
79+
- name: Install dependencies
80+
run: npm ci
81+
82+
- name: Get changed JavaScript files
83+
id: get_files
84+
run: |
85+
if [ "${{ github.event_name }}" = "pull_request" ]; then
86+
BASE="${{ github.event.pull_request.base.sha }}"
87+
HEAD="${{ github.event.pull_request.head.sha }}"
88+
else
89+
BASE="${{ github.event.before }}"
90+
HEAD="${{ github.sha }}"
91+
fi
92+
93+
# Guard against the all-zero SHA on first push of a new branch.
94+
if ! git cat-file -e "$BASE^{commit}" 2>/dev/null; then
95+
BASE="$(git rev-parse "$HEAD^" 2>/dev/null || echo "$HEAD")"
96+
fi
97+
98+
git diff --diff-filter=ACMRT --name-only "$BASE" "$HEAD" \
99+
-- '*.js' '*.mjs' ':!node_modules/**' > changed-js-files.txt || true
100+
101+
if [ -s changed-js-files.txt ]; then
102+
echo "has_files=true" >> "$GITHUB_OUTPUT"
103+
else
104+
echo "has_files=false" >> "$GITHUB_OUTPUT"
105+
fi
106+
107+
- name: Run ESLint on changed files
108+
if: steps.get_files.outputs.has_files == 'true'
109+
run: |
110+
echo "Linting the following files:"
111+
cat changed-js-files.txt
112+
xargs -r npx eslint < changed-js-files.txt
113+
114+
- name: Run Prettier check on changed files
115+
if: steps.get_files.outputs.has_files == 'true'
116+
run: |
117+
echo "Checking formatting for the following files:"
118+
cat changed-js-files.txt
119+
xargs -r npx prettier --check < changed-js-files.txt
120+
121+
# ----------------------------------------------------------------------
122+
# Build / smoke test across Node versions
123+
# ----------------------------------------------------------------------
124+
build:
125+
name: Build (Node ${{ matrix.node-version }})
126+
runs-on: ubuntu-latest
127+
timeout-minutes: 30
128+
strategy:
129+
fail-fast: false
130+
matrix:
131+
node-version: [20.x, 22.x]
132+
steps:
133+
- name: Checkout code
134+
uses: actions/checkout@v4
135+
with:
136+
fetch-depth: 0
137+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
138+
139+
- name: Use Node.js ${{ matrix.node-version }}
140+
uses: actions/setup-node@v5
141+
with:
142+
node-version: ${{ matrix.node-version }}
143+
cache: 'npm'
144+
145+
- name: Install dependencies
146+
run: npm ci
147+
148+
- name: Build project
149+
run: npm run build --if-present
150+
151+
# ----------------------------------------------------------------------
152+
# Jest unit tests + coverage threshold + Codecov upload
153+
# ----------------------------------------------------------------------
154+
test:
155+
name: Jest tests & coverage
156+
runs-on: ubuntu-latest
157+
timeout-minutes: 30
158+
steps:
159+
- name: Checkout code
160+
uses: actions/checkout@v4
161+
with:
162+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
163+
164+
- name: Setup Node.js
165+
uses: actions/setup-node@v5
166+
with:
167+
node-version: '22'
168+
cache: 'npm'
169+
170+
- name: Install dependencies
171+
run: npm ci
172+
173+
# Coverage thresholds are enforced inside Jest (coverageThreshold in
174+
# your Jest config), so this step fails the job if coverage drops
175+
# below the configured minimums.
176+
- name: Run Jest with coverage
177+
run: npm test -- --coverage --ci
178+
179+
# Upload to Codecov for the PR-vs-base coverage diff + status check.
180+
# NOTE: secrets (CODECOV_TOKEN) are NOT available to pull_request runs
181+
# originating from forks. The threshold enforcement above still runs
182+
# on every PR; only the upload is skipped on forks. fail_ci_if_error
183+
# is false so a flaky/absent upload never blocks the PR.
184+
- name: Upload coverage to Codecov
185+
uses: codecov/codecov-action@v5
186+
with:
187+
token: ${{ secrets.CODECOV_TOKEN }}
188+
files: ./coverage/lcov.info
189+
fail_ci_if_error: false
190+
verbose: true
191+
192+
# ----------------------------------------------------------------------
193+
# Cypress end-to-end tests
194+
# ----------------------------------------------------------------------
195+
e2e:
196+
name: Cypress E2E
197+
runs-on: ubuntu-latest
198+
timeout-minutes: 30
199+
steps:
200+
- name: Checkout code
201+
uses: actions/checkout@v4
202+
with:
203+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
204+
205+
- name: Setup Node.js
206+
uses: actions/setup-node@v5
207+
with:
208+
node-version: '22'
209+
cache: 'npm'
210+
211+
- name: Run Cypress E2E tests
212+
uses: cypress-io/github-action@v6
213+
with:
214+
install-command: npm ci
215+
start: npm start
216+
wait-on: 'http://127.0.0.1:3000'
217+
wait-on-timeout: 120
218+
browser: chrome
219+
config: video=false
220+
221+
- name: Upload Cypress screenshots on failure
222+
if: failure()
223+
uses: actions/upload-artifact@v4
224+
with:
225+
name: cypress-screenshots
226+
path: cypress/screenshots
227+
if-no-files-found: ignore
228+
229+
# ----------------------------------------------------------------------
230+
# Dependency security audit
231+
# (Branch trigger fixed to `master` here — the standalone file's `main`
232+
# trigger no longer applies once this job replaces it.)
233+
# ----------------------------------------------------------------------
234+
security:
235+
name: Security audit
236+
runs-on: ubuntu-latest
237+
timeout-minutes: 30
238+
steps:
239+
- name: Checkout code
240+
uses: actions/checkout@v4
241+
with:
242+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
243+
244+
- name: Setup Node.js
245+
uses: actions/setup-node@v5
246+
with:
247+
node-version: '22'
248+
249+
- name: Run npm audit
250+
run: npm audit --omit=dev --audit-level=high

.github/workflows/linter.yml

Lines changed: 0 additions & 53 deletions
This file was deleted.

.github/workflows/node.js.yml

Lines changed: 0 additions & 42 deletions
This file was deleted.

.github/workflows/pr-cypress-e2e.yml

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)