mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-29 19:14:22 -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
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);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user