Skip to content

Commit 6ae8f8d

Browse files
authored
ci: add Codecov (#3237)
* ci: add codecov reporting to PR test workflow * chore: point to the right lcov locations * chore: tighten up the coverage & reporting config - we're just using the default coverageReporters: https://jestjs.io/docs/configuration#coveragereporters-arraystring--string-options - the base config is using the preset, so we only need to declare reporters in one place - 'summary' is an invalid reporter - we want to always include the github-actions reporter in CI * chore: add missing jest dir * ci: let codecov find the coverage files with directory * style: nx format:write * chore: re-add missing coverageReporters these are different from the reporters * ci: add testing on main - nx run-many instead of nx affected to guarantee main tests always reflect the whole repo - differentiate between PRs and main coverage with tags * ci: add initial codecov config * ci: bump versions to latest and pin actions use latest ubuntu LTS version * ci: remove redundant config from https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request: > By default, a workflow only runs when a pull_request event's activity type is opened, synchronize, or reopened. * ci: try out codecov test analysis * ci: don't upload artifacts if the workflow was cancelled * chore: refactor jest config function & set consistent coverage dir * ci: use updated jest config * style: nx format:write
1 parent 38f5368 commit 6ae8f8d

File tree

5 files changed

+116
-41
lines changed

5 files changed

+116
-41
lines changed

.github/codecov.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
codecov:
2+
require_ci_to_pass: false
3+
4+
# use flags to differentiate coverage for:
5+
# - each package in the monorepo
6+
# - pull requests and the main branch
7+
#
8+
# use carryforward by default since we're testing with nx affected on everything
9+
# except the main branch.
10+
# https://docs.codecov.com/docs/carryforward-flags
11+
flag_management:
12+
default_rules:
13+
carryforward: true
14+
paths:
15+
- packages/*/
16+
individual_flags:
17+
# Workflow-specific flags (not package-based)
18+
- name: pull-request
19+
carryforward: true
20+
paths:
21+
- packages/
22+
- name: main
23+
carryforward: false
24+
paths:
25+
- packages/
26+
27+
# https://docs.codecov.com/docs/codecovyml-reference#coverage
28+
coverage:
29+
status:
30+
# https://docs.codecov.com/docs/commit-status#project-status
31+
project:
32+
default:
33+
target: 80%
34+
threshold: 1%
35+
# https://docs.codecov.com/docs/commit-status#patch-status
36+
patch:
37+
default:
38+
target: 80%
39+
threshold: 1%
40+
# https://docs.codecov.com/docs/commit-status#changes-status
41+
changes:
42+
default:
43+
informational: true
44+
45+
# https://docs.codecov.com/docs/pull-request-comments
46+
comment:
47+
# only comment if there are changes in coverage (positive or negative)
48+
require_changes: true

.github/workflows/test.yml

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ name: Test Suite
22

33
on:
44
pull_request:
5-
types: [opened, synchronize, reopened]
5+
push:
6+
branches:
7+
- main
68

79
env:
810
NODE_VERSION: '22.13.1'
@@ -18,32 +20,57 @@ permissions:
1820

1921
jobs:
2022
test:
21-
runs-on: ubuntu-22.04
23+
runs-on: ubuntu-24.04
2224
timeout-minutes: 30
2325
steps:
24-
- uses: actions/checkout@v4
26+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2527
with:
2628
fetch-depth: 0
2729
- uses: ./.github/actions/yarn
2830
- name: Fetch main branch
2931
run: git fetch origin main:main
32+
if: github.event_name == 'pull_request'
3033
- name: Ensure workflow is associated with a pull request
3134
uses: ./.github/actions/validate-pr-context
35+
if: github.event_name == 'pull_request'
3236
- name: Skip build from automated commit
3337
uses: ./.github/actions/skip-automated-commits
38+
if: github.event_name == 'pull_request'
3439
with:
3540
ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }}
3641
- name: Build All Packages
3742
run: yarn build
38-
- name: Run test suite on affected projects
39-
run: npx nx affected --target=test --parallel=4 --ci --coverage --runInBand
40-
env:
41-
JEST_JUNIT_OUTPUT_DIR: /tmp/test-results/junit
42-
JEST_JUNIT_ADD_FILE_ATTRIBUTE: 'true'
43+
- name: Run test suite
44+
run: |
45+
if [ "${{ github.event_name }}" == "pull_request" ]; then
46+
npx nx affected --target=test --parallel=4 --ci --coverage --runInBand
47+
else
48+
npx nx run-many --target=test --all --parallel=4 --ci --coverage --runInBand
49+
fi
4350
- name: Upload test results
44-
uses: actions/upload-artifact@v4
45-
if: always()
51+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
52+
if: ${{ !cancelled() }}
4653
with:
4754
name: test-results
48-
path: /tmp/test-results
55+
path: ./coverage
4956
retention-days: 30
57+
- name: Upload coverage reports to Codecov
58+
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.2.2
59+
if: ${{ !cancelled() }}
60+
with:
61+
token: ${{ secrets.CODECOV_TOKEN }}
62+
slug: Codecademy/gamut
63+
flags: ${{ github.event_name == 'pull_request' && 'pull-request' || 'main' }}
64+
fail_ci_if_error: false
65+
directory: ./coverage
66+
report_type: coverage
67+
- name: Upload test results to Codecov
68+
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.2.2
69+
if: ${{ !cancelled() }}
70+
with:
71+
token: ${{ secrets.CODECOV_TOKEN }}
72+
slug: Codecademy/gamut
73+
flags: ${{ github.event_name == 'pull_request' && 'pull-request' || 'main' }}
74+
fail_ci_if_error: false
75+
directory: ./coverage
76+
report_type: test_results

jest.config.base.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,43 @@
1-
const baseConfig = (packageName: string, overrides: any) => {
2-
const baseCoveragePathIgnorePatterns = [
3-
'<rootDir>/node_modules/',
4-
'<rootDir>/dist/',
5-
'/node_modules/',
6-
'/dist/',
7-
'packages/gamut-icons/dist/icons/',
8-
'packages/gamut-patterns/dist/patterns/',
9-
];
10-
const mergedCoveragePathIgnorePatterns = [
11-
...baseCoveragePathIgnorePatterns,
12-
...(overrides.coveragePathIgnorePatterns || []),
13-
];
1+
import type { Config } from 'jest';
2+
import path from 'node:path';
143

4+
const COVERAGE_PATH_IGNORE_PATTERNS = [
5+
'<rootDir>/node_modules/',
6+
'<rootDir>/dist/',
7+
'/node_modules/',
8+
'/dist/',
9+
'packages/gamut-icons/dist/icons/',
10+
'packages/gamut-patterns/dist/patterns/',
11+
];
12+
13+
const baseConfig = (packageName: string, overrides: Config): Config => {
14+
const outputDirectory = path.join(__dirname, `coverage/${packageName}`);
1515
return {
1616
displayName: packageName,
1717
preset: '../../jest.preset.js',
1818
clearMocks: true,
19-
coverageDirectory: process.env.CI
20-
? `/tmp/test-results/jest/${packageName}`
21-
: `../../coverage/packages/${packageName}`,
22-
reporters: process.env.CI ? ['github-actions', 'summary'] : ['default'],
19+
coverageDirectory: outputDirectory,
20+
coverageReporters: process.env.CI
21+
? ['clover', 'json', 'lcov', 'text']
22+
: ['html', 'text'],
23+
reporters: process.env.CI
24+
? [
25+
'default',
26+
'github-actions',
27+
['jest-junit', { addFileAttribute: true, outputDirectory }],
28+
]
29+
: ['default'],
2330
moduleNameMapper: {
2431
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|md)$':
2532
'<rootDir>/../../script/jest/fileMock',
2633
'\\.(css|scss)$': '<rootDir>/../../script/jest/styleMock',
2734
},
2835
testPathIgnorePatterns: ['node_modules', 'dist'],
2936
...overrides,
30-
coveragePathIgnorePatterns: mergedCoveragePathIgnorePatterns,
37+
coveragePathIgnorePatterns: [
38+
...COVERAGE_PATH_IGNORE_PATTERNS,
39+
...(overrides.coveragePathIgnorePatterns ?? []),
40+
],
3141
};
3242
};
3343

jest.preset.js

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
11
const nxPreset = require('@nx/jest/preset').default;
2-
const kebabCase = require('lodash/kebabCase');
32

4-
const targetProject = kebabCase(
5-
process.env.NX_TASK_TARGET_PROJECT || 'unknown'
6-
);
7-
8-
module.exports = {
9-
...nxPreset,
10-
coverageReporters: ['json', 'text', 'clover'],
11-
reporters: process.env.CI
12-
? ['default', ['jest-junit', { outputName: `${targetProject}-report.xml` }]]
13-
: ['default'],
14-
};
3+
module.exports = { ...nxPreset };

nx.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"inputs": [
4545
"default",
4646
"^production",
47+
"{workspaceRoot}/jest.config.base.ts",
4748
"{workspaceRoot}/jest.preset.js",
4849
"babelConfig",
4950
"ci"

0 commit comments

Comments
 (0)