Skip to content

Commit e01e4db

Browse files
committed
Add CI job to check npm dependencies
Checks that if one React package depends on another, the current version satisfies the given dependency range. That way we don't forget to bump dependencies when we release a new version.
1 parent ad60746 commit e01e4db

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

.circleci/config.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,17 @@ jobs:
210210
- *restore_node_modules
211211
- run: yarn lint-build
212212

213+
yarn_check_release_dependencies:
214+
docker: *docker
215+
environment: *environment
216+
steps:
217+
- checkout
218+
- attach_workspace: *attach_workspace
219+
- run: yarn workspaces info | head -n -1 > workspace_info.txt
220+
- *restore_node_modules
221+
- run: yarn check-release-dependencies
222+
223+
213224
check_error_codes:
214225
docker: *docker
215226
environment: *environment
@@ -427,6 +438,9 @@ workflows:
427438
- yarn_lint_build:
428439
requires:
429440
- yarn_build_combined
441+
- yarn_check_release_dependencies:
442+
requires:
443+
- yarn_build_combined
430444
- check_error_codes:
431445
requires:
432446
- yarn_build_combined

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@
145145
"publish-prereleases": "node ./scripts/release/publish-using-ci-workflow.js",
146146
"download-build": "node ./scripts/release/download-experimental-build.js",
147147
"download-build-for-head": "node ./scripts/release/download-experimental-build.js --commit=$(git rev-parse HEAD)",
148-
"download-build-in-codesandbox-ci": "cd scripts/release && yarn install && cd ../../ && yarn download-build-for-head || yarn build-combined --type=node react/index react-dom scheduler"
148+
"download-build-in-codesandbox-ci": "cd scripts/release && yarn install && cd ../../ && yarn download-build-for-head || yarn build-combined --type=node react/index react-dom scheduler",
149+
"check-release-dependencies": "node ./scripts/release/check-release-dependencies"
149150
},
150151
"resolutions": {
151152
"react-is": "npm:react-is"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
/* eslint-disable no-for-of-loops/no-for-of-loops */
4+
5+
const fs = require('fs');
6+
const semver = require('semver');
7+
8+
const {stablePackages} = require('../../ReactVersions');
9+
10+
function checkDependency(packageName, depName, version, range) {
11+
if (!semver.satisfies(version, range)) {
12+
throw new Error(
13+
`${packageName} has an invalid dependency on ${depName}: ${range}` +
14+
'\n\n' +
15+
'Actual version is: ' +
16+
version
17+
);
18+
}
19+
}
20+
21+
function main() {
22+
if (!fs.existsSync('./build/oss-stable-semver')) {
23+
throw new Error('No build artifacts found');
24+
}
25+
26+
const packages = new Map();
27+
for (const packageName in stablePackages) {
28+
if (!fs.existsSync(`build/oss-stable-semver/${packageName}/package.json`)) {
29+
throw new Error(`${packageName}`);
30+
} else {
31+
const info = JSON.parse(
32+
fs.readFileSync(`build/oss-stable-semver/${packageName}/package.json`)
33+
);
34+
packages.set(info.name, info);
35+
}
36+
}
37+
38+
for (const [packageName, info] of packages) {
39+
if (info.dependencies) {
40+
for (const [depName, depRange] of Object.entries(info.dependencies)) {
41+
if (packages.has(depName)) {
42+
const releaseVersion = packages.get(depName).version;
43+
checkDependency(packageName, depName, releaseVersion, depRange);
44+
}
45+
}
46+
}
47+
48+
if (info.peerDependencies) {
49+
for (const [depName, depRange] of Object.entries(info.peerDependencies)) {
50+
if (packages.has(depName)) {
51+
const releaseVersion = packages.get(depName).version;
52+
checkDependency(packageName, depName, releaseVersion, depRange);
53+
}
54+
}
55+
}
56+
}
57+
}
58+
59+
function checkDependency(packageName, depName, version, range) {
60+
if (!semver.satisfies(version, range)) {
61+
throw new Error(
62+
`${packageName} has an invalid dependency on ${depName}: ${range}` +
63+
'\n\n' +
64+
'Actual version is: ' +
65+
version
66+
);
67+
}
68+
}
69+
70+
main();

0 commit comments

Comments
 (0)