Skip to content

Commit 5e19b94

Browse files
authored
Merge pull request #36 from privacybydesign/chore/fix-dependabot-client-vulns
Resolve all 30 Dependabot alerts (client): webpack 5 + jest 30 modernization
2 parents d57ecc3 + 40f36a2 commit 5e19b94

35 files changed

Lines changed: 11855 additions & 17369 deletions

.github/workflows/delivery.yml

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,76 @@ permissions:
1919
security-events: write
2020

2121
jobs:
22+
test:
23+
runs-on: ubuntu-latest
24+
defaults:
25+
run:
26+
working-directory: client
27+
steps:
28+
- uses: actions/checkout@v6
29+
- uses: actions/setup-node@v6
30+
with:
31+
node-version: lts/*
32+
cache: npm
33+
cache-dependency-path: client/package-lock.json
34+
- run: npm ci
35+
- run: npm test
36+
- run: npm run build
37+
- uses: actions/upload-artifact@v7
38+
with:
39+
name: client-dist
40+
path: client/dist/
41+
retention-days: 1
42+
43+
e2e:
44+
needs: test
45+
runs-on: ubuntu-latest
46+
defaults:
47+
run:
48+
working-directory: client
49+
steps:
50+
- uses: actions/checkout@v6
51+
- uses: actions/setup-node@v6
52+
with:
53+
node-version: lts/*
54+
cache: npm
55+
cache-dependency-path: client/package-lock.json
56+
- run: npm ci
57+
- uses: actions/download-artifact@v8
58+
with:
59+
name: client-dist
60+
path: client/dist/
61+
- run: npx playwright install --with-deps chromium
62+
- run: npm run test:e2e
63+
2264
publish-docker-image:
65+
needs: [e2e]
2366
runs-on: ubuntu-latest
2467
steps:
2568
- name: Checkout
26-
uses: actions/checkout@v4
69+
uses: actions/checkout@v6
2770

2871
- name: Docker meta
2972
id: meta
30-
uses: docker/metadata-action@v5
73+
uses: docker/metadata-action@v6
3174
with:
3275
images: ghcr.io/${{ github.repository }}
3376
tags: |
3477
type=semver,pattern={{major}}.{{minor}}.{{patch}}
3578
type=raw,value=edge
3679
3780
- name: Set up Docker Buildx
38-
uses: docker/setup-buildx-action@v3
81+
uses: docker/setup-buildx-action@v4
3982

4083
- name: Login to GitHub Container Registry
41-
uses: docker/login-action@v3
84+
uses: docker/login-action@v4
4285
with:
4386
registry: ghcr.io
4487
username: ${{ github.actor }}
4588
password: ${{ secrets.GITHUB_TOKEN }}
4689

4790
- name: Build container and export to local Docker
48-
uses: docker/build-push-action@v5
91+
uses: docker/build-push-action@v7
4992
with:
5093
context: .
5194
file: Dockerfile.prod
@@ -65,13 +108,13 @@ jobs:
65108
output-format: sarif
66109

67110
- name: Upload Anchore scan SARIF report
68-
uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
111+
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
69112
if: ${{ !cancelled() }}
70113
with:
71114
sarif_file: ${{ steps.scan.outputs.sarif }}
72115

73116
- name: Push image to GitHub Container Registry
74-
uses: docker/build-push-action@v5
117+
uses: docker/build-push-action@v7
75118
if: ${{ github.event_name != 'schedule' }}
76119
with:
77120
file: Dockerfile.prod

client/.stylelintrc

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

client/babel.config.js

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1-
module.exports = {
2-
babelrc: false,
3-
presets: [
4-
[
5-
'@babel/preset-env',
6-
{
7-
useBuiltIns: 'usage',
8-
corejs: 3,
9-
modules: false
10-
}
1+
module.exports = api => {
2+
// Jest needs CommonJS modules; webpack builds keep ES modules for tree-shaking.
3+
const isTest = api.env('test');
4+
5+
return {
6+
babelrc: false,
7+
// Detect CJS files (no import/export) as scripts so useBuiltIns:'usage' adds
8+
// require() polyfills instead of import statements. Without this, babel injects
9+
// ESM import polyfills into already-compiled CJS packages (@amsterdam, @privacybydesign),
10+
// causing webpack 5 to treat them as ES modules where `exports` is undefined.
11+
sourceType: 'unambiguous',
12+
presets: [
13+
[
14+
'@babel/preset-env',
15+
{
16+
useBuiltIns: 'usage',
17+
corejs: 3,
18+
modules: isTest ? 'commonjs' : false
19+
}
20+
],
21+
'@babel/preset-typescript',
22+
'@babel/preset-react'
1123
],
12-
'@babel/preset-typescript',
13-
'@babel/preset-react'
14-
],
15-
plugins: [
16-
'@babel/plugin-transform-runtime',
17-
'@babel/plugin-transform-modules-commonjs',
18-
'@babel/proposal-class-properties',
19-
'@babel/proposal-object-rest-spread',
20-
'@babel/plugin-proposal-optional-chaining',
21-
'@babel/plugin-transform-reserved-words',
22-
'babel-plugin-styled-components',
23-
'react-hot-loader/babel'
24-
]
24+
plugins: [
25+
'@babel/plugin-transform-runtime',
26+
'@babel/plugin-proposal-class-properties',
27+
'@babel/plugin-proposal-object-rest-spread',
28+
'@babel/plugin-proposal-optional-chaining',
29+
'@babel/plugin-transform-reserved-words',
30+
['babel-plugin-styled-components', { pure: true }]
31+
]
32+
};
2533
};

client/e2e/smoke.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test('homepage loads without JS errors', async ({ page }) => {
4+
const errors: string[] = [];
5+
page.on('pageerror', err => errors.push(err.message));
6+
7+
await page.goto('/');
8+
await page.waitForLoadState('networkidle');
9+
10+
expect(errors, errors.join('\n')).toHaveLength(0);
11+
await expect(page.locator('h1').first()).toBeVisible();
12+
});

client/jest.config.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
/* eslint-disable @typescript-eslint/no-var-requires */
2-
const { pathsToModuleNameMapper } = require('ts-jest/utils');
3-
const { compilerOptions } = require('./tsconfig.json');
4-
51
module.exports = {
62
collectCoverageFrom: ['src/**/*.{js,ts,tsx}'],
73
coverageDirectory: '<rootDir>/coverage',
4+
testEnvironment: 'jsdom',
85
moduleNameMapper: {
96
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
107
'<rootDir>/src/test/fileMock.ts',
118
'\\.(css)$': '<rootDir>/src/test/styleMock.ts',
12-
...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/src/' })
9+
'@privacybydesign/yivi-css': '<rootDir>/src/test/styleMock.ts',
10+
'^@config/(.*)$': '<rootDir>/src/config/$1',
11+
'^@app/(.*)$': '<rootDir>/src/app/$1',
12+
'^@components/(.*)$': '<rootDir>/src/components/$1',
13+
'^@pages/(.*)$': '<rootDir>/src/pages/$1',
14+
'^@hooks/(.*)$': '<rootDir>/src/hooks/$1',
15+
'^@services/(.*)$': '<rootDir>/src/services/$1',
16+
'^@test/(.*)$': '<rootDir>/src/test/$1'
1317
},
1418
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
15-
testRegex: '.spec.(js|ts|tsx)$',
19+
testRegex: 'src/.+\\.spec\\.(js|ts|tsx)$',
1620
transform: {
17-
'^.+\\.(js|jsx|mjs)$': 'babel-jest',
18-
'^.+\\.tsx?$': 'ts-jest'
21+
'^.+\\.(js|jsx|mjs|ts|tsx)$': 'babel-jest'
1922
}
2023
};

0 commit comments

Comments
 (0)