Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions .github/workflows/update-dependencies.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Update dependencies

# Runs nightly and manually
on:
workflow_dispatch:
inputs:
group_name:
description: 'Package group to update'
type: choice
default: 'all'
options:
- electron
- eslint
- typescript
- mongosh
- all
required: true
schedule:
- cron: '0 0 * * *'

permissions:
contents: none # We use the github app token to push the changes

jobs:
update_dependencies_group:
name: Update ${{ matrix.group_name }} to latest
runs-on: ubuntu-latest
strategy:
matrix:
group_name:
# When adding new group, don't forget to update the
# `workflow_dispatch.inputs`
- electron
- eslint
- typescript
- mongosh
if: ${{ inputs.group_name == '' || inputs.group_name == 'all' || inputs.group_name == matrix.group_name }}
steps:
- name: Create Github App Token
uses: mongodb-js/devtools-shared/actions/setup-bot-token@main
id: app-token
with:
app-id: ${{ vars.DEVTOOLS_BOT_APP_ID }}
private-key: ${{ secrets.DEVTOOLS_BOT_PRIVATE_KEY }}

- uses: actions/checkout@v4
with:
# don't checkout a detatched HEAD
ref: ${{ github.head_ref || github.ref_name }}
token: ${{ steps.app-token.outputs.token }}

- uses: actions/setup-node@v4
with:
node-version: 22.15.1
cache: 'npm'

- name: Install [email protected]
run: |
npm install -g [email protected]
- name: Install dependencies
run: |
npm ci
- name: Run "update dependencies" script
run: npx compass-scripts update-dependencies preset-${{ matrix.group_name }}

- name: Create Pull Request
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # 7.0.5
with:
token: ${{ steps.app-token.outputs.token }}
commit-message: 'chore(deps): update ${{ matrix.group_name }} to latest'
branch: ci/update-${{ matrix.group_name }}
title: 'chore(deps): update ${{ matrix.group_name }} to latest'
labels: no-title-validation
author: '${{ steps.app-token.outputs.app-slug}}[bot] <${{ steps.app-token.outputs.app-email }}>'
body: |
<p>This PR is automatically generated and updates the versions of
the dependency group ${{ matrix.group_name }} to latest version.</p>
<p>If CI is green on this patch you should feel free to merge it at
your convenience.</p>
<p>If CI is red and you think that failures are related to the
version updates, you should raise an issue, so that it can be
manually resolved and we can continue to update the package group to
latest.</p>
55 changes: 0 additions & 55 deletions .github/workflows/update-electron.yaml

This file was deleted.

56 changes: 0 additions & 56 deletions .github/workflows/update-eslint.yaml

This file was deleted.

7 changes: 7 additions & 0 deletions scripts/update-dependencies-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ module.exports = {
'eslint-plugin-react-hooks',
],
typescript: ['typescript', 'ts-node'],
leafygreen: [
'@emotion/*',
'@leafygreen-ui/*',
'@lg-code/*',
'@mongodb-js/diagramming',
],
mongosh: ['@mongosh/*'],
// TODO(COMPASS-9443): Update update-* github actions to handle all groups as
// a matrix inside one action instead of having separate action for every
// group and add more groups following the ones in _dependabot
Expand Down
51 changes: 39 additions & 12 deletions scripts/update-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,15 @@ async function getVersion(depSpec) {
return [name, version.trim()];
}

const DEP_TYPES = [
'dependencies',
'devDependencies',
'peerDependencies',
'optionalDependencies',
];

function updateDependencies(packageJson, newVersions) {
for (const depType of [
'dependencies',
'devDependencies',
'peerDependencies',
'optionalDependencies',
]) {
for (const depType of DEP_TYPES) {
if (packageJson[depType]) {
for (const packageName of Object.keys(packageJson[depType])) {
if (packageJson[depType][packageName] && newVersions[packageName]) {
Expand Down Expand Up @@ -146,6 +148,36 @@ async function main() {
dependencies = args;
}

const monorepoRoot = await findMonorepoRoot();
const workspaces = [monorepoRoot].concat(
await Array.fromAsync(listAllPackages(), (workspace) => workspace.location)
);
const allMonorepoDependencies = Array.from(
new Set(
workspaces.flatMap((location) => {
try {
const deps = {};
const packageJson = require(path.join(location, 'package.json'));
for (const depType of DEP_TYPES) {
Object.assign(deps, packageJson[depType] ?? {});
}
return Object.keys(deps);
} catch {
return [];
}
})
)
);

dependencies = dependencies.flatMap((depToUpdate) => {
if (/\*/.test(depToUpdate)) {
return allMonorepoDependencies.filter((dep) => {
return dep.startsWith(depToUpdate.replace('*', ''));
});
}
return depToUpdate;
});

const newVersions = await withProgress(
`Collection version information for packages...`,
() => {
Expand All @@ -159,7 +191,7 @@ async function main() {

console.log();
console.log(
'Updating following packages:\n\n * %s\n',
'Updating following packages:\n\n * %s',
newVersions
.map((spec) => {
return spec.join('@');
Expand All @@ -171,11 +203,6 @@ async function main() {
const newVersionsObj = Object.fromEntries(newVersions);
let hasChanged;

const monorepoRoot = await findMonorepoRoot();
const workspaces = [monorepoRoot].concat(
await Array.fromAsync(listAllPackages(), (workspace) => workspace.location)
);

await withProgress('Updating package.json in workspaces', async () => {
for (const workspacePath of workspaces) {
await updatePackageJson(workspacePath, (packageJson) => {
Expand Down
Loading