mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-21 15:36:50 -05:00
[AI] Add Yarn constraints to enforce consistent dependency versions (#7229)
* [AI] Add yarn constraints to enforce consistent dependency versions Adds a `yarn.config.cjs` that uses Yarn 4's built-in constraints feature to detect when the same dependency is declared with different version ranges across workspaces. Workspace protocol references and peerDependencies are excluded from the check. Also adds a `yarn constraints` convenience script and the `@yarnpkg/types` dev dependency for type-checked constraint authoring. https://claude.ai/code/session_01B1xRjZXn6b18anZjo8cbqb * Add release notes for PR #7229 * Add constraints job to GitHub Actions workflow * Fix constraints --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
dfd6e468a6
commit
c4ee71409e
10
.github/workflows/check.yml
vendored
10
.github/workflows/check.yml
vendored
@@ -12,6 +12,16 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
jobs:
|
||||
constraints:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Set up environment
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
download-translations: 'false'
|
||||
- name: Check dependency version consistency
|
||||
run: yarn constraints
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"lint": "oxfmt --check . && oxlint --type-aware --quiet",
|
||||
"lint:fix": "oxfmt . && oxlint --fix --type-aware --quiet",
|
||||
"install:server": "yarn workspaces focus @actual-app/sync-server --production",
|
||||
"constraints": "yarn constraints",
|
||||
"typecheck": "tsgo -p tsconfig.root.json --noEmit && lage typecheck",
|
||||
"jq": "./node_modules/node-jq/bin/jq",
|
||||
"prepare": "husky"
|
||||
@@ -66,6 +67,7 @@
|
||||
"@types/node": "^22.19.10",
|
||||
"@types/prompts": "^2.4.9",
|
||||
"@typescript/native-preview": "^7.0.0-dev.20260309.1",
|
||||
"@yarnpkg/types": "^4.0.1",
|
||||
"baseline-browser-mapping": "^2.9.19",
|
||||
"cross-env": "^10.1.0",
|
||||
"eslint": "^9.39.2",
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
"@r74tech/docusaurus-plugin-panzoom": "^2.4.0",
|
||||
"clsx": "^2.1.1",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4"
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.9.2",
|
||||
|
||||
6
upcoming-release-notes/7229.md
Normal file
6
upcoming-release-notes/7229.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Maintenance
|
||||
authors: [MatissJanis]
|
||||
---
|
||||
|
||||
Add Yarn constraints to ensure consistent dependency versions across all workspace packages.
|
||||
54
yarn.config.cjs
Normal file
54
yarn.config.cjs
Normal file
@@ -0,0 +1,54 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@yarnpkg/types')} */
|
||||
const { defineConfig } = require('@yarnpkg/types');
|
||||
|
||||
/**
|
||||
* Enforce that all workspaces use the same version of any shared dependency.
|
||||
* Workspace protocol references (workspace:*) and peerDependencies are
|
||||
* excluded since they intentionally use different/wider ranges.
|
||||
*
|
||||
* @param {import('@yarnpkg/types').Yarn.Constraints.Context} context
|
||||
*/
|
||||
function enforceConsistentDependencies({ Yarn }) {
|
||||
/** @type {Map<string, Map<string, Array<import('@yarnpkg/types').Yarn.Constraints.Workspace>>>} */
|
||||
const dependencyVersions = new Map();
|
||||
|
||||
for (const workspace of Yarn.workspaces()) {
|
||||
for (const type of ['dependencies', 'devDependencies']) {
|
||||
for (const dep of Yarn.dependencies({ workspace, type })) {
|
||||
if (dep.range.startsWith('workspace:')) continue;
|
||||
|
||||
if (!dependencyVersions.has(dep.ident)) {
|
||||
dependencyVersions.set(dep.ident, new Map());
|
||||
}
|
||||
const versions = dependencyVersions.get(dep.ident);
|
||||
if (!versions.has(dep.range)) {
|
||||
versions.set(dep.range, []);
|
||||
}
|
||||
versions.get(dep.range).push(workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [ident, versions] of dependencyVersions) {
|
||||
if (versions.size <= 1) continue;
|
||||
|
||||
const rangeList = [...versions.keys()].join(', ');
|
||||
|
||||
for (const [, workspaces] of versions) {
|
||||
for (const workspace of workspaces) {
|
||||
workspace.error(
|
||||
`Package "${ident}" has inconsistent versions across workspaces (${rangeList}). ` +
|
||||
`All workspaces must use the same version range.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = defineConfig({
|
||||
async constraints(ctx) {
|
||||
enforceConsistentDependencies(ctx);
|
||||
},
|
||||
});
|
||||
18
yarn.lock
18
yarn.lock
@@ -11242,6 +11242,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@yarnpkg/types@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "@yarnpkg/types@npm:4.0.1"
|
||||
dependencies:
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 10/f391763cd955356e9aad551b29e8de7bbf68a6c8992af7cdc950ccf53f8aff6695ad81aa4c8a8e7c582786a840a4f30617732e2cb49f4109b971a9242c31c9fc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"abbrev@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "abbrev@npm:3.0.1"
|
||||
@@ -11322,6 +11331,7 @@ __metadata:
|
||||
"@types/node": "npm:^22.19.10"
|
||||
"@types/prompts": "npm:^2.4.9"
|
||||
"@typescript/native-preview": "npm:^7.0.0-dev.20260309.1"
|
||||
"@yarnpkg/types": "npm:^4.0.1"
|
||||
baseline-browser-mapping: "npm:^2.9.19"
|
||||
cross-env: "npm:^10.1.0"
|
||||
eslint: "npm:^9.39.2"
|
||||
@@ -15199,8 +15209,8 @@ __metadata:
|
||||
"@types/react": "npm:^19.2.14"
|
||||
clsx: "npm:^2.1.1"
|
||||
prism-react-renderer: "npm:^2.4.1"
|
||||
react: "npm:^19.2.4"
|
||||
react-dom: "npm:^19.2.4"
|
||||
react: "npm:19.2.4"
|
||||
react-dom: "npm:19.2.4"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -24779,7 +24789,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-dom@npm:19.2.4, react-dom@npm:^19.2.4":
|
||||
"react-dom@npm:19.2.4":
|
||||
version: 19.2.4
|
||||
resolution: "react-dom@npm:19.2.4"
|
||||
dependencies:
|
||||
@@ -25227,7 +25237,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react@npm:19.2.4, react@npm:^19.2.4":
|
||||
"react@npm:19.2.4":
|
||||
version: 19.2.4
|
||||
resolution: "react@npm:19.2.4"
|
||||
checksum: 10/18179fe217f67eb2d0bc61cd04e7ad3c282ea09a1dface7eacd71816f62609f4bbf566c447c704335284deb8397b00bca084e0cd60e6f437279a7498e2d0bfe0
|
||||
|
||||
Reference in New Issue
Block a user