From 9320c9443b13d57c314793b94f8434cccac6c83f Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Mon, 3 Nov 2025 18:30:16 -0800 Subject: [PATCH 1/6] Copy JSON schemas to projects' temp/json-schemas folders. --- apps/api-documenter/config/heft.json | 27 ++++++++++++++++++ apps/api-extractor/config/heft.json | 17 +++++++++++ apps/heft/config/heft.json | 27 ++++++++++++++++++ apps/lockfile-explorer/config/heft.json | 18 ++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../heft-jest-plugin/config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../heft-plugin.json | 2 +- ...ft-json-schema-typings-plugin.schema.json} | 0 .../heft-lint-plugin/config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../heft-plugin.json | 2 +- ...t-localization-typings-plugin.schema.json} | 0 .../heft-rspack-plugin/config/heft.json | 27 ++++++++++++++++++ .../heft-sass-plugin/config/heft.json | 27 ++++++++++++++++++ .../heft-storybook-plugin/config/heft.json | 27 ++++++++++++++++++ .../heft-typescript-plugin/config/heft.json | 27 ++++++++++++++++++ .../heft-webpack4-plugin/config/heft.json | 27 ++++++++++++++++++ .../heft-webpack5-plugin/config/heft.json | 27 ++++++++++++++++++ libraries/credential-cache/config/heft.json | 28 +++++++++++++++++++ libraries/rig-package/config/heft.json | 27 ++++++++++++++++++ libraries/rush-lib/config/heft.json | 17 +++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../rush-bridge-cache-plugin/config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../config/heft.json | 27 ++++++++++++++++++ .../rush-serve-plugin/config/heft.json | 27 ++++++++++++++++++ 30 files changed, 676 insertions(+), 2 deletions(-) create mode 100644 apps/api-documenter/config/heft.json create mode 100644 apps/heft/config/heft.json create mode 100644 heft-plugins/heft-api-extractor-plugin/config/heft.json create mode 100644 heft-plugins/heft-isolated-typescript-transpile-plugin/config/heft.json create mode 100644 heft-plugins/heft-jest-plugin/config/heft.json create mode 100644 heft-plugins/heft-json-schema-typings-plugin/config/heft.json rename heft-plugins/heft-json-schema-typings-plugin/src/schemas/{options.schema.json => heft-json-schema-typings-plugin.schema.json} (100%) create mode 100644 heft-plugins/heft-lint-plugin/config/heft.json create mode 100644 heft-plugins/heft-localization-typings-plugin/config/heft.json rename heft-plugins/heft-localization-typings-plugin/src/schemas/{options.schema.json => heft-localization-typings-plugin.schema.json} (100%) create mode 100644 heft-plugins/heft-rspack-plugin/config/heft.json create mode 100644 heft-plugins/heft-sass-plugin/config/heft.json create mode 100644 heft-plugins/heft-storybook-plugin/config/heft.json create mode 100644 heft-plugins/heft-typescript-plugin/config/heft.json create mode 100644 heft-plugins/heft-webpack4-plugin/config/heft.json create mode 100644 heft-plugins/heft-webpack5-plugin/config/heft.json create mode 100644 libraries/credential-cache/config/heft.json create mode 100644 libraries/rig-package/config/heft.json create mode 100644 rush-plugins/rush-amazon-s3-build-cache-plugin/config/heft.json create mode 100644 rush-plugins/rush-azure-storage-build-cache-plugin/config/heft.json create mode 100644 rush-plugins/rush-bridge-cache-plugin/config/heft.json create mode 100644 rush-plugins/rush-buildxl-graph-plugin/config/heft.json create mode 100644 rush-plugins/rush-http-build-cache-plugin/config/heft.json create mode 100644 rush-plugins/rush-redis-cobuild-plugin/config/heft.json create mode 100644 rush-plugins/rush-serve-plugin/config/heft.json diff --git a/apps/api-documenter/config/heft.json b/apps/api-documenter/config/heft.json new file mode 100644 index 00000000000..b3046cad172 --- /dev/null +++ b/apps/api-documenter/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/api-extractor/v7"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/apps/api-extractor/config/heft.json b/apps/api-extractor/config/heft.json index 0b965cec36a..a36ac2cf4c0 100644 --- a/apps/api-extractor/config/heft.json +++ b/apps/api-extractor/config/heft.json @@ -29,6 +29,23 @@ ] } } + }, + + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/api-extractor/v7"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } } } } diff --git a/apps/heft/config/heft.json b/apps/heft/config/heft.json new file mode 100644 index 00000000000..8d1359f022f --- /dev/null +++ b/apps/heft/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/apps/lockfile-explorer/config/heft.json b/apps/lockfile-explorer/config/heft.json index 6664d95480c..ca7a8305599 100644 --- a/apps/lockfile-explorer/config/heft.json +++ b/apps/lockfile-explorer/config/heft.json @@ -58,9 +58,27 @@ } } }, + "typescript": { // The "typescript" task should not run until after "pre-compile-copy" completes. "taskDependencies": ["pre-compile-copy"] + }, + + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/lockfile-explorer"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } } } } diff --git a/heft-plugins/heft-api-extractor-plugin/config/heft.json b/heft-plugins/heft-api-extractor-plugin/config/heft.json new file mode 100644 index 00000000000..8d1359f022f --- /dev/null +++ b/heft-plugins/heft-api-extractor-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-isolated-typescript-transpile-plugin/config/heft.json b/heft-plugins/heft-isolated-typescript-transpile-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-isolated-typescript-transpile-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-jest-plugin/config/heft.json b/heft-plugins/heft-jest-plugin/config/heft.json new file mode 100644 index 00000000000..8d1359f022f --- /dev/null +++ b/heft-plugins/heft-jest-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-json-schema-typings-plugin/config/heft.json b/heft-plugins/heft-json-schema-typings-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-json-schema-typings-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-json-schema-typings-plugin/heft-plugin.json b/heft-plugins/heft-json-schema-typings-plugin/heft-plugin.json index 29eec2267b7..f9db17a5dbd 100644 --- a/heft-plugins/heft-json-schema-typings-plugin/heft-plugin.json +++ b/heft-plugins/heft-json-schema-typings-plugin/heft-plugin.json @@ -5,7 +5,7 @@ { "pluginName": "json-schema-typings-plugin", "entryPoint": "./lib/JsonSchemaTypingsPlugin", - "optionsSchema": "./lib/schemas/options.schema.json" + "optionsSchema": "./lib/schemas/heft-json-schema-typings-plugin.schema.json" } ] } diff --git a/heft-plugins/heft-json-schema-typings-plugin/src/schemas/options.schema.json b/heft-plugins/heft-json-schema-typings-plugin/src/schemas/heft-json-schema-typings-plugin.schema.json similarity index 100% rename from heft-plugins/heft-json-schema-typings-plugin/src/schemas/options.schema.json rename to heft-plugins/heft-json-schema-typings-plugin/src/schemas/heft-json-schema-typings-plugin.schema.json diff --git a/heft-plugins/heft-lint-plugin/config/heft.json b/heft-plugins/heft-lint-plugin/config/heft.json new file mode 100644 index 00000000000..8d1359f022f --- /dev/null +++ b/heft-plugins/heft-lint-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-localization-typings-plugin/config/heft.json b/heft-plugins/heft-localization-typings-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-localization-typings-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-localization-typings-plugin/heft-plugin.json b/heft-plugins/heft-localization-typings-plugin/heft-plugin.json index f4a6d738ecf..3d1d82ac7f3 100644 --- a/heft-plugins/heft-localization-typings-plugin/heft-plugin.json +++ b/heft-plugins/heft-localization-typings-plugin/heft-plugin.json @@ -5,7 +5,7 @@ { "pluginName": "localization-typings-plugin", "entryPoint": "./lib/LocalizationTypingsPlugin", - "optionsSchema": "./lib/schemas/options.schema.json" + "optionsSchema": "./lib/schemas/heft-localization-typings-plugin.schema.json" } ] } diff --git a/heft-plugins/heft-localization-typings-plugin/src/schemas/options.schema.json b/heft-plugins/heft-localization-typings-plugin/src/schemas/heft-localization-typings-plugin.schema.json similarity index 100% rename from heft-plugins/heft-localization-typings-plugin/src/schemas/options.schema.json rename to heft-plugins/heft-localization-typings-plugin/src/schemas/heft-localization-typings-plugin.schema.json diff --git a/heft-plugins/heft-rspack-plugin/config/heft.json b/heft-plugins/heft-rspack-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-rspack-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-sass-plugin/config/heft.json b/heft-plugins/heft-sass-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-sass-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-storybook-plugin/config/heft.json b/heft-plugins/heft-storybook-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-storybook-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-typescript-plugin/config/heft.json b/heft-plugins/heft-typescript-plugin/config/heft.json new file mode 100644 index 00000000000..8d1359f022f --- /dev/null +++ b/heft-plugins/heft-typescript-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-webpack4-plugin/config/heft.json b/heft-plugins/heft-webpack4-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-webpack4-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/heft-plugins/heft-webpack5-plugin/config/heft.json b/heft-plugins/heft-webpack5-plugin/config/heft.json new file mode 100644 index 00000000000..0e52387039a --- /dev/null +++ b/heft-plugins/heft-webpack5-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/heft/v1"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/libraries/credential-cache/config/heft.json b/libraries/credential-cache/config/heft.json new file mode 100644 index 00000000000..0922361a39e --- /dev/null +++ b/libraries/credential-cache/config/heft.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/libraries/rig-package/config/heft.json b/libraries/rig-package/config/heft.json new file mode 100644 index 00000000000..2fc245813e5 --- /dev/null +++ b/libraries/rig-package/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "decoupled-local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rig-package"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/libraries/rush-lib/config/heft.json b/libraries/rush-lib/config/heft.json index cb203be79e0..e260d7e35e9 100644 --- a/libraries/rush-lib/config/heft.json +++ b/libraries/rush-lib/config/heft.json @@ -63,6 +63,23 @@ "taskPlugin": { "pluginPackage": "@rushstack/heft-webpack5-plugin" } + }, + + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } } } } diff --git a/rush-plugins/rush-amazon-s3-build-cache-plugin/config/heft.json b/rush-plugins/rush-amazon-s3-build-cache-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-amazon-s3-build-cache-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-azure-storage-build-cache-plugin/config/heft.json b/rush-plugins/rush-azure-storage-build-cache-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-azure-storage-build-cache-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-bridge-cache-plugin/config/heft.json b/rush-plugins/rush-bridge-cache-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-bridge-cache-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-buildxl-graph-plugin/config/heft.json b/rush-plugins/rush-buildxl-graph-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-buildxl-graph-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-http-build-cache-plugin/config/heft.json b/rush-plugins/rush-http-build-cache-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-http-build-cache-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-redis-cobuild-plugin/config/heft.json b/rush-plugins/rush-redis-cobuild-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-redis-cobuild-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} diff --git a/rush-plugins/rush-serve-plugin/config/heft.json b/rush-plugins/rush-serve-plugin/config/heft.json new file mode 100644 index 00000000000..625490052a1 --- /dev/null +++ b/rush-plugins/rush-serve-plugin/config/heft.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "extends": "local-node-rig/profiles/default/config/heft.json", + "phasesByName": { + "build": { + "tasksByName": { + "copy-json-schemas": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "src/schemas", + "destinationFolders": ["temp/json-schemas/rush/v5"], + "fileExtensions": [".schema.json"], + "hardlink": true + } + ] + } + } + } + } + } + } +} From fd0556eb77741cba5a8d5fa3df0a6b2288a8d310 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Mon, 3 Nov 2025 18:30:33 -0800 Subject: [PATCH 2/6] Introduce a tool for collecting JSON schemas. --- .../src/cli/ToolboxCommandLine.ts | 11 +- .../actions/BumpDecoupledLocalDependencies.ts | 12 +- .../cli/actions/CollectJsonSchemasAction.ts | 138 ++++++++++++++++++ .../src/cli/actions/ReadmeAction.ts | 10 +- .../src/cli/actions/RecordVersionsAction.ts | 10 +- 5 files changed, 168 insertions(+), 13 deletions(-) create mode 100644 repo-scripts/repo-toolbox/src/cli/actions/CollectJsonSchemasAction.ts diff --git a/repo-scripts/repo-toolbox/src/cli/ToolboxCommandLine.ts b/repo-scripts/repo-toolbox/src/cli/ToolboxCommandLine.ts index eb384cdb761..aeadc6150cc 100644 --- a/repo-scripts/repo-toolbox/src/cli/ToolboxCommandLine.ts +++ b/repo-scripts/repo-toolbox/src/cli/ToolboxCommandLine.ts @@ -2,10 +2,12 @@ // See LICENSE in the project root for license information. import { CommandLineParser } from '@rushstack/ts-command-line'; +import { ConsoleTerminalProvider, type ITerminal, Terminal } from '@rushstack/terminal'; import { ReadmeAction } from './actions/ReadmeAction'; import { RecordVersionsAction } from './actions/RecordVersionsAction'; import { BumpDecoupledLocalDependencies } from './actions/BumpDecoupledLocalDependencies'; +import { CollectJsonSchemasAction } from './actions/CollectJsonSchemasAction'; export class ToolboxCommandLine extends CommandLineParser { public constructor() { @@ -14,8 +16,11 @@ export class ToolboxCommandLine extends CommandLineParser { toolDescription: 'Used to execute various operations specific to this repo' }); - this.addAction(new ReadmeAction()); - this.addAction(new RecordVersionsAction()); - this.addAction(new BumpDecoupledLocalDependencies()); + const terminal: ITerminal = new Terminal(new ConsoleTerminalProvider()); + + this.addAction(new ReadmeAction(terminal)); + this.addAction(new RecordVersionsAction(terminal)); + this.addAction(new BumpDecoupledLocalDependencies(terminal)); + this.addAction(new CollectJsonSchemasAction(terminal)); } } diff --git a/repo-scripts/repo-toolbox/src/cli/actions/BumpDecoupledLocalDependencies.ts b/repo-scripts/repo-toolbox/src/cli/actions/BumpDecoupledLocalDependencies.ts index b2f10b83de8..7d60e1e775f 100644 --- a/repo-scripts/repo-toolbox/src/cli/actions/BumpDecoupledLocalDependencies.ts +++ b/repo-scripts/repo-toolbox/src/cli/actions/BumpDecoupledLocalDependencies.ts @@ -4,21 +4,25 @@ import type { ChildProcess } from 'node:child_process'; import { Async, Executable, JsonFile } from '@rushstack/node-core-library'; -import { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal'; +import type { ITerminal } from '@rushstack/terminal'; import { DependencyType, RushConfiguration, type CommonVersionsConfiguration } from '@microsoft/rush-lib'; import { CommandLineAction } from '@rushstack/ts-command-line'; export class BumpDecoupledLocalDependencies extends CommandLineAction { - public constructor() { + private readonly _terminal: ITerminal; + + public constructor(terminal: ITerminal) { super({ actionName: 'bump-decoupled-local-dependencies', summary: 'Updates decoupled local dependencies inside the repo.', documentation: '' }); + + this._terminal = terminal; } protected override async onExecuteAsync(): Promise { - const terminal: Terminal = new Terminal(new ConsoleTerminalProvider()); + const terminal: ITerminal = this._terminal; const rushConfiguration: RushConfiguration = RushConfiguration.loadFromDefaultLocation({ startingFolder: process.cwd() }); @@ -93,7 +97,7 @@ export class BumpDecoupledLocalDependencies extends CommandLineAction { terminal.writeLine(`Updated ${rushConfiguration.rushJsonFile}`); } - private async _getLatestPublishedVersionAsync(terminal: Terminal, packageName: string): Promise { + private async _getLatestPublishedVersionAsync(terminal: ITerminal, packageName: string): Promise { return await new Promise((resolve: (result: string) => void, reject: (error: Error) => void) => { const childProcess: ChildProcess = Executable.spawn('npm', ['view', packageName, 'version'], { stdio: ['ignore', 'pipe', 'pipe'] diff --git a/repo-scripts/repo-toolbox/src/cli/actions/CollectJsonSchemasAction.ts b/repo-scripts/repo-toolbox/src/cli/actions/CollectJsonSchemasAction.ts new file mode 100644 index 00000000000..48cdfa0784f --- /dev/null +++ b/repo-scripts/repo-toolbox/src/cli/actions/CollectJsonSchemasAction.ts @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import * as path from 'node:path'; + +import { FileSystem, AlreadyReportedError, Async, type FolderItem } from '@rushstack/node-core-library'; +import type { ITerminal } from '@rushstack/terminal'; +import { RushConfiguration, type RushConfigurationProject } from '@microsoft/rush-lib'; +import { CommandLineAction, type IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line'; + +interface IFolderItemToCopy { + absolutePath: string; + relativePath: string; + content: string; +} + +async function* _getFolderItemsRecursiveAsync( + folderAbsolutePath: string, + folderRelativePath: string = '' +): AsyncIterable { + let folderItems: FolderItem[]; + try { + folderItems = await FileSystem.readFolderItemsAsync(folderAbsolutePath); + } catch (e) { + if (!FileSystem.isNotExistError(e)) { + throw e; + } else { + return; + } + } + + for (const entry of folderItems) { + const entryRelativePath: string = `${folderRelativePath}/${entry.name}`; + const entryAbsolutePath: string = `${folderAbsolutePath}/${entry.name}`; + if (entry.isDirectory()) { + yield* _getFolderItemsRecursiveAsync(entryAbsolutePath, entryRelativePath); + } else { + const content: string = await FileSystem.readFileAsync(entryAbsolutePath); + yield { + absolutePath: entryAbsolutePath, + relativePath: entryRelativePath, + content + }; + } + } +} + +export class CollectJsonSchemasAction extends CommandLineAction { + private readonly _outputPathParameter: IRequiredCommandLineStringParameter; + + private readonly _terminal: ITerminal; + + public constructor(terminal: ITerminal) { + super({ + actionName: 'collect-json-schemas', + summary: 'Generates JSON schema files based on rush.json inventory', + documentation: "Use this to update the repo's JSON schema files" + }); + + this._terminal = terminal; + + this._outputPathParameter = this.defineStringParameter({ + parameterLongName: '--output-path', + description: 'Path to the output directory for the generated JSON schema files.', + argumentName: 'PATH', + required: true + }); + } + + protected override async onExecuteAsync(): Promise { + const terminal: ITerminal = this._terminal; + const rushConfiguration: RushConfiguration = RushConfiguration.loadFromDefaultLocation(); + + const outputPath: string = path.resolve(this._outputPathParameter.value); + + const contentByAbsolutePathByRelativePath: Map> = new Map(); + + await Async.forEachAsync( + rushConfiguration.projects, + async ({ projectFolder }: RushConfigurationProject) => { + const schemaFiles: AsyncIterable = _getFolderItemsRecursiveAsync( + `${projectFolder}/temp/json-schemas`, + '' + ); + await Async.forEachAsync(schemaFiles, async ({ absolutePath, relativePath, content }) => { + let contentByAbsolutePath: Map | undefined = + contentByAbsolutePathByRelativePath.get(relativePath); + if (!contentByAbsolutePath) { + contentByAbsolutePath = new Map(); + contentByAbsolutePathByRelativePath.set(relativePath, contentByAbsolutePath); + } + + let absolutePaths: string[] | undefined = contentByAbsolutePath.get(content); + if (!absolutePaths) { + absolutePaths = []; + contentByAbsolutePath.set(content, absolutePaths); + } + + absolutePaths.push(absolutePath); + }); + }, + { concurrency: 5 } + ); + + let encounteredCollisions: boolean = false; + const filesToWrite: Map = new Map(); + for (const [relativePath, contentByAbsolutePath] of contentByAbsolutePathByRelativePath) { + if (contentByAbsolutePath.size > 1) { + encounteredCollisions = true; + + terminal.writeErrorLine( + `Multiple projects generated different contents for the JSON schema "${relativePath}":` + ); + + for (const absolutePaths of contentByAbsolutePath.values()) { + for (const absolutePath of absolutePaths) { + terminal.writeErrorLine(` - ${absolutePath}`); + } + } + } else { + filesToWrite.set(`${outputPath}/${relativePath}`, Array.from(contentByAbsolutePath.keys())[0]); + } + } + + if (encounteredCollisions) { + throw new AlreadyReportedError(); + } else { + await FileSystem.ensureEmptyFolderAsync(outputPath); + + await Async.forEachAsync( + filesToWrite, + async ([outPath, content]) => + await FileSystem.writeFileAsync(outPath, content, { ensureFolderExists: true }), + { concurrency: 25 } + ); + } + } +} diff --git a/repo-scripts/repo-toolbox/src/cli/actions/ReadmeAction.ts b/repo-scripts/repo-toolbox/src/cli/actions/ReadmeAction.ts index 01961880ea3..5128ceebf59 100644 --- a/repo-scripts/repo-toolbox/src/cli/actions/ReadmeAction.ts +++ b/repo-scripts/repo-toolbox/src/cli/actions/ReadmeAction.ts @@ -6,7 +6,7 @@ import * as path from 'node:path'; import * as Diff from 'diff'; import { StringBuilder, Sort, FileSystem, Text, AlreadyReportedError } from '@rushstack/node-core-library'; -import { Terminal, ConsoleTerminalProvider, Colorize } from '@rushstack/terminal'; +import { Colorize, type ITerminal } from '@rushstack/terminal'; import { RushConfiguration, type RushConfigurationProject, LockStepVersionPolicy } from '@microsoft/rush-lib'; import { CommandLineAction, type CommandLineFlagParameter } from '@rushstack/ts-command-line'; @@ -16,13 +16,17 @@ const GENERATED_PROJECT_SUMMARY_END_COMMENT_TEXT: string = '