@mui/internal-code-infra 0.0.3-canary.21 → 0.0.3-canary.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/package.json +4 -3
- package/src/cli/cmdArgosPush.mjs +13 -2
- package/src/cli/cmdPublish.mjs +10 -0
- package/src/cli/cmdPublishNewPackage.mjs +86 -0
- package/src/cli/index.mjs +2 -0
- package/src/cli/pnpm.mjs +19 -1
package/README.md
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
1
|
# @mui/internal-code-infra
|
|
2
2
|
|
|
3
3
|
Scripts and configs to be used across MUI repos.
|
|
4
|
+
|
|
5
|
+
## Publishing packages
|
|
6
|
+
|
|
7
|
+
1. Go to the publish action -
|
|
8
|
+
|
|
9
|
+
- [Base UI](https://github.com/mui/base-ui/actions/workflows/publish.yml)
|
|
10
|
+
- [Core](https://github.com/mui/material-ui/actions/workflows/publish.yml)
|
|
11
|
+
- [MUI X](https://github.com/mui/mui-x/actions/workflows/publish.yml)
|
|
12
|
+
|
|
13
|
+
2. Choose "Run workflow" dropdown
|
|
14
|
+
|
|
15
|
+
> - **Branch:** master
|
|
16
|
+
> - **Commit SHA to release from:** the commit that contains the merged release on master. This commit is linked to the GitHub release.
|
|
17
|
+
> - **Run in dry-run mode:** Used for debugging.
|
|
18
|
+
> - **Create GitHub release:** Keep selected if you want a GitHub release to be automatically created from the changelog.
|
|
19
|
+
> - **npm dist tag to publish to** Use to publish legacy or canary versions.
|
|
20
|
+
|
|
21
|
+
3. Click "Run workflow"
|
|
22
|
+
4. Refresh the page to see the newly created workflow, and click it.
|
|
23
|
+
5. The next screen shows "@username requested your review to deploy to npm-publish", click "Review deployments" and authorize your workflow run. **Never approve workflow runs you didn't initiaite.**
|
|
24
|
+
|
|
25
|
+
> [!IMPORTANT]
|
|
26
|
+
> Go through the below steps if there is an error that says `The following packages are new and need to be published manually first` in the publish flow.
|
|
27
|
+
|
|
28
|
+
### Adding and publishing new packages
|
|
29
|
+
|
|
30
|
+
Whenever news packages are added to the repo (that will get published to npm) or a private package is turned into a public one, follow the below steps before invoking the publish workflow of the previous section.
|
|
31
|
+
|
|
32
|
+
1. Goto your repo's code base on your system, open terminal and run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm code-infra publish-new-package
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This command detects the new public packages in the repo and asks for your confirmation before publishing them to the npm registry. Add the `--dryRun` flag to skip the actual publishing.
|
|
39
|
+
|
|
40
|
+
2. Goto the settings link for each packages, ie, https://www.npmjs.com/package/<pkg-name>/access , and setup `Trusted Publisher`.
|
|
41
|
+
3. In `Select your publisher` step in the above link, click on the `Github Actions` button to configure Github actions based trusted publishing.
|
|
42
|
+
4. Fill in the details of the repo -
|
|
43
|
+
1. `Organization or user` as `mui`,
|
|
44
|
+
2. `Repository` as per the new package
|
|
45
|
+
3. `Workflow filename*` should be `publish.yml`
|
|
46
|
+
4. `Environment name` should be `npm-publish`
|
|
47
|
+
5. In the `Publishing access` section, toggle the recommended option of `Require two-factor authentication and disallow tokens`.
|
|
48
|
+
6. Finally, save the changes by clicking on `Update Package Settings` button.
|
|
49
|
+
|
|
50
|
+
After following these steps, the `Publish` workflow can be invoked again.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/internal-code-infra",
|
|
3
|
-
"version": "0.0.3-canary.
|
|
3
|
+
"version": "0.0.3-canary.23",
|
|
4
4
|
"description": "Infra scripts and configs to be used across MUI repos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@babel/preset-typescript": "^7.27.1",
|
|
34
34
|
"@eslint/compat": "^1.4.0",
|
|
35
35
|
"@eslint/js": "^9.36.0",
|
|
36
|
+
"@inquirer/confirm": "^5.1.18",
|
|
36
37
|
"@next/eslint-plugin-next": "^15.5.4",
|
|
37
38
|
"@octokit/auth-action": "^6.0.1",
|
|
38
39
|
"@octokit/rest": "^22.0.0",
|
|
@@ -64,8 +65,8 @@
|
|
|
64
65
|
"stylelint-config-standard": "^39.0.0",
|
|
65
66
|
"typescript-eslint": "^8.45.0",
|
|
66
67
|
"yargs": "^18.0.0",
|
|
67
|
-
"@mui/internal-babel-plugin-resolve-imports": "2.0.7-canary.23",
|
|
68
68
|
"@mui/internal-babel-plugin-display-name": "1.0.4-canary.7",
|
|
69
|
+
"@mui/internal-babel-plugin-resolve-imports": "2.0.7-canary.23",
|
|
69
70
|
"@mui/internal-babel-plugin-minify-errors": "2.0.8-canary.10"
|
|
70
71
|
},
|
|
71
72
|
"peerDependencies": {
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
"publishConfig": {
|
|
98
99
|
"access": "public"
|
|
99
100
|
},
|
|
100
|
-
"gitSha": "
|
|
101
|
+
"gitSha": "d9d08c1e6632b905ea3cd3bc91b33493efa7ccc1",
|
|
101
102
|
"scripts": {
|
|
102
103
|
"typescript": "tsc -p tsconfig.json",
|
|
103
104
|
"test": "pnpm -w test --project @mui/internal-code-infra",
|
package/src/cli/cmdArgosPush.mjs
CHANGED
|
@@ -63,8 +63,11 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
|
|
|
63
63
|
const screenshots = await globby(`${folder}/**/*`, {
|
|
64
64
|
onlyFiles: true,
|
|
65
65
|
});
|
|
66
|
+
const threshold = process.env.ARGOS_THRESHOLD ? parseFloat(process.env.ARGOS_THRESHOLD) : 0.5;
|
|
66
67
|
|
|
67
|
-
console.log(
|
|
68
|
+
console.log(
|
|
69
|
+
`Found ${screenshots.length} screenshots. Uploading with threshold ${threshold}.`,
|
|
70
|
+
);
|
|
68
71
|
if (verbose) {
|
|
69
72
|
console.log('Screenshots found:');
|
|
70
73
|
screenshots.forEach((screenshot) => {
|
|
@@ -99,14 +102,22 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
|
|
|
99
102
|
commit: circleSha1,
|
|
100
103
|
branch: circleBranch,
|
|
101
104
|
token: argosToken,
|
|
105
|
+
threshold,
|
|
102
106
|
parallel: {
|
|
103
107
|
total: batches.length,
|
|
104
108
|
nonce: circleBuildNum,
|
|
105
109
|
},
|
|
106
110
|
});
|
|
107
111
|
|
|
112
|
+
if (verbose) {
|
|
113
|
+
console.log('Screenshots uploaded:');
|
|
114
|
+
for (const screenshot of result.screenshots) {
|
|
115
|
+
console.log(`- ${screenshot.name}. Threshold: ${screenshot.threshold}.`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
console.log(
|
|
109
|
-
`Batch of ${batches[i].length} screenshots uploaded. Build URL: ${result.build.url}`,
|
|
120
|
+
`Batch of ${batches[i].length} screenshots uploaded. Threshold: ${threshold}. Build URL: ${result.build.url}`,
|
|
110
121
|
);
|
|
111
122
|
}
|
|
112
123
|
} finally {
|
package/src/cli/cmdPublish.mjs
CHANGED
|
@@ -307,6 +307,16 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
|
|
|
307
307
|
githubReleaseData = await validateGitHubRelease(version);
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
+
const newPackages = await getWorkspacePackages({ nonPublishedOnly: true });
|
|
311
|
+
|
|
312
|
+
if (newPackages.length > 0) {
|
|
313
|
+
throw new Error(
|
|
314
|
+
`The following packages are new and need to be published manually first: ${newPackages.join(
|
|
315
|
+
', ',
|
|
316
|
+
)}. Read more about it here: https://github.com/mui/mui-public/blob/master/packages/code-infra/README.md#adding-and-publishing-new-packages`,
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
310
320
|
// Publish to npm (pnpm handles duplicate checking automatically)
|
|
311
321
|
// No git checks, we'll do our own
|
|
312
322
|
await publishToNpm(allPackages, { dryRun, noGitChecks: true, tag });
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
import confirm from '@inquirer/confirm';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { $ } from 'execa';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
|
|
10
|
+
import { getWorkspacePackages } from './pnpm.mjs';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} Args
|
|
14
|
+
* @property {boolean} [dryRun] If true, will only log the commands without executing them
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
|
|
18
|
+
command: 'publish-new-package [pkg...]',
|
|
19
|
+
describe: 'Publish new empty package(s) to the npm registry.',
|
|
20
|
+
builder: (yargs) =>
|
|
21
|
+
yargs.option('dryRun', {
|
|
22
|
+
type: 'boolean',
|
|
23
|
+
default: false,
|
|
24
|
+
description: 'If true, will only log the commands without executing them.',
|
|
25
|
+
}),
|
|
26
|
+
async handler(args) {
|
|
27
|
+
console.log(`🔍 Detecting new packages to publish in workspace...`);
|
|
28
|
+
const newPackages = await getWorkspacePackages({ nonPublishedOnly: true });
|
|
29
|
+
|
|
30
|
+
if (!newPackages.length) {
|
|
31
|
+
console.log('No new packages to publish.');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log(`Found ${newPackages.map((pkg) => pkg.name).join(', ')} to publish.`);
|
|
36
|
+
|
|
37
|
+
const answer = await confirm({
|
|
38
|
+
message: `Do you want to publish ${newPackages.length} new package(s) to the npm registry?`,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!answer) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
await Promise.all(
|
|
46
|
+
newPackages.map(async (pkg) => {
|
|
47
|
+
const newPkgDir = await fs.mkdtemp(path.join(os.tmpdir(), 'publish-new-package-'));
|
|
48
|
+
try {
|
|
49
|
+
await fs.mkdir(newPkgDir, { recursive: true });
|
|
50
|
+
const packageJson = {
|
|
51
|
+
name: pkg.name,
|
|
52
|
+
version: '0.0.1',
|
|
53
|
+
};
|
|
54
|
+
await fs.writeFile(
|
|
55
|
+
path.join(newPkgDir, 'package.json'),
|
|
56
|
+
`${JSON.stringify(packageJson, null, 2)}\n`,
|
|
57
|
+
);
|
|
58
|
+
/**
|
|
59
|
+
* @type {string[]}
|
|
60
|
+
*/
|
|
61
|
+
const publishArgs = [];
|
|
62
|
+
|
|
63
|
+
if (args.dryRun) {
|
|
64
|
+
publishArgs.push('--dry-run');
|
|
65
|
+
}
|
|
66
|
+
await $({
|
|
67
|
+
cwd: newPkgDir,
|
|
68
|
+
})`npm publish --access public --tag=canary ${publishArgs}`;
|
|
69
|
+
console.log(
|
|
70
|
+
`✅ ${args.dryRun ? '[Dry run] ' : ''}Published ${chalk.bold(`${pkg.name}@${packageJson.version}`)} to npm registry.`,
|
|
71
|
+
);
|
|
72
|
+
} finally {
|
|
73
|
+
await fs.rm(newPkgDir, { recursive: true, force: true });
|
|
74
|
+
}
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const trustedPublisherLinks = newPackages
|
|
79
|
+
.map((pkg) => `https://www.npmjs.com/package/${pkg.name}/access`)
|
|
80
|
+
.join('\n');
|
|
81
|
+
console.log(`
|
|
82
|
+
📝 Please ensure that the ${chalk.underline(chalk.bold('Trusted Publishers'))} settings are configured for the new packages:
|
|
83
|
+
${trustedPublisherLinks}
|
|
84
|
+
Read how to do that here - https://github.com/mui/mui-public/blob/master/packages/code-infra/README.md#adding-and-publishing-new-packages`);
|
|
85
|
+
},
|
|
86
|
+
});
|
package/src/cli/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import cmdJsonLint from './cmdJsonLint.mjs';
|
|
|
10
10
|
import cmdListWorkspaces from './cmdListWorkspaces.mjs';
|
|
11
11
|
import cmdPublish from './cmdPublish.mjs';
|
|
12
12
|
import cmdPublishCanary from './cmdPublishCanary.mjs';
|
|
13
|
+
import cmdPublishNewPackage from './cmdPublishNewPackage.mjs';
|
|
13
14
|
import cmdSetVersionOverrides from './cmdSetVersionOverrides.mjs';
|
|
14
15
|
|
|
15
16
|
const pkgJson = createRequire(import.meta.url)('../../package.json');
|
|
@@ -25,6 +26,7 @@ yargs()
|
|
|
25
26
|
.command(cmdListWorkspaces)
|
|
26
27
|
.command(cmdPublish)
|
|
27
28
|
.command(cmdPublishCanary)
|
|
29
|
+
.command(cmdPublishNewPackage)
|
|
28
30
|
.command(cmdSetVersionOverrides)
|
|
29
31
|
.demandCommand(1, 'You need at least one command before moving on')
|
|
30
32
|
.strict()
|
package/src/cli/pnpm.mjs
CHANGED
|
@@ -46,6 +46,7 @@ import * as semver from 'semver';
|
|
|
46
46
|
* @typedef {Object} GetWorkspacePackagesOptions
|
|
47
47
|
* @property {string|null} [sinceRef] - Git reference to filter changes since
|
|
48
48
|
* @property {boolean} [publicOnly=false] - Whether to filter to only public packages
|
|
49
|
+
* @property {boolean} [nonPublishedOnly=false] - Whether to filter to only non-published packages. It by default means public packages yet to be published.
|
|
49
50
|
*/
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -56,6 +57,10 @@ import * as semver from 'semver';
|
|
|
56
57
|
* @returns {Promise<PublicPackage[]>} Array of packages
|
|
57
58
|
*
|
|
58
59
|
* @overload
|
|
60
|
+
* @param {{ nonPublishedOnly: true } & GetWorkspacePackagesOptions} [options={}] - Options for filtering packages
|
|
61
|
+
* @returns {Promise<PublicPackage[]>} Array of packages
|
|
62
|
+
*
|
|
63
|
+
* @overload
|
|
59
64
|
* @param {{ publicOnly?: false | undefined } & GetWorkspacePackagesOptions} [options={}] - Options for filtering packages
|
|
60
65
|
* @returns {Promise<PrivatePackage[]>} Array of packages
|
|
61
66
|
*
|
|
@@ -67,7 +72,7 @@ import * as semver from 'semver';
|
|
|
67
72
|
* @returns {Promise<(PrivatePackage | PublicPackage)[]>} Array of packages
|
|
68
73
|
*/
|
|
69
74
|
export async function getWorkspacePackages(options = {}) {
|
|
70
|
-
const { sinceRef = null, publicOnly = false } = options;
|
|
75
|
+
const { sinceRef = null, publicOnly = false, nonPublishedOnly = false } = options;
|
|
71
76
|
|
|
72
77
|
// Build command with conditional filter
|
|
73
78
|
const filterArg = sinceRef ? ['--filter', `...[${sinceRef}]`] : [];
|
|
@@ -91,6 +96,19 @@ export async function getWorkspacePackages(options = {}) {
|
|
|
91
96
|
];
|
|
92
97
|
});
|
|
93
98
|
|
|
99
|
+
if (nonPublishedOnly) {
|
|
100
|
+
// Check if any of the packages are new/need manual publishing first.
|
|
101
|
+
const filteredPublicPackages = filteredPackages.filter((pkg) => !pkg.isPrivate);
|
|
102
|
+
|
|
103
|
+
const results = await Promise.all(
|
|
104
|
+
filteredPublicPackages.map(async (pkg) => {
|
|
105
|
+
const url = `${process.env.npm_config_registry || 'https://registry.npmjs.org'}/${pkg.name}`;
|
|
106
|
+
return fetch(url).then((res) => res.status === 404);
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
return filteredPublicPackages.filter((_pkg, index) => !!results[index]);
|
|
110
|
+
}
|
|
111
|
+
|
|
94
112
|
return filteredPackages;
|
|
95
113
|
}
|
|
96
114
|
|