From c865929b93e751b3fcd2a8b18d67e9be1cbe2488 Mon Sep 17 00:00:00 2001 From: Stanislaw Wilczynski Date: Fri, 25 Sep 2026 16:15:16 +0200 Subject: [PATCH 1/2] fix: include declarations in published packages Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .azure-devops/nova-facade-release.yml | 7 +- ...-2a22ce80-9800-4f30-b2ad-e1681aa0e1ea.json | 7 ++ ...-364b7342-8ecf-4df4-902d-03f56bd6009e.json | 7 ++ package.json | 5 +- scripts/bin/verify-package-declarations.js | 101 ++++++++++++++++++ 5 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 change/@nova-react-2a22ce80-9800-4f30-b2ad-e1681aa0e1ea.json create mode 100644 change/@nova-types-364b7342-8ecf-4df4-902d-03f56bd6009e.json create mode 100644 scripts/bin/verify-package-declarations.js diff --git a/.azure-devops/nova-facade-release.yml b/.azure-devops/nova-facade-release.yml index dc79d93b..3be0deaf 100644 --- a/.azure-devops/nova-facade-release.yml +++ b/.azure-devops/nova-facade-release.yml @@ -112,8 +112,11 @@ extends: YARN_NPM_AUTH_TOKEN: $(NPM_TOKEN) NPM_CONFIG_USERCONFIG: $(Agent.TempDirectory)/npm-mirror.npmrc - - script: yarn build - displayName: build + - script: | + yarn build + yarn types + yarn verify-package-declarations + displayName: Build and validate publishable packages env: NPM_CONFIG_USERCONFIG: $(Agent.TempDirectory)/npm-mirror.npmrc diff --git a/change/@nova-react-2a22ce80-9800-4f30-b2ad-e1681aa0e1ea.json b/change/@nova-react-2a22ce80-9800-4f30-b2ad-e1681aa0e1ea.json new file mode 100644 index 00000000..72ef3261 --- /dev/null +++ b/change/@nova-react-2a22ce80-9800-4f30-b2ad-e1681aa0e1ea.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Restore declaration files in published packages", + "packageName": "@nova/react", + "email": "stwilczy@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@nova-types-364b7342-8ecf-4df4-902d-03f56bd6009e.json b/change/@nova-types-364b7342-8ecf-4df4-902d-03f56bd6009e.json new file mode 100644 index 00000000..62d15825 --- /dev/null +++ b/change/@nova-types-364b7342-8ecf-4df4-902d-03f56bd6009e.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Restore declaration files in published packages", + "packageName": "@nova/types", + "email": "stwilczy@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/package.json b/package.json index 81b81e99..01159d14 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "lage build", "change": "yarn beachball -b origin/main change", "checkchange": "yarn beachball -b origin/main check", - "ci": "yarn lage build types test lint && yarn checkchange", + "ci": "yarn lage build types test lint && yarn verify-package-declarations && yarn checkchange", "clean": "git clean -fdx -e node_modules", "postinstall": "yarn workspace @nova/examples playwright install --with-deps chromium", "lage": "lage", @@ -20,7 +20,8 @@ "prepare": "lage prepare", "release": "yarn beachball publish", "test": "lage test", - "types": "lage types" + "types": "lage types", + "verify-package-declarations": "node scripts/bin/verify-package-declarations.js" }, "resolutions": { "immutable": "^4.3.9", diff --git a/scripts/bin/verify-package-declarations.js b/scripts/bin/verify-package-declarations.js new file mode 100644 index 00000000..e780d5bd --- /dev/null +++ b/scripts/bin/verify-package-declarations.js @@ -0,0 +1,101 @@ +const fs = require("node:fs"); +const path = require("node:path"); +const { spawnSync } = require("node:child_process"); + +const repositoryRoot = path.resolve(__dirname, "../.."); +const packagesDirectory = path.join(repositoryRoot, "packages"); + +function collectDeclarationPaths(value, key, declarationPaths) { + if (key === "types" && typeof value === "string") { + declarationPaths.add(value.replace(/^\.\//, "")); + return; + } + + if (value && typeof value === "object") { + for (const [childKey, childValue] of Object.entries(value)) { + collectDeclarationPaths(childValue, childKey, declarationPaths); + } + } +} + +function getPackedFiles(packageDirectory) { + if (!process.env.npm_execpath) { + throw new Error("Run this validation through Yarn."); + } + + const result = spawnSync( + process.env.npm_execpath, + ["pack", "--dry-run", "--json"], + { + cwd: packageDirectory, + encoding: "utf8", + shell: process.platform === "win32", + }, + ); + + if (result.status !== 0) { + throw new Error(result.stderr || result.stdout); + } + + return new Set( + result.stdout + .trim() + .split("\n") + .map((line) => JSON.parse(line)) + .filter(({ location }) => location) + .map(({ location }) => location), + ); +} + +const failures = []; +const packageDirectories = fs + .readdirSync(packagesDirectory, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => path.join(packagesDirectory, entry.name)); + +for (const packageDirectory of packageDirectories) { + const packageJsonPath = path.join(packageDirectory, "package.json"); + if (!fs.existsSync(packageJsonPath)) { + continue; + } + + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); + if (packageJson.private || !packageJson.publishConfig) { + continue; + } + + const declarationPaths = new Set(); + collectDeclarationPaths( + packageJson.publishConfig, + undefined, + declarationPaths, + ); + + if (declarationPaths.size === 0) { + continue; + } + + const packedFiles = getPackedFiles(packageDirectory); + const missingDeclarations = [...declarationPaths].filter( + (declarationPath) => !packedFiles.has(declarationPath), + ); + + if (missingDeclarations.length > 0) { + failures.push( + `${packageJson.name}: missing ${missingDeclarations.join(", ")}`, + ); + } else { + console.log( + `${packageJson.name}: verified ${declarationPaths.size} declaration file(s)`, + ); + } +} + +if (failures.length > 0) { + console.error( + `Publishable package declaration validation failed:\n${failures + .map((failure) => `- ${failure}`) + .join("\n")}`, + ); + process.exitCode = 1; +} From 600238700d64ae4aafb48a9e8f3ca1ec405b567c Mon Sep 17 00:00:00 2001 From: Stanislaw Wilczynski Date: Fri, 25 Sep 2026 16:31:35 +0200 Subject: [PATCH 2/2] chore: keep declaration fix minimal Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .azure-devops/nova-facade-release.yml | 3 +- package.json | 5 +- scripts/bin/verify-package-declarations.js | 101 --------------------- 3 files changed, 3 insertions(+), 106 deletions(-) delete mode 100644 scripts/bin/verify-package-declarations.js diff --git a/.azure-devops/nova-facade-release.yml b/.azure-devops/nova-facade-release.yml index 3be0deaf..6e31e19d 100644 --- a/.azure-devops/nova-facade-release.yml +++ b/.azure-devops/nova-facade-release.yml @@ -115,8 +115,7 @@ extends: - script: | yarn build yarn types - yarn verify-package-declarations - displayName: Build and validate publishable packages + displayName: Build publishable packages env: NPM_CONFIG_USERCONFIG: $(Agent.TempDirectory)/npm-mirror.npmrc diff --git a/package.json b/package.json index 01159d14..81b81e99 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "lage build", "change": "yarn beachball -b origin/main change", "checkchange": "yarn beachball -b origin/main check", - "ci": "yarn lage build types test lint && yarn verify-package-declarations && yarn checkchange", + "ci": "yarn lage build types test lint && yarn checkchange", "clean": "git clean -fdx -e node_modules", "postinstall": "yarn workspace @nova/examples playwright install --with-deps chromium", "lage": "lage", @@ -20,8 +20,7 @@ "prepare": "lage prepare", "release": "yarn beachball publish", "test": "lage test", - "types": "lage types", - "verify-package-declarations": "node scripts/bin/verify-package-declarations.js" + "types": "lage types" }, "resolutions": { "immutable": "^4.3.9", diff --git a/scripts/bin/verify-package-declarations.js b/scripts/bin/verify-package-declarations.js deleted file mode 100644 index e780d5bd..00000000 --- a/scripts/bin/verify-package-declarations.js +++ /dev/null @@ -1,101 +0,0 @@ -const fs = require("node:fs"); -const path = require("node:path"); -const { spawnSync } = require("node:child_process"); - -const repositoryRoot = path.resolve(__dirname, "../.."); -const packagesDirectory = path.join(repositoryRoot, "packages"); - -function collectDeclarationPaths(value, key, declarationPaths) { - if (key === "types" && typeof value === "string") { - declarationPaths.add(value.replace(/^\.\//, "")); - return; - } - - if (value && typeof value === "object") { - for (const [childKey, childValue] of Object.entries(value)) { - collectDeclarationPaths(childValue, childKey, declarationPaths); - } - } -} - -function getPackedFiles(packageDirectory) { - if (!process.env.npm_execpath) { - throw new Error("Run this validation through Yarn."); - } - - const result = spawnSync( - process.env.npm_execpath, - ["pack", "--dry-run", "--json"], - { - cwd: packageDirectory, - encoding: "utf8", - shell: process.platform === "win32", - }, - ); - - if (result.status !== 0) { - throw new Error(result.stderr || result.stdout); - } - - return new Set( - result.stdout - .trim() - .split("\n") - .map((line) => JSON.parse(line)) - .filter(({ location }) => location) - .map(({ location }) => location), - ); -} - -const failures = []; -const packageDirectories = fs - .readdirSync(packagesDirectory, { withFileTypes: true }) - .filter((entry) => entry.isDirectory()) - .map((entry) => path.join(packagesDirectory, entry.name)); - -for (const packageDirectory of packageDirectories) { - const packageJsonPath = path.join(packageDirectory, "package.json"); - if (!fs.existsSync(packageJsonPath)) { - continue; - } - - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); - if (packageJson.private || !packageJson.publishConfig) { - continue; - } - - const declarationPaths = new Set(); - collectDeclarationPaths( - packageJson.publishConfig, - undefined, - declarationPaths, - ); - - if (declarationPaths.size === 0) { - continue; - } - - const packedFiles = getPackedFiles(packageDirectory); - const missingDeclarations = [...declarationPaths].filter( - (declarationPath) => !packedFiles.has(declarationPath), - ); - - if (missingDeclarations.length > 0) { - failures.push( - `${packageJson.name}: missing ${missingDeclarations.join(", ")}`, - ); - } else { - console.log( - `${packageJson.name}: verified ${declarationPaths.size} declaration file(s)`, - ); - } -} - -if (failures.length > 0) { - console.error( - `Publishable package declaration validation failed:\n${failures - .map((failure) => `- ${failure}`) - .join("\n")}`, - ); - process.exitCode = 1; -}