clients/.github/renovate.json5
Will Martin 69c937e592
[CL-954] Upgrade to Angular 21 (#19725)
* prune desktop packages

* Fix @napi-rs/cli version mismatch in desktop napi workspace

Aligns package.json declaration with the locked version (3.2.0) to
resolve npm workspace inconsistency that was blocking ng update.

* update Storybook to v10

* update Angular to v21

* override jest in ng builder

* Add jest-environment-jsdom as explicit dependency

Previously installed as a side effect of a jest@29 override; removing
that override caused it to disappear from node_modules.

* Add .claude/worktrees/ to .gitignore

* Restore @napi-rs/cli to 3.5.1 to match main

* Pin jest-environment-jsdom to 29.7.0 and add to renovate config

* Override jest-environment-jsdom to 29.7.0 in build-angular context

* Add isolatedModules to libs/subscription tsconfig.spec.json to fix Angular 21 module resolution

* Change moduleResolution to bundler for Angular 21 subpath export compatibility

* Add isolatedModules to Angular libs with old spec tsconfig pattern

* Disable emitDecoratorMetadata in spec tsconfigs with isolatedModules

* Fix HostListener event parameter types for Angular 21 compiler strictness

* Revert accidental change to access-selector spec

* Remove accidentally generated desktop package-lock.json

* Fix type-only imports/exports caught by Rolldown in Storybook v10/Vite v8

* fix vault-wrapper type error from Angular 21 stricter generic inference

ngComponentOutlet accepts Type<unknown>; annotate computed() explicitly
since VaultComponent is generic and VaultOrigComponent is not, preventing
TypeScript from inferring a compatible union constructor type.

* Fix kitchen-sink interaction tests for Storybook v10

Replace fire-and-forget navigateTo + synchronous getByRole with
navigateAndWaitFor<T>, which sets the hash and retries the ready
callback via waitFor. Storybook v10 starts play functions before
Angular's initial router navigation completes, so synchronous DOM
queries after navigation were failing intermittently.

* Provide ZoneJS change detection scheduler for Storybook stories

Angular 21 no longer sets up the ZoneJS change detection scheduler by
default in bootstrapApplication. Storybook's Angular renderer uses
bootstrapApplication internally and does not add provideZoneChangeDetection
automatically, so Default CD components relying on zone.js to trigger
re-renders after async operations were not updating before Chromatic
snapshots.

* Wait for dialog/side nav to render before Chromatic snapshot

After userEvent.click the dialog and side nav open asynchronously.
Without an explicit waitFor, Chromatic captures the snapshot before the
resulting UI state is present.

* Fix kitchen-sink waitFor: re-query side nav button, use querySelector for dialog

- openSideNav: re-query the toggle button inside waitFor to avoid reading
  a stale DOM reference after Angular re-renders the element post-click
- SimpleDialogOpen / VirtualScrollBlockingDialog: replace getByRole("dialog")
  with querySelector("cdk-dialog-container") to avoid testing-library's
  visibility check failing on a momentarily inaccessible overlay element

* Revert kitchen-sink stories to main

* Bump Angular, Storybook, and ng-select to latest patch versions

* Trigger pre-commit hooks on merge

* Regenerate package-lock.json with --force to fix npm ci sync
2026-05-18 10:55:47 -05:00

611 lines
18 KiB
Plaintext

{
$schema: "https://docs.renovatebot.com/renovate-schema.json",
extends: ["github>bitwarden/renovate-config"], // Extends our default configuration for pinned dependencies
enabledManagers: ["cargo", "github-actions", "npm", "custom.regex"],
customManagers: [
{
customType: "regex",
fileMatch: ["apps/desktop/desktop_native/cargo-tool-versions"],
matchStrings: ["(?<depName>[a-z][a-z0-9-]+)=(?<currentValue>[\\d.]+)"],
datasourceTemplate: "crate",
},
{
// Keep electronVersion in electron-builder.json in sync with the electron package.
customType: "regex",
fileMatch: ["apps/desktop/electron-builder\\.json$"],
matchStrings: ['"electronVersion":\\s*"(?<currentValue>[\\d.]+)"'],
depNameTemplate: "electron",
datasourceTemplate: "npm",
},
],
packageRules: [
// ==================== Repo-Wide Update Behavior Rules ====================
{
// Group all Github Action minor updates together to reduce PR noise.
groupName: "Minor github-actions updates",
matchManagers: ["github-actions"],
matchUpdateTypes: ["minor"],
},
{
// Enable support for Rust toolchain updates.
matchManagers: ["custom.regex"],
matchDepNames: ["rust"],
commitMessageTopic: "Rust",
},
{
// Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular.
matchPackageNames: ["typescript", "zone.js"],
matchUpdateTypes: ["major", "minor"],
description: "Determined by Angular",
enabled: false,
},
{
// Disable major updates for core Angular dependencies because they are managed through ng update
// when we decide to upgrade.
matchSourceUrls: [
"https://github.com/angular-eslint/angular-eslint",
"https://github.com/angular/angular-cli",
"https://github.com/angular/angular",
"https://github.com/angular/components",
"https://github.com/ng-select/ng-select",
],
matchUpdateTypes: ["major"],
description: "Manually updated using ng update",
enabled: false,
},
// ==================== Team Ownership Rules ====================
{
matchPackageNames: ["buffer", "bufferutil", "core-js", "process", "url", "util"],
description: "Admin Console owned dependencies",
commitMessagePrefix: "[deps] AC:",
reviewers: ["team:team-admin-console-dev"],
},
{
matchPackageNames: ["qrious"],
description: "Auth owned dependencies",
commitMessagePrefix: "[deps] Auth:",
reviewers: ["team:team-auth-dev"],
},
{
matchPackageNames: [
"@angular-eslint/schematics",
"@eslint/compat",
"@typescript-eslint/rule-tester",
"@typescript-eslint/utils",
"angular-eslint",
"eslint-config-prettier",
"eslint-import-resolver-typescript",
"eslint-plugin-import",
"eslint-plugin-jest",
"eslint-plugin-rxjs-angular",
"eslint-plugin-rxjs",
"eslint-plugin-storybook",
"eslint-plugin-tailwindcss",
"eslint",
"husky",
"lint-staged",
"typescript-eslint",
],
description: "Architecture owned dependencies",
commitMessagePrefix: "[deps] Architecture:",
reviewers: ["team:dept-architecture"],
},
{
matchPackageNames: [
"@emotion/css",
"@webcomponents/custom-elements",
"concurrently",
"cross-env",
"del",
"lit",
"@lit-labs/signals",
"patch-package",
"prettier",
"prettier-plugin-tailwindcss",
"rimraf",
"ssh-encoding",
"ssh-key",
"@storybook/web-components-vite",
"tabbable",
"tldts",
"wait-on",
],
description: "Autofill owned dependencies",
commitMessagePrefix: "[deps] Autofill:",
reviewers: ["team:team-autofill-dev"],
},
{
matchPackageNames: ["ed25519", "mockall", "pkcs8", "serial_test"],
description: "Autofill-Desktop owned dependencies",
commitMessagePrefix: "[deps] Desktop Native:",
reviewers: ["team:team-desktop-native-dev"],
},
{
matchPackageNames: ["braintree-web-drop-in"],
description: "Billing owned dependencies",
commitMessagePrefix: "[deps] Billing:",
reviewers: ["team:team-billing-dev"],
},
{
matchPackageNames: [
"@babel/core",
"@babel/preset-env",
"@bitwarden/sdk-internal",
"@bitwarden/commercial-sdk-internal",
"@bitwarden/desktop-napi",
"@electron/fuses",
"@electron/notarize",
"@electron/rebuild",
"@ngtools/webpack",
"@nx/devkit",
"@nx/eslint",
"@nx/jest",
"@nx/js",
"@nx/webpack",
"@types/chrome",
"@types/firefox-webext-browser",
"@types/glob",
"@types/lowdb",
"@types/jest",
"@types/node",
"@types/node-ipc",
"@yao-pkg/pkg",
"anyhow",
"arboard",
"ashpd",
"babel-loader",
"base64-loader",
"base64",
"bindgen",
"browserslist",
"byteorder",
"bytes",
"core-foundation",
"copy-webpack-plugin",
"css-loader",
"ctor",
"dirs",
"electron",
"electron-builder",
"electron-log",
"electron-reload",
"electron-store",
"electron-updater",
"embed_plist",
"futures",
"hex",
"homedir",
"html-loader",
"html-webpack-injector",
"html-webpack-plugin",
"interprocess",
"itertools",
"jest",
"jest-diff",
"jest-environment-jsdom",
"jest-junit",
"jest-mock-extended",
"jest-preset-angular",
"json5",
"keytar",
"libc",
"lowdb",
"mini-css-extract-plugin",
"napi",
"napi-build",
"napi-derive",
"node-ipc",
"nx",
"oo7",
"oslog",
"pin-project",
"pkg",
"postcss",
"postcss-loader",
"rand",
"rxjs",
"sass",
"sass-loader",
"scopeguard",
"secmem-proc",
"security-framework",
"security-framework-sys",
"semver",
"serde",
"serde_json",
"serde_with",
"simplelog",
"style-loader",
"sysinfo",
"thiserror",
"tokio",
"tokio-util",
"tracing",
"tracing-subscriber",
"ts-jest",
"ts-loader",
"ts-node",
"tsconfig-paths-webpack-plugin",
"type-fest",
"typenum",
"typescript",
"typescript-strict-plugin",
"uniffi",
"webpack",
"webpack-cli",
"webpack-dev-server",
"webpack-node-externals",
"widestring",
"windows",
"windows-core",
"windows-future",
"windows-registry",
"zbus",
"zbus_polkit",
"zeroizing-alloc",
],
description: "Platform owned dependencies",
commitMessagePrefix: "[deps] Platform:",
reviewers: ["team:team-platform-dev"],
},
{
matchUpdateTypes: ["lockFileMaintenance"],
description: "Platform owns lock file maintenance",
commitMessagePrefix: "[deps] Platform:",
reviewers: ["team:team-platform-dev"],
},
{
matchPackageNames: [
"@angular-devkit/build-angular",
"@angular/animations",
"@angular/cdk",
"@angular/cli",
"@angular/common",
"@angular/compiler-cli",
"@angular/compiler",
"@angular/core",
"@angular/forms",
"@angular/platform-browser-dynamic",
"@angular/platform-browser",
"@angular/platform",
"@angular/router",
"axe-playwright",
"@compodoc/compodoc",
"@ng-select/ng-select",
"@storybook/addon-a11y",
"@storybook/addon-designs",
"@storybook/addon-docs",
"@storybook/addon-links",
"@storybook/test-runner",
"@storybook/addon-themes",
"@storybook/angular",
"@types/react",
"autoprefixer",
"bootstrap",
"chromatic",
"fantasticon",
"ngx-toastr",
"path-browserify",
"react",
"react-dom",
"remark-gfm",
"storybook",
"svgo",
"tailwindcss",
"vite-tsconfig-paths",
"zone.js",
"@tailwindcss/container-queries",
],
description: "UI Foundation owned dependencies",
commitMessagePrefix: "[deps] UI Foundation:",
reviewers: ["team:team-ui-foundation"],
},
{
matchPackageNames: [
"@microsoft/signalr-protocol-msgpack",
"@microsoft/signalr",
"@types/jsdom",
"@types/papaparse",
"@types/zxcvbn",
"aes-gcm",
"async-trait",
"clap",
"jsdom",
"jszip",
"oidc-client-ts",
"papaparse",
"utf-8-validate",
"verifysign",
"zxcvbn",
],
description: "Tools owned dependencies",
commitMessagePrefix: "[deps] Tools:",
reviewers: ["team:team-tools-dev"],
},
{
matchPackageNames: [
"@koa/multer",
"@koa/router",
"@types/inquirer",
"@types/koa",
"@types/koa__multer",
"@types/koa-bodyparser",
"@types/koa-json",
"@types/lunr",
"@types/node-fetch",
"@types/proper-lockfile",
"@types/retry",
"chalk",
"commander",
"form-data",
"https-proxy-agent",
"inquirer",
"koa",
"koa-bodyparser",
"koa-json",
"lunr",
"multer",
"node-fetch",
"open",
"proper-lockfile",
"qrcode-parser",
],
description: "Vault owned dependencies",
commitMessagePrefix: "[deps] Vault:",
reviewers: ["team:team-vault-dev"],
},
{
matchPackageNames: [
"@types/node-forge",
"aes",
"big-integer",
"cbc",
"chacha20poly1305",
"linux-keyutils",
"memsec",
"node-forge",
"rsa",
"russh-cryptovec",
"sha2",
],
description: "Key Management owned dependencies",
commitMessagePrefix: "[deps] KM:",
reviewers: ["team:team-key-management-dev"],
},
{
matchPackageNames: ["chart.js", "chartjs-adapter-date-fns"],
description: "DIRT owned dependencies",
commitMessagePrefix: "[deps] DIRT:",
reviewers: ["team:team-data-insights-and-reporting-dev"],
},
// ==================== Grouping Rules ====================
// These come after any specific team assignment rules to ensure
// that grouping is not overridden by subsequent rule definitions.
{
matchPackageNames: [
"@angular-eslint/schematics",
"@eslint/compat",
"@typescript-eslint/rule-tester",
"@typescript-eslint/utils",
"angular-eslint",
"eslint-config-prettier",
"eslint-import-resolver-typescript",
"eslint-plugin-import",
"eslint-plugin-jest",
"eslint-plugin-rxjs-angular",
"eslint-plugin-rxjs",
"eslint-plugin-storybook",
"eslint-plugin-tailwindcss",
"eslint",
"husky",
"lint-staged",
"typescript-eslint",
],
groupName: "Minor and patch linting updates",
matchUpdateTypes: ["minor", "patch"],
},
{
// We need to group all napi-related packages together to avoid build errors caused by version incompatibilities.
groupName: "napi",
matchPackageNames: ["napi", "napi-build", "napi-derive"],
},
{
// We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities.
groupName: "macOS/iOS bindings",
matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"],
},
{
// We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities.
groupName: "zbus",
matchPackageNames: ["zbus", "zbus_polkit"],
},
{
// We need to group all windows-related packages together to avoid build errors caused by version incompatibilities.
groupName: "windows",
matchPackageNames: ["windows", "windows-core", "windows-future", "windows-registry"],
},
{
// We need to group all tokio-related packages together to avoid build errors caused by version incompatibilities.
groupName: "tokio",
matchPackageNames: ["bytes", "tokio", "tokio-util"],
},
{
// We group all webpack build-related minor and patch updates together to reduce PR noise.
// We include patch updates here because we want PRs for webpack patch updates and it's in this group.
matchPackageNames: [
"@babel/core",
"@babel/preset-env",
"babel-loader",
"base64-loader",
"browserslist",
"copy-webpack-plugin",
"css-loader",
"html-loader",
"html-webpack-injector",
"html-webpack-plugin",
"mini-css-extract-plugin",
"postcss-loader",
"postcss",
"sass-loader",
"sass",
"style-loader",
"ts-loader",
"tsconfig-paths-webpack-plugin",
"webpack-cli",
"webpack-dev-server",
"webpack-node-externals",
"webpack",
],
description: "webpack-related build dependencies",
groupName: "Minor and patch webpack updates",
matchUpdateTypes: ["minor", "patch"],
},
{
// We need to update several Jest-related packages together, for version compatibility.
groupName: "jest",
matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"],
},
{
// Some electron packages are version coupled
groupName: "electron",
matchPackageNames: [
"@electron/fuses",
"@electron/rebuild",
"electron",
"electron-builder",
"electron-updater",
],
},
// ==================== Dashboard Rules ====================
{
// For the packages below, we have decided we will only be creating PRs
// for major updates, and sending minor (as well as patch) to the dashboard.
// This rule comes AFTER grouping rules so that groups are respected while still
// sending minor/patch updates to the dependency dashboard for approval.
matchPackageNames: [
"@types/jest",
"anyhow",
"arboard",
"ashpd",
"babel-loader",
"base64",
"base64-loader",
"bindgen",
"byteorder",
"bytes",
"core-foundation",
"copy-webpack-plugin",
"css-loader",
"ctor",
"dirs",
"electron-builder",
"electron-log",
"electron-reload",
"electron-store",
"electron-updater",
"embed_plist",
"futures",
"hex",
"homedir",
"html-loader",
"html-webpack-injector",
"html-webpack-plugin",
"interprocess",
"jest",
"jest-diff",
"jest-environment-jsdom",
"jest-junit",
"jest-mock-extended",
"jest-preset-angular",
"json5",
"keytar",
"libc",
"lowdb",
"mini-css-extract-plugin",
"napi",
"napi-build",
"napi-derive",
"node-ipc",
"nx",
"oo7",
"oslog",
"pin-project",
"pkg",
"postcss",
"postcss-loader",
"rand",
"sass",
"sass-loader",
"scopeguard",
"secmem-proc",
"security-framework",
"security-framework-sys",
"semver",
"serde",
"serde_json",
"simplelog",
"style-loader",
"sysinfo",
"thiserror",
"tokio",
"tokio-util",
"tracing",
"tracing-subscriber",
"ts-jest",
"ts-loader",
"ts-node",
"tsconfig-paths-webpack-plugin",
"type-fest",
"typenum",
"typescript-strict-plugin",
"uniffi",
"webpack-cli",
"webpack-dev-server",
"webpack-node-externals",
"widestring",
"windows",
"windows-core",
"windows-future",
"windows-registry",
"zbus",
"zbus_polkit",
"zeroizing-alloc",
],
matchUpdateTypes: ["minor", "patch"],
dependencyDashboardApproval: true,
},
{
// By default, we send patch updates to the Dependency Dashboard and do not generate a PR.
// We want to generate PRs for a select number of dependencies to ensure we stay up to date on these.
matchPackageNames: ["browserslist", "electron", "rxjs", "typescript", "webpack", "zone.js"],
matchUpdateTypes: ["patch"],
dependencyDashboardApproval: false,
},
// ==================== Special Version Constraints ====================
{
// Any versions of lowdb above 1.0.0 are not compatible with CommonJS.
matchPackageNames: ["lowdb"],
allowedVersions: "1.0.0",
description: "Higher versions of lowdb are not compatible with CommonJS",
},
{
// Pin types as well since we are not upgrading past v1 (and also v2+ does not need separate types).
matchPackageNames: ["@types/lowdb"],
allowedVersions: "< 2.0.0",
description: "Higher versions of lowdb do not need separate types",
},
],
ignoreDeps: [
"@types/koa-bodyparser",
"bootstrap",
"node-ipc",
"@bitwarden/sdk-internal",
"@bitwarden/commercial-sdk-internal",
"bitwarden-russh",
],
}