diff --git a/change/@fluentui-react-text-701383d5-631a-46fc-a991-276a590f6132.json b/change/@fluentui-react-text-701383d5-631a-46fc-a991-276a590f6132.json new file mode 100644 index 0000000000000..3d142300ca350 --- /dev/null +++ b/change/@fluentui-react-text-701383d5-631a-46fc-a991-276a590f6132.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: add verify-packaging task", + "packageName": "@fluentui/react-text", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-utilities-78031fb1-2f31-4c82-a6e6-921baf28c8f6.json b/change/@fluentui-utilities-78031fb1-2f31-4c82-a6e6-921baf28c8f6.json new file mode 100644 index 0000000000000..961ab0b50fe2e --- /dev/null +++ b/change/@fluentui-utilities-78031fb1-2f31-4c82-a6e6-921baf28c8f6.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: add verify-packaging task", + "packageName": "@fluentui/utilities", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/lage.config.js b/lage.config.js index 52eb6f5274402..8ddb1dc7fdd27 100644 --- a/lage.config.js +++ b/lage.config.js @@ -16,6 +16,7 @@ module.exports = { 'code-style': [], 'update-snapshots': ['^update-snapshots'], '@fluentui/docs#build': ['@fluentui/react-northstar#build:info'], + 'verify-packaging': ['build'], }, // Adds some ADO-specific logging commands for reporting failures diff --git a/package.json b/package.json index 0a67d15443323..8378e58d12b3d 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "build": "lage build --verbose", "build:codesandbox": "yarn build --to @fluentui/react --to @fluentui/react-components", "build:fluentui:docs": "gulp build:docs", - "buildci": "lage build test lint type-check test-ssr --verbose", + "buildci": "lage build test lint type-check test-ssr verify-packaging --verbose", "builddemo": "yarn build --to public-docsite-resources", "buildto": "lage build --verbose --to", "buildto:lerna": "node ./scripts/executors/buildTo.js", diff --git a/packages/react-components/react-text/package.json b/packages/react-components/react-text/package.json index 55b5186faf18d..677a772a24ec6 100644 --- a/packages/react-components/react-text/package.json +++ b/packages/react-components/react-text/package.json @@ -23,7 +23,8 @@ "storybook": "start-storybook", "type-check": "tsc -b tsconfig.json", "generate-api": "just-scripts generate-api", - "test-ssr": "test-ssr \"./stories/**/*.stories.tsx\"" + "test-ssr": "test-ssr \"./stories/**/*.stories.tsx\"", + "verify-packaging": "just-scripts verify-packaging" }, "devDependencies": { "@fluentui/eslint-plugin": "*", diff --git a/packages/utilities/package.json b/packages/utilities/package.json index c54e727b09cba..43a75bac72eb7 100644 --- a/packages/utilities/package.json +++ b/packages/utilities/package.json @@ -21,7 +21,8 @@ "lint": "just-scripts lint", "start-test": "just-scripts jest-watch", "test": "just-scripts test", - "update-snapshots": "just-scripts jest -u" + "update-snapshots": "just-scripts jest -u", + "verify-packaging": "just-scripts verify-packaging" }, "devDependencies": { "@fluentui/eslint-plugin": "*", diff --git a/scripts/tasks/src/presets.ts b/scripts/tasks/src/presets.ts index ffa8f45073515..3f57d27a64ffe 100644 --- a/scripts/tasks/src/presets.ts +++ b/scripts/tasks/src/presets.ts @@ -21,6 +21,7 @@ import { buildStorybookTask, startStorybookTask } from './storybook'; import { swc } from './swc'; import { ts } from './ts'; import { typeCheck } from './type-check'; +import { verifyPackaging } from './verify-packaging'; import { webpack, webpackDevServer } from './webpack'; /** Do only the bare minimum setup of options and resolve paths */ @@ -74,6 +75,7 @@ export function preset() { task('babel:postprocess', babel); task('generate-api', generateApi); task('type-check', typeCheck); + task('verify-packaging', verifyPackaging); task('ts:compile', () => { const moduleFlag = args.module; diff --git a/scripts/tasks/src/verify-packaging.ts b/scripts/tasks/src/verify-packaging.ts new file mode 100644 index 0000000000000..7802ebf6174c8 --- /dev/null +++ b/scripts/tasks/src/verify-packaging.ts @@ -0,0 +1,58 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; + +export function verifyPackaging() { + const cwd = process.cwd(); + const projectJSON: import('@nx/devkit').ProjectConfiguration = JSON.parse( + readFileSync(path.join(cwd, 'project.json'), 'utf-8'), + ); + const tags = projectJSON.tags ?? []; + + const result = spawnSync('npm', ['pack', '--dry-run']); + + const processedResult = result.output + .toString() + .replace(/\bnpm notice\b\s+[\d.]+[kB]+\s+/gi, '') + .replace(/[ ]+/g, ''); + + const isV8package = tags.indexOf('v8') !== -1; + const isV9package = tags.indexOf('vNext') !== -1; + + if (isV9package) { + assert.doesNotMatch(processedResult, /src\/[.a-z0-9/-_]+/i, `wont ship source code from "/src"`); + assert.doesNotMatch(processedResult, /config\/[.a-z0-9/-_]+/i, `wont ship config folder`); + assert.doesNotMatch(processedResult, /etc\/[.a-z0-9/-_]+/i, `wont ship etc folder`); + assert.doesNotMatch(processedResult, /just\.config\.[jt]s/i, `wont ship configuration files`); + } + + if (isV8package) { + assert.match(processedResult, /lib\/[.a-z0-9/-_]+(.d.ts)/i, 'ships dts'); + } + + assert.match(processedResult, /package\.json/, 'ships package.json'); + assert.match(processedResult, /README\.md/, 'ships README.md'); + assert.match(processedResult, /CHANGELOG\.md/, 'ships CHANGELOG.md'); + assert.match(processedResult, /dist\/[a-z-]+\.d\.ts/, 'ships rolluped dts'); + assert.match(processedResult, /lib-commonjs\/[.a-z0-9/-_]+(.js|.map)/i, 'ships cjs'); + assert.match(processedResult, /lib\/[.a-z0-9/-_]+(.js|.map)/i, 'ships esm'); + + assert.doesNotMatch(processedResult, /docs\/[.a-z0-9/-_]+/i, `wont ship docs folder`); + assert.doesNotMatch(processedResult, /temp\/[.a-z0-9/-_]+/i, `wont ship temp folder`); + assert.doesNotMatch(processedResult, /bundle-size\/[.a-z0-9/-_]+/i, `wont ship bundle-size fixtures`); + assert.doesNotMatch(processedResult, /.storybook\/[.a-z0-9/-_]+/i, `wont ship .storybook config`); + assert.doesNotMatch(processedResult, /stories\/[.a-z0-9/-_]+/i, `wont ship stories`); + assert.doesNotMatch(processedResult, /jest\.config\.js/i, `wont ship configuration files`); + assert.doesNotMatch(processedResult, /tsconfig[.a-z]*\.json/i, `wont ship configuration files`); + assert.doesNotMatch(processedResult, /project\.json/i, `wont ship configuration files`); + assert.doesNotMatch(processedResult, /\.eslintrc\.(json|js)/i, `wont ship configuration files`); + assert.doesNotMatch(processedResult, /\.babelrc\.json/i, `wont ship configuration files`); + assert.doesNotMatch(processedResult, /\.swcrc/i, `wont ship configuration files`); + + // @FIXME `amd` is created only on release pipeline where `--production` flag is used on build commands which triggers it + // we should enable this also on PR pipelines - need to verify time execution impact + // if (isV8package || tags.indexOf('ships-amd') !== -1) { + // assert.match(processedResult, /lib-amd\/[.a-z0-9/-_]+(.js|.map)/i, 'ships amd'); + // } +}