diff --git a/.ng-dev/commit-message.mjs b/.ng-dev/commit-message.mjs index 8790c7d6d1e1..acf372245104 100644 --- a/.ng-dev/commit-message.mjs +++ b/.ng-dev/commit-message.mjs @@ -1,8 +1,8 @@ -import packages from '../lib/packages.js'; +import { getReleasablePackages } from '../lib/packages.mjs'; /** * The configuration for `ng-dev commit-message` commands. - * + * * @type { import("@angular/ng-dev").CommitMessageConfig } */ export const commitMessage = { @@ -10,5 +10,5 @@ export const commitMessage = { minBodyLength: 0, minBodyLengthTypeExcludes: ['docs'], // Note: When changing this logic, also change the `contributing.ejs` file. - scopes: [...Object.keys(packages.packages)], + scopes: getReleasablePackages().map(({ name }) => name), }; diff --git a/.ng-dev/release.mjs b/.ng-dev/release.mjs index c9d78449fd84..4871f71aac31 100644 --- a/.ng-dev/release.mjs +++ b/.ng-dev/release.mjs @@ -1,19 +1,16 @@ import semver from 'semver'; -import packages from '../lib/packages.js'; +import { getReleasablePackages } from '../lib/packages.mjs'; -const npmPackages = Object.entries(packages.releasePackages).map(([name, { experimental }]) => ({ - name, - experimental, -})); +const packages = getReleasablePackages(); -/** +/** * Configuration for the `ng-dev release` command. - * + * * @type { import("@angular/ng-dev").ReleaseConfig } */ export const release = { representativeNpmPackage: '@angular/cli', - npmPackages, + npmPackages: packages.map(({ name, experimental }) => ({ name, experimental })), buildPackages: async () => { // The `performNpmReleaseBuild` function is loaded at runtime to avoid loading additional // files and dependencies unless a build is required. @@ -26,7 +23,7 @@ export const release = { '../scripts/release-checks/dependency-ranges/index.mjs' ); - await assertValidDependencyRanges(newVersion, packages.releasePackages); + await assertValidDependencyRanges(newVersion, packages); }, releaseNotes: { groupOrder: [ diff --git a/.ng-dev/tsconfig.json b/.ng-dev/tsconfig.json index 1c0503523bf5..9f0a0f84be18 100644 --- a/.ng-dev/tsconfig.json +++ b/.ng-dev/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../tsconfig.json", "compilerOptions": { + "resolveJsonModule": true, "allowJs": true, "module": "Node16", "moduleResolution": "Node16", + "checkJs": true, "noEmit": true, "types": [] }, diff --git a/lib/packages.mjs b/lib/packages.mjs new file mode 100644 index 000000000000..defd9c4dbec6 --- /dev/null +++ b/lib/packages.mjs @@ -0,0 +1,32 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import fastGlob from 'fast-glob'; +import { readFileSync } from 'node:fs'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); +const monorepoData = require('../.monorepo.json'); + +export function getReleasablePackages() { + const packages = []; + for (const pkg of fastGlob.sync('./packages/*/*/package.json')) { + const data = JSON.parse(readFileSync(pkg, 'utf-8')); + if (!(data.name in monorepoData.packages)) { + throw new Error(`${data.name} does not exist in .monorepo.json`); + } + + if (data.private) { + continue; + } + + packages.push(data); + } + + return packages; +} diff --git a/lib/packages.ts b/lib/packages.ts index 7fa8848f78ab..ed5df586ad42 100644 --- a/lib/packages.ts +++ b/lib/packages.ts @@ -85,7 +85,7 @@ function loadPackageJson(p: string) { // Overwrite engines to a common default. case 'engines': pkg['engines'] = { - 'node': '^16.14.0 || >=18.10.0', + 'node': '^18.19.1 || ^20.11.1', 'npm': '^6.11.0 || ^7.5.6 || >=8.0.0', 'yarn': '>= 1.13.0', }; diff --git a/package.json b/package.json index 168964f7e1a8..6f821b67f175 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,13 @@ "build": "node ./bin/devkit-admin build", "build-tsc": "tsc -p tsconfig.json", "lint": "eslint --cache --max-warnings=0 \"**/*.ts\"", - "ng-dev": "ts-node --esm --project .ng-dev/tsconfig.json --transpile-only node_modules/@angular/ng-dev/bundles/cli.mjs", "templates": "node ./bin/devkit-admin templates", "validate": "node ./bin/devkit-admin validate", "postinstall": "yarn webdriver-update && yarn husky && patch-package --patch-dir tools/postinstall/patches", "//webdriver-update-README": "ChromeDriver version must match Puppeteer Chromium version, see https://github.com/GoogleChrome/puppeteer/releases http://chromedriver.chromium.org/downloads", "webdriver-update": "webdriver-manager update --standalone false --gecko false --versions.chrome 106.0.5249.21", "public-api:check": "node goldens/public-api/manage.js test", + "ng-dev": "node --no-warnings=ExperimentalWarning --loader ts-node/esm/transpile-only node_modules/@angular/ng-dev/bundles/cli.mjs", "public-api:update": "node goldens/public-api/manage.js accept", "ts-circular-deps:check": "yarn -s ng-dev ts-circular-deps check --config ./packages/circular-deps-test.conf.js", "ts-circular-deps:approve": "yarn -s ng-dev ts-circular-deps approve --config ./packages/circular-deps-test.conf.js", @@ -39,7 +39,7 @@ "url": "https://github.com/angular/angular-cli.git" }, "engines": { - "node": "^18.13.0 || ^20.9.0", + "node": "^18.19.1 || ^20.11.1", "yarn": ">=1.21.1 <2", "npm": "Please use yarn instead of NPM to install dependencies" }, diff --git a/scripts/release-checks/dependency-ranges/index.mts b/scripts/release-checks/dependency-ranges/index.mts index 764f2c9bfbb4..b9dfbc98e186 100644 --- a/scripts/release-checks/dependency-ranges/index.mts +++ b/scripts/release-checks/dependency-ranges/index.mts @@ -6,11 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ +import { Log, ReleasePrecheckError, bold } from '@angular/ng-dev'; import semver from 'semver'; -import { Log, bold, ReleasePrecheckError } from '@angular/ng-dev'; -import { checkPeerDependencies } from './peer-deps-check.mjs'; import { checkSchematicsAngularLatestVersion } from './latest-versions-check.mjs'; -import { PackageMap } from '../../../lib/packages.js'; +import { PackageJson, checkPeerDependencies } from './peer-deps-check.mjs'; /** Environment variable that can be used to skip this pre-check. */ const skipEnvVar = 'SKIP_DEPENDENCY_RANGE_PRECHECK'; @@ -26,7 +25,7 @@ const skipEnvVar = 'SKIP_DEPENDENCY_RANGE_PRECHECK'; */ export async function assertValidDependencyRanges( newVersion: semver.SemVer, - allPackages: PackageMap, + allPackages: PackageJson[], ) { if (process.env[skipEnvVar] === '1') { return; diff --git a/scripts/release-checks/dependency-ranges/peer-deps-check.mts b/scripts/release-checks/dependency-ranges/peer-deps-check.mts index 1f5d90676984..40aec5fab2eb 100644 --- a/scripts/release-checks/dependency-ranges/peer-deps-check.mts +++ b/scripts/release-checks/dependency-ranges/peer-deps-check.mts @@ -6,26 +6,20 @@ * found in the LICENSE file at https://angular.io/license */ -import path from 'path'; -import url from 'url'; import semver from 'semver'; -import { PackageMap } from '../../../lib/packages.js'; /** Path to the current directory. */ -const currentDir = path.dirname(url.fileURLToPath(import.meta.url)); -/** Path to the project directory. */ -const projectDir = path.join(currentDir, '../../../'); /** Describes a parsed `package.json` file. */ -interface PackageJson { +export interface PackageJson { name?: string; peerDependencies?: Record; } export async function checkPeerDependencies( newVersion: semver.SemVer, - allPackages: PackageMap, + allPackages: PackageJson[], ): Promise { const { major, minor } = newVersion; const isPrerelease = !!newVersion.prerelease[0]; @@ -39,8 +33,8 @@ export async function checkPeerDependencies( } const failures: string[] = []; - for (const pkgInfo of Object.values(allPackages)) { - failures.push(...checkPackage(pkgInfo.packageJson, expectedFwPeerDep)); + for (const pkgInfo of allPackages) { + failures.push(...checkPackage(pkgInfo, expectedFwPeerDep)); } return failures;