Skip to content

Commit fd3cd69

Browse files
authored
chore(scripts): refactor update-electron to general purpose update-dependencies; replace usage in CI (#7071)
1 parent ab392de commit fd3cd69

File tree

7 files changed

+203
-147
lines changed

7 files changed

+203
-147
lines changed

.github/workflows/update-electron.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
run: npm ci
4141

4242
- name: Bump packages
43-
run: node scripts/update-electron.js
43+
run: npx compass-scripts update-dependencies preset-electron
4444

4545
- name: Create Pull Request
4646
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # 7.0.5

.github/workflows/update-eslint.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,7 @@ jobs:
3737
npm install -g [email protected]
3838
3939
- name: Bump eslint
40-
run: |
41-
npm i --save --workspace @mongodb-js/eslint-config-compass \
42-
eslint@8 \
43-
@typescript-eslint/eslint-plugin@latest \
44-
@typescript-eslint/parser@latest
40+
run: npx compass-scripts update-dependencies preset-eslint
4541

4642
- name: Create Pull Request
4743
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # 7.0.5

package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
"@babel/core": "^7.24.3",
4040
"@mongodb-js/monorepo-tools": "^1.1.16",
4141
"commander": "^11.0.0",
42-
"electron": "^36.5.0",
4342
"jsdom": "^24.1.3",
43+
"lodash": "^4.17.21",
4444
"make-fetch-happen": "^10.2.1",
4545
"pacote": "^11.3.5",
4646
"pkg-up": "^3.1.0",

scripts/update-dependencies-config.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
module.exports = {
3+
electron: [
4+
'@electron/remote',
5+
'@electron/rebuild',
6+
'browserslist',
7+
// NB: We're always trying to update to latest major, this usually implies
8+
// breaking changes, but those rarely affect us. If it becomes a problem, we
9+
// can always change this code to lock it to whatever major version of
10+
// electron compass is currently at
11+
'electron',
12+
'electron-to-chromium',
13+
'node-abi',
14+
],
15+
eslint: [
16+
'@typescript-eslint/eslint-plugin',
17+
'@typescript-eslint/parser',
18+
'eslint@8', // TODO: update to flat config, switch to eslint 9, remove the fixed version
19+
'eslint-plugin-jsx-a11y',
20+
'eslint-plugin-react',
21+
'eslint-plugin-react-hooks',
22+
],
23+
// TODO(COMPASS-9443): Update update-* github actions to handle all groups as
24+
// a matrix inside one action instead of having separate action for every
25+
// group and add more groups following the ones in _dependabot
26+
// mongosh: [],
27+
// 'devtools-shared-prod': [],
28+
};

scripts/update-dependencies.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
'use strict';
2+
const fs = require('fs');
3+
const path = require('path');
4+
const { isEqual, cloneDeep } = require('lodash');
5+
const {
6+
listAllPackages,
7+
runInDir,
8+
updatePackageJson,
9+
findMonorepoRoot,
10+
withProgress,
11+
} = require('@mongodb-js/monorepo-tools');
12+
13+
const UPDATE_CONFIGS = require('./update-dependencies-config');
14+
15+
async function hoistSharedDependencies(newVersions) {
16+
try {
17+
const root = await findMonorepoRoot();
18+
19+
await withProgress('Cleaning up existing node_modules', async () => {
20+
await runInDir("npx lerna exec 'rm -Rf node_modules'", root);
21+
await runInDir('rm -Rf node_modules', root);
22+
});
23+
24+
const packageJsonBkp = await withProgress(
25+
'Updating package-lock to apply package.json changes',
26+
async () => {
27+
await runInDir('npm i --package-lock-only --ignore-scripts', root);
28+
return await fs.promises.readFile(path.resolve(root, 'package.json'));
29+
}
30+
);
31+
32+
await withProgress(
33+
'Installing new dependencies at root to make sure they are hoisted',
34+
async () => {
35+
const versionsToInstall = newVersions
36+
.map((spec) => {
37+
return spec.join('@');
38+
})
39+
.join(' ');
40+
await runInDir(
41+
`npm i ${versionsToInstall} --package-lock-only --ignore-scripts`,
42+
root
43+
);
44+
}
45+
);
46+
47+
await withProgress(
48+
'Cleaning-up hoisted `dependencies` from root package.json',
49+
async () => {
50+
await fs.promises.writeFile(
51+
path.resolve(root, 'package.json'),
52+
packageJsonBkp
53+
);
54+
await runInDir('npm i', root);
55+
}
56+
);
57+
} catch (error) {
58+
console.error(`Error running command: ${error}`);
59+
}
60+
}
61+
62+
async function getVersion(depSpec) {
63+
const [name, versionSpec = 'latest'] = depSpec.split(
64+
/(?<!^)@/ // split by version, avoid splitting by optional namespace
65+
);
66+
const { stdout: output } = await runInDir(
67+
`npm view ${name}@${versionSpec} version --json`
68+
);
69+
const parsed = JSON.parse(output);
70+
const version = Array.isArray(parsed) ? parsed.pop() : parsed;
71+
return [name, version.trim()];
72+
}
73+
74+
async function main() {
75+
let dependencies;
76+
77+
const args = process.argv.slice(3);
78+
79+
if (args.length === 0) {
80+
throw new Error(
81+
'Missing dependencies list. Provide a list of dependencies to update or a preset name:\n\n npx compass-scripts update-dependencies <package[@version-range] [...packages] | preset>'
82+
);
83+
}
84+
85+
if (args[0].startsWith('preset-')) {
86+
const presetName = args[0].replace('preset-', '');
87+
dependencies = UPDATE_CONFIGS[args[0].replace('preset-', '')];
88+
if (!dependencies) {
89+
throw new Error(
90+
`Can not find update config for preset "${presetName}". Available presets: ${Object.keys(
91+
UPDATE_CONFIGS
92+
).join(', ')}`
93+
);
94+
}
95+
console.log();
96+
console.log('Running update for preset "%s" ...', presetName);
97+
console.log();
98+
} else {
99+
dependencies = args;
100+
}
101+
102+
const newVersions = await withProgress(
103+
`Collection version information for packages...`,
104+
() => {
105+
return Promise.all(
106+
dependencies.map((depSpec) => {
107+
return getVersion(depSpec);
108+
})
109+
);
110+
}
111+
);
112+
113+
console.log();
114+
console.log(
115+
'Updating following packages:\n\n * %s\n',
116+
newVersions
117+
.map((spec) => {
118+
return spec.join('@');
119+
})
120+
.join('\n * ')
121+
);
122+
console.log();
123+
124+
const newVersionsObj = Object.fromEntries(newVersions);
125+
let hasChanged;
126+
127+
await withProgress('Updating package.json in workspaces', async () => {
128+
for await (const props of listAllPackages()) {
129+
await updatePackageJson(props.location, (packageJson) => {
130+
const origPackageJson = cloneDeep(packageJson);
131+
for (const depType of [
132+
'dependencies',
133+
'devDependencies',
134+
'peerDependencies',
135+
'optionalDependencies',
136+
]) {
137+
if (packageJson[depType]) {
138+
for (const packageName of Object.keys(packageJson[depType])) {
139+
if (
140+
packageJson[depType][packageName] &&
141+
newVersionsObj[packageName]
142+
) {
143+
packageJson[depType][
144+
packageName
145+
] = `^${newVersionsObj[packageName]}`;
146+
}
147+
}
148+
}
149+
}
150+
hasChanged = hasChanged || !isEqual(origPackageJson, packageJson);
151+
return packageJson;
152+
});
153+
}
154+
});
155+
156+
if (!hasChanged) {
157+
console.log();
158+
console.log('Everything is up to date, exiting ...');
159+
return;
160+
}
161+
162+
await hoistSharedDependencies(newVersions);
163+
164+
console.log();
165+
console.log('Successfully updated dependencies');
166+
}
167+
168+
main();

scripts/update-electron.js

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

0 commit comments

Comments
 (0)