[ENHC] Create Yarn constraints to validate node version (#10542)

## Introduction
This is PR is a suggestion ! And should be discussed

With yarn `^4`, during installation won't raise an error if current dev
env does not satisfies the `engines` policy.
We have usually 10+ contributors support request regarding higher node
version issue per week

I would have preferred a very declarative integration using npm
[engines](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#engines)
but this does not seems to be natively supported by `yarn`

We should keep in mind that this might block any machines from our CICD
if they have diff node version installed ( such as running the project
on a different node version could result in bugs too )

## Implem

Created a yarn [constraints](https://yarnpkg.com/features/constraints)
run after each installation that checking if current node version
satisfies defined engines range ( might also be done for others engines
entries )

I assume we will always have the same engines policy for every packages,
at least that's not a consideration from now

## Further
We could refactor our package.json engines into only one using
`Yarn.set` etc

## Resource
- https://yarnpkg.com/configuration/yarnrc
- https://yarnpkg.com/features/constraints

## Note
- Not running constraints in `preInstall` hook as won't be effective on
fresh install
-
[engine-strict](https://docs.npmjs.com/cli/v8/using-npm/config#engine-strict)
is an npm-config
-
[devEngines](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#devengines)
are npm feature too ( for instance pnpm current PR
https://github.com/pnpm/pnpm/issues/8153 )

## Conclusion
As always any suggestions are more than welcomed !
This commit is contained in:
Paul Rastoin
2025-02-27 15:18:07 +01:00
committed by GitHub
parent 6be66f27d3
commit 65e569986d
4 changed files with 45 additions and 0 deletions

View File

@@ -2,6 +2,8 @@ enableHardenedMode: true
enableInlineHunks: true
enableConstraintsChecks: true
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.4.0.cjs

View File

@@ -1,4 +1,5 @@
{
"private": true,
"dependencies": {
"@air/react-drag-to-select": "^5.0.8",
"@apollo/client": "^3.7.17",
@@ -293,6 +294,7 @@
"@typescript-eslint/utils": "6.21.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/ui": "1.4.0",
"@yarnpkg/types": "^4.0.0",
"chromatic": "^6.18.0",
"concurrently": "^8.2.2",
"cross-var": "^1.1.0",

31
yarn.config.cjs Normal file
View File

@@ -0,0 +1,31 @@
// @ts-check
/** @type {import('@yarnpkg/types')} */
const { defineConfig, Yarn } = require('@yarnpkg/types');
const semver = require('semver');
const MONOREPO_ROOT_WORKSPACE = 'twenty';
module.exports = defineConfig({
async constraints({ Yarn }) {
const rootWorkspace = Yarn.workspace({ ident: MONOREPO_ROOT_WORKSPACE });
if (!rootWorkspace) {
throw new Error(
`Should never occur, ${MONOREPO_ROOT_WORKSPACE} workspace not found`,
);
}
const requiredNodeVersion = rootWorkspace.manifest.engines?.node;
if (!requiredNodeVersion) {
throw new Error(
`Should never occur, ${requiredNodeVersion} could not find node range in engines manifest`,
);
}
const currentNodeVersion = process.version;
if (!semver.satisfies(currentNodeVersion, requiredNodeVersion)) {
throw new Error(
`Node version ${currentNodeVersion} doesn't match the required version, please use ${requiredNodeVersion}`,
);
}
},
});

View File

@@ -19925,6 +19925,15 @@ __metadata:
languageName: node
linkType: hard
"@yarnpkg/types@npm:^4.0.0":
version: 4.0.0
resolution: "@yarnpkg/types@npm:4.0.0"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/41f67a4aa5c414c1e228f51453451fa15e0dd70c5cf2b1ae1ca142a3f018f25e4a37e60372cd0f5970c755e1804a2e31e208bff427add1cf13f899b0b9adc1e0
languageName: node
linkType: hard
"@zapier/secret-scrubber@npm:^1.0.8":
version: 1.1.1
resolution: "@zapier/secret-scrubber@npm:1.1.1"
@@ -47239,6 +47248,7 @@ __metadata:
"@vitest/ui": "npm:1.4.0"
"@wyw-in-js/vite": "npm:^0.5.3"
"@xyflow/react": "npm:^12.4.2"
"@yarnpkg/types": "npm:^4.0.0"
add: "npm:^2.0.6"
addressparser: "npm:^1.0.1"
afterframe: "npm:^1.0.2"