Skip to content

Commit 34b9036

Browse files
committed
add react_next workflow in circle ci
1 parent c57f764 commit 34b9036

File tree

2 files changed

+165
-19
lines changed

2 files changed

+165
-19
lines changed

.circleci/config.yml

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ parameters:
55
description: Whether to force browserstack usage. We have limited resources on browserstack so the pipeline might decide to skip browserstack if this parameter isn't set to true.
66
type: boolean
77
default: false
8-
react-dist-tag:
9-
description: The dist-tag of react to be used
8+
react-version:
9+
description: The version of react to be used
1010
type: string
1111
default: stable
1212
workflow:
@@ -20,10 +20,10 @@ parameters:
2020

2121
default-job: &default-job
2222
parameters:
23-
react-dist-tag:
24-
description: The dist-tag of react to be used
23+
react-version:
24+
description: The version of react to be used
2525
type: string
26-
default: << pipeline.parameters.react-dist-tag >>
26+
default: << pipeline.parameters.react-version >>
2727
e2e-base-url:
2828
description: The base url for running end-to-end test
2929
type: string
@@ -33,7 +33,7 @@ default-job: &default-job
3333
PLAYWRIGHT_BROWSERS_PATH: /tmp/pw-browsers
3434
# expose it globally otherwise we have to thread it from each job to the install command
3535
BROWSERSTACK_FORCE: << pipeline.parameters.browserstack-force >>
36-
REACT_DIST_TAG: << parameters.react-dist-tag >>
36+
REACT_VERSION: << parameters.react-version >>
3737
working_directory: /tmp/mui
3838
docker:
3939
- image: cimg/node:18.20
@@ -59,6 +59,13 @@ commands:
5959
description: 'Set to true if you intend to any browser (for example with playwright).'
6060

6161
steps:
62+
- run:
63+
name: Resolve React version
64+
command: |
65+
node scripts/useReactVersion.mjs
66+
# log a patch for maintainers who want to check out this change
67+
git --no-pager diff HEAD
68+
6269
- when:
6370
condition: << parameters.browsers >>
6471
steps:
@@ -112,18 +119,23 @@ jobs:
112119
steps:
113120
- checkout
114121
- install_js
115-
- run:
116-
name: Should not have any git not staged
117-
command: git add -A && git diff --exit-code --staged
118-
- run:
119-
name: Check for duplicated packages
120-
command: |
121-
if [[ $(git diff --name-status next | grep pnpm-lock) == "" ]];
122-
then
123-
echo "No changes to dependencies detected. Skipping..."
124-
else
125-
pnpm dedupe --check
126-
fi
122+
- when:
123+
# Install can be "dirty" when running with non-default versions of React
124+
condition:
125+
equal: [<< parameters.react-version >>, stable]
126+
steps:
127+
- run:
128+
name: Should not have any git not staged
129+
command: git add -A && git diff --exit-code --staged
130+
- run:
131+
name: Check for duplicated packages
132+
command: |
133+
if [[ $(git diff --name-status next | grep pnpm-lock) == "" ]];
134+
then
135+
echo "No changes to dependencies detected. Skipping..."
136+
else
137+
pnpm dedupe --check
138+
fi
127139
test_unit:
128140
<<: *default-job
129141
steps:
@@ -147,7 +159,7 @@ jobs:
147159
command: |
148160
curl -Os https://uploader.codecov.io/latest/linux/codecov
149161
chmod +x codecov
150-
./codecov -t ${CODECOV_TOKEN} -Z -F "$REACT_DIST_TAG-jsdom"
162+
./codecov -t ${CODECOV_TOKEN} -Z -F "$REACT_VERSION-jsdom"
151163
test_lint:
152164
<<: *default-job
153165
steps:
@@ -337,3 +349,25 @@ workflows:
337349
- test_e2e_website:
338350
requires:
339351
- checkout
352+
353+
react-next:
354+
# triggers:
355+
# - schedule:
356+
# cron: '0 0 * * *'
357+
# filters:
358+
# branches:
359+
# only:
360+
# - master
361+
jobs:
362+
- test_unit:
363+
<<: *default-context
364+
react-version: next
365+
- test_browser:
366+
<<: *default-context
367+
react-version: next
368+
- test_regressions:
369+
<<: *default-context
370+
react-version: next
371+
- test_e2e:
372+
<<: *default-context
373+
react-version: next

scripts/useReactVersion.mjs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* eslint-disable no-console */
2+
/**
3+
* Given the dist tag fetch the corresponding
4+
* version and make sure this version is used throughout the repository.
5+
*
6+
* If you work on this file:
7+
* WARNING: This script can only use built-in modules since it has to run before
8+
* `pnpm install`
9+
*/
10+
import childProcess from 'child_process';
11+
import fs from 'fs';
12+
import os from 'os';
13+
import path from 'path';
14+
import { promisify } from 'util';
15+
import { getWorkspaceRoot } from './utils.mjs';
16+
17+
// TODO: reuse the `useReactVersion.mjs` from the monorepo
18+
19+
const exec = promisify(childProcess.exec);
20+
21+
// packages published from the react monorepo using the same version
22+
const reactPackageNames = ['react', 'react-dom', 'react-is', 'react-test-renderer', 'scheduler'];
23+
const devDependenciesPackageNames = ['@mnajdova/enzyme-adapter-react-18', '@testing-library/react'];
24+
25+
// if we need to support more versions we will need to add new mapping here
26+
const additionalVersionsMappings = {
27+
17: {
28+
'@mnajdova/enzyme-adapter-react-18': 'npm:@eps1lon/enzyme-adapter-react-17',
29+
'@testing-library/react': '^12.1.0',
30+
},
31+
19: {},
32+
};
33+
34+
async function main(version) {
35+
if (typeof version !== 'string') {
36+
throw new TypeError(`expected version: string but got '${version}'`);
37+
}
38+
39+
if (version === 'stable') {
40+
console.log('Nothing to do with stable');
41+
return;
42+
}
43+
44+
const packageJsonPath = path.resolve(getWorkspaceRoot(), 'package.json');
45+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, { encoding: 'utf8' }));
46+
47+
// the version is something in format: "17.0.0"
48+
let majorVersion = null;
49+
50+
if (version.startsWith('^') || version.startsWith('~') || !Number.isNaN(version.charAt(0))) {
51+
majorVersion = version.replace('^', '').replace('~', '').split('.')[0];
52+
}
53+
54+
await Promise.all(
55+
reactPackageNames.map(async (reactPackageName) => {
56+
const { stdout: versions } = await exec(`npm dist-tag ls ${reactPackageName} ${version}`);
57+
const tagMapping = versions.split('\n').find((mapping) => {
58+
return mapping.startsWith(`${version}: `);
59+
});
60+
61+
let packageVersion = null;
62+
63+
if (tagMapping === undefined) {
64+
// Some specific version is being requested
65+
if (majorVersion) {
66+
packageVersion = version;
67+
if (reactPackageName === 'scheduler') {
68+
// get the scheduler version from the react-dom's dependencies entry
69+
const { stdout: reactDOMDependenciesString } = await exec(
70+
`npm view --json react-dom@${version} dependencies`,
71+
);
72+
packageVersion = JSON.parse(reactDOMDependenciesString).scheduler;
73+
}
74+
} else {
75+
throw new Error(`Could not find '${version}' in "${versions}"`);
76+
}
77+
} else {
78+
packageVersion = tagMapping.replace(`${version}: `, '');
79+
}
80+
81+
packageJson.resolutions[reactPackageName] = packageVersion;
82+
}),
83+
);
84+
85+
// At this moment all dist tags reference React 18 version, so we don't need
86+
// to update these dependencies unless an older version is used, or when the
87+
// next/experimental dist tag reference to a future version of React
88+
// packageJson.devDependencies['@mnajdova/enzyme-adapter-react-18'] =
89+
// 'npm:@mnajdova/enzyme-adapter-react-next';
90+
// packageJson.devDependencies['@testing-library/react'] = 'alpha';
91+
92+
if (majorVersion && additionalVersionsMappings[majorVersion]) {
93+
devDependenciesPackageNames.forEach((packageName) => {
94+
if (!additionalVersionsMappings[majorVersion][packageName]) {
95+
throw new Error(
96+
`Version ${majorVersion} does not have version defined for the ${packageName}`,
97+
);
98+
}
99+
packageJson.devDependencies[packageName] =
100+
additionalVersionsMappings[majorVersion][packageName];
101+
});
102+
}
103+
104+
// add newline for clean diff
105+
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}${os.EOL}`);
106+
}
107+
108+
const [version = process.env.REACT_VERSION] = process.argv.slice(2);
109+
main(version).catch((error) => {
110+
console.error(error);
111+
process.exit(1);
112+
});

0 commit comments

Comments
 (0)