@mui/internal-code-infra 0.1.1-canary.2 → 0.1.1-canary.21
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 +7 -4
- package/build/changelog/fetchChangelogs.d.mts +9 -10
- package/build/changelog/index.d.mts +1 -0
- package/build/cli/cmdBaseline.d.mts +18 -0
- package/build/cli/cmdNetlifyIgnore.d.mts +1 -1
- package/build/eslint/mui/rules/no-constructor-assigned-field.d.mts +50 -0
- package/build/eslint/packageJsonConfig.d.mts +7 -0
- package/build/remark/config.d.mts +5 -14
- package/build/utils/build.d.mts +14 -0
- package/build/utils/credentials.d.mts +2 -2
- package/build/utils/git.d.mts +30 -9
- package/build/utils/github.d.mts +8 -0
- package/build/utils/pnpm.d.mts +49 -0
- package/package.json +38 -35
- package/src/changelog/fetchChangelogs.mjs +66 -26
- package/src/changelog/index.mjs +3 -0
- package/src/cli/cmdBaseline.mjs +31 -0
- package/src/cli/cmdBuild.mjs +2 -0
- package/src/cli/cmdNetlifyIgnore.mjs +14 -7
- package/src/cli/cmdPublish.mjs +15 -0
- package/src/cli/cmdPublishNewPackage.mjs +6 -2
- package/src/cli/index.mjs +2 -0
- package/src/eslint/baseConfig.mjs +2 -0
- package/src/eslint/docsConfig.mjs +28 -10
- package/src/eslint/jsonConfig.mjs +2 -1
- package/src/eslint/mui/config.mjs +16 -1
- package/src/eslint/mui/index.mjs +2 -0
- package/src/eslint/mui/rules/no-constructor-assigned-field.mjs +183 -0
- package/src/eslint/packageJsonConfig.mjs +50 -0
- package/src/eslint/testConfig.mjs +1 -2
- package/src/remark/config.mjs +60 -13
- package/src/utils/build.mjs +34 -0
- package/src/utils/credentials.mjs +4 -3
- package/src/utils/extractErrorCodes.mjs +1 -3
- package/src/utils/git.mjs +107 -46
- package/src/utils/github.mjs +27 -0
- package/src/utils/pnpm.mjs +109 -0
- package/vale/styles/MUI/GoogleLatin.yml +5 -2
- package/vale/styles/MUI/CorrectRererenceCased.yml +0 -14
package/README.md
CHANGED
|
@@ -14,9 +14,9 @@ This is stored in the `docs` top-level directory.
|
|
|
14
14
|
|
|
15
15
|
1. Go to the publish action -
|
|
16
16
|
|
|
17
|
-
- [Base
|
|
17
|
+
- [Base UI](https://github.com/mui/base-ui/actions/workflows/publish.yml)
|
|
18
18
|
- [Core](https://github.com/mui/material-ui/actions/workflows/publish.yml)
|
|
19
|
-
- [MUI
|
|
19
|
+
- [MUI X](https://github.com/mui/mui-x/actions/workflows/publish.yml)
|
|
20
20
|
|
|
21
21
|
2. Choose "Run workflow" dropdown
|
|
22
22
|
|
|
@@ -24,12 +24,15 @@ This is stored in the `docs` top-level directory.
|
|
|
24
24
|
> - **Commit SHA to release from:** the commit that contains the merged release on master. This commit is linked to the GitHub release.
|
|
25
25
|
> - **Run in dry-run mode:** Used for debugging.
|
|
26
26
|
> - **Create GitHub release:** Keep selected if you want a GitHub release to be automatically created from the changelog.
|
|
27
|
-
> - **npm dist tag to publish to** Use to publish legacy or canary versions.
|
|
27
|
+
> - **npm dist tag to publish to** Use to publish legacy or canary versions. The publish fails before it publishes anything when a dist-tag would move to a lower version. `latest` and `latest-*` also cannot move to a prerelease unless they already point to one, and `latest-*` cannot change its major.
|
|
28
28
|
|
|
29
29
|
3. Click "Run workflow"
|
|
30
30
|
4. Refresh the page to see the newly created workflow, and click it.
|
|
31
31
|
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.**
|
|
32
32
|
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> A CI dry run (`code-infra publish --ci --dry-run`) runs the same dist-tag check. On a branch that does not publish to `latest`, pass the dist-tag of the release to it, for example `--tag next` for prereleases or `--tag latest-v8` for a previous major.
|
|
35
|
+
|
|
33
36
|
> [!IMPORTANT]
|
|
34
37
|
> 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.
|
|
35
38
|
|
|
@@ -59,7 +62,7 @@ If publishing fails with npm asking for `otp`, run the command again with 6 digi
|
|
|
59
62
|
pnpm code-infra publish-new-package --otp=123456
|
|
60
63
|
```
|
|
61
64
|
|
|
62
|
-
3. Go to the settings link for each package,
|
|
65
|
+
3. Go to the settings link for each package, for example, `https://www.npmjs.com/package/<pkg-name>/access`, and setup `Trusted Publisher`.
|
|
63
66
|
4. In the `Select your publisher` step in the above link, click on the `GitHub Actions` button to configure GitHub Actions-based trusted publishing.
|
|
64
67
|
5. Fill in the details of the repo -
|
|
65
68
|
1. `Organization or user` as `mui`,
|
|
@@ -8,6 +8,14 @@ export type FetchCommitsOptions = {
|
|
|
8
8
|
* - GitHub organization name, defaults to 'mui'
|
|
9
9
|
*/
|
|
10
10
|
org?: string;
|
|
11
|
+
/**
|
|
12
|
+
* - Called as commits are listed and their pull request details are fetched
|
|
13
|
+
*/
|
|
14
|
+
onProgress?: (progress: {
|
|
15
|
+
phase: string;
|
|
16
|
+
count: number;
|
|
17
|
+
total: number;
|
|
18
|
+
}) => void;
|
|
11
19
|
};
|
|
12
20
|
/**
|
|
13
21
|
* @typedef {import('@octokit/rest').Octokit} OctokitType
|
|
@@ -21,17 +29,8 @@ export type FetchCommitsOptions = {
|
|
|
21
29
|
* @property {string} lastRelease
|
|
22
30
|
* @property {string} release
|
|
23
31
|
* @property {string} [org='mui'] - GitHub organization name, defaults to 'mui'
|
|
32
|
+
* @property {(progress: { phase: string; count: number; total: number }) => void} [onProgress] - Called as commits are listed and their pull request details are fetched
|
|
24
33
|
*/
|
|
25
|
-
/**
|
|
26
|
-
* @param {Object} opts
|
|
27
|
-
* @param {string} opts.cwd
|
|
28
|
-
* @param {boolean} [opts.fetchAll=true] Whether to fetch all tags from all remotes before finding the latest tag.
|
|
29
|
-
* @returns {Promise<string>}
|
|
30
|
-
*/
|
|
31
|
-
export declare function findLatestTaggedVersion(opts: {
|
|
32
|
-
cwd: string;
|
|
33
|
-
fetchAll?: boolean;
|
|
34
|
-
}): Promise<string>;
|
|
35
34
|
/**
|
|
36
35
|
* Fetches commits between two refs (lastRelease..release) including PR details.
|
|
37
36
|
* Automatically handles GitHub OAuth authentication if none provided.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export type Args = {
|
|
3
|
+
/**
|
|
4
|
+
* - Branch pull requests fork from
|
|
5
|
+
*/
|
|
6
|
+
baseBranch?: string;
|
|
7
|
+
/**
|
|
8
|
+
* - Remote the base branch is fetched from
|
|
9
|
+
*/
|
|
10
|
+
remote?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} Args
|
|
14
|
+
* @property {string} [baseBranch] - Branch pull requests fork from
|
|
15
|
+
* @property {string} [remote] - Remote the base branch is fetched from
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
export type PropertyDefinition = import('@typescript-eslint/utils').TSESTree.PropertyDefinition;
|
|
3
|
+
export type Node = import('@typescript-eslint/utils').TSESTree.Node;
|
|
4
|
+
/**
|
|
5
|
+
* ESLint rule that disallows assigning a class field in the constructor when it is also
|
|
6
|
+
* declared as a (non-`declare`) class field.
|
|
7
|
+
*
|
|
8
|
+
* Babel 8 only strips TypeScript fields marked `declare` (see mui/material-ui#49241), so a
|
|
9
|
+
* field without an initializer is emitted as a property definition that sets it to
|
|
10
|
+
* `undefined` before the constructor assigns it again. Either initialize the field at its
|
|
11
|
+
* declaration, or mark it `declare` so it only serves as a type annotation.
|
|
12
|
+
*
|
|
13
|
+
* `declare` fields are exempt from TypeScript's strict property initialization check
|
|
14
|
+
* (TS2564), so prefer initializing at the declaration where the value doesn't depend on
|
|
15
|
+
* constructor arguments. The `declare` suggestion is only offered when every path through the
|
|
16
|
+
* constructor assigns the field, i.e. for an unconditional top-level assignment.
|
|
17
|
+
*
|
|
18
|
+
* Only plain `=` assignments count: compound assignments read the field rather than
|
|
19
|
+
* re-initialize it. A field with an initializer is only reported for an unconditional
|
|
20
|
+
* top-level assignment, as a conditional one overrides a default. Private (`#`) and decorated
|
|
21
|
+
* fields are ignored: they are runtime declarations that `declare` can't replace.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Invalid
|
|
25
|
+
* class ModalManager {
|
|
26
|
+
* private modals: Modal[];
|
|
27
|
+
* constructor() {
|
|
28
|
+
* this.modals = [];
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Valid - initialized at the declaration
|
|
34
|
+
* class ModalManager {
|
|
35
|
+
* private modals: Modal[] = [];
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Valid - declared only, assigned in the constructor
|
|
40
|
+
* class ModalManager {
|
|
41
|
+
* declare private modals: Modal[];
|
|
42
|
+
* constructor(modals: Modal[]) {
|
|
43
|
+
* this.modals = modals;
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
47
|
+
declare const _default: ESLintUtils.RuleModule<"addDeclare" | "assignedInConstructor", [], unknown, ESLintUtils.RuleListener> & {
|
|
48
|
+
name: string;
|
|
49
|
+
};
|
|
50
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lints package.json files for publishing metadata. Published packages must
|
|
3
|
+
* declare an SPDX license, `"author": "MUI Team"` and a repository pointing at
|
|
4
|
+
* their own directory. Private packages must not carry publishing metadata.
|
|
5
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
6
|
+
*/
|
|
7
|
+
export declare function createPackageJsonConfig(): import('eslint').Linter.Config[];
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import remarkGfm from 'remark-gfm';
|
|
2
|
-
import remarkLint from 'remark-lint';
|
|
3
1
|
/**
|
|
4
2
|
* Returns a remark preset wiring the MUI-authored remark-lint plugins together
|
|
5
3
|
* with a curated set of community plugins. Drop this into `.remarkrc.mjs`:
|
|
@@ -23,21 +21,14 @@ import remarkLint from 'remark-lint';
|
|
|
23
21
|
* ```
|
|
24
22
|
*
|
|
25
23
|
* @param {Object} [options]
|
|
24
|
+
* @param {boolean} [options.allowDefinitionComments=false] Allow titled `[//]` link-reference comments.
|
|
26
25
|
* @param {Array<{ files: string | string[], rules: Record<string, false | unknown[]> }>} [options.overrides]
|
|
26
|
+
* @returns {import('unified').Preset}
|
|
27
27
|
*/
|
|
28
|
-
export declare function createRemarkConfig({ overrides }?: {
|
|
28
|
+
export declare function createRemarkConfig({ overrides, allowDefinitionComments }?: {
|
|
29
|
+
allowDefinitionComments?: boolean;
|
|
29
30
|
overrides?: Array<{
|
|
30
31
|
files: string | string[];
|
|
31
32
|
rules: Record<string, false | unknown[]>;
|
|
32
33
|
}>;
|
|
33
|
-
}):
|
|
34
|
-
settings: {
|
|
35
|
-
bullet: string;
|
|
36
|
-
emphasis: string;
|
|
37
|
-
fence: string;
|
|
38
|
-
listItemIndent: string;
|
|
39
|
-
resourceLink: boolean;
|
|
40
|
-
rule: string;
|
|
41
|
-
};
|
|
42
|
-
plugins: (any[] | typeof remarkGfm | typeof remarkLint)[];
|
|
43
|
-
};
|
|
34
|
+
}): import('unified').Preset;
|
package/build/utils/build.d.mts
CHANGED
|
@@ -93,6 +93,20 @@ export declare function validatePkgJson(packageJson: Record<string, any>, option
|
|
|
93
93
|
skipMainCheck?: boolean;
|
|
94
94
|
enableReactCompiler?: boolean;
|
|
95
95
|
}): void;
|
|
96
|
+
/**
|
|
97
|
+
* Validates that "engines.node" in package.json doesn't allow Node.js versions older than the
|
|
98
|
+
* "node" browserslist environment, which the CommonJS bundle is compiled for. Otherwise the
|
|
99
|
+
* build can emit syntax that the oldest supported Node.js version can't run.
|
|
100
|
+
* Targets are resolved the same way `@babel/preset-env` resolves them during the build.
|
|
101
|
+
* @param {{ name?: string; engines?: { node?: string } }} packageJson
|
|
102
|
+
* @param {string} cwd - The package directory, used to find the browserslist config.
|
|
103
|
+
*/
|
|
104
|
+
export declare function validateEnginesNode(packageJson: {
|
|
105
|
+
name?: string;
|
|
106
|
+
engines?: {
|
|
107
|
+
node?: string;
|
|
108
|
+
};
|
|
109
|
+
}, cwd: string): void;
|
|
96
110
|
/**
|
|
97
111
|
* Marks the start and end of a function execution for performance measurement.
|
|
98
112
|
* Uses the Performance API to create marks and measure the duration.
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
export declare const KEYRING_SERVICE = "mui-code-infra";
|
|
9
9
|
/**
|
|
10
10
|
* @param {string} key
|
|
11
|
-
* @returns {Promise<string |
|
|
11
|
+
* @returns {Promise<string | null>}
|
|
12
12
|
*/
|
|
13
|
-
export declare function getPassword(key: string): Promise<string |
|
|
13
|
+
export declare function getPassword(key: string): Promise<string | null>;
|
|
14
14
|
/**
|
|
15
15
|
* @param {string} key
|
|
16
16
|
* @param {string} password
|
package/build/utils/git.d.mts
CHANGED
|
@@ -13,22 +13,18 @@ export type RepoInfo = {
|
|
|
13
13
|
remoteName: string;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @property {string} repo - Repository name
|
|
19
|
-
* @property {string} remoteName - Remote name
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* Get current repository info from git remote
|
|
16
|
+
* The canonical repository's remote, as opposed to a fork's: `upstream`, else `origin`, each only if
|
|
17
|
+
* it points at a mui repository. Reads the configured URLs, which `insteadOf` does not rewrite.
|
|
23
18
|
* @param {string} [cwd=process.cwd()]
|
|
24
|
-
* @returns {Promise<RepoInfo>}
|
|
19
|
+
* @returns {Promise<RepoInfo>}
|
|
25
20
|
*/
|
|
26
21
|
export declare function getRepositoryInfo(cwd?: string): Promise<RepoInfo>;
|
|
27
22
|
/**
|
|
28
23
|
* Get current git SHA
|
|
24
|
+
* @param {string} [cwd=process.cwd()]
|
|
29
25
|
* @returns {Promise<string>} Current git commit SHA
|
|
30
26
|
*/
|
|
31
|
-
export declare function getCurrentGitSha(): Promise<string>;
|
|
27
|
+
export declare function getCurrentGitSha(cwd?: string): Promise<string>;
|
|
32
28
|
/**
|
|
33
29
|
* Check whether a tag already exists on the origin remote
|
|
34
30
|
* @param {string} tagName - Tag name to check (e.g. `v1.2.3`)
|
|
@@ -36,3 +32,28 @@ export declare function getCurrentGitSha(): Promise<string>;
|
|
|
36
32
|
* @returns {Promise<boolean>} True if the tag exists on origin
|
|
37
33
|
*/
|
|
38
34
|
export declare function remoteGitTagExists(tagName: string, cwd?: string): Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* The commit HEAD should be compared against: where it forked from the base branch, or its parent
|
|
37
|
+
* when HEAD is already on the base branch.
|
|
38
|
+
* @param {Object} [options]
|
|
39
|
+
* @param {string} [options.cwd]
|
|
40
|
+
* @param {string} [options.remote] - Defaults to the canonical remote.
|
|
41
|
+
* @param {string} [options.baseBranch] - Defaults to the remote's default branch.
|
|
42
|
+
* @returns {Promise<string>}
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveBaseline(options?: {
|
|
45
|
+
cwd?: string;
|
|
46
|
+
remote?: string;
|
|
47
|
+
baseBranch?: string;
|
|
48
|
+
}): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* The most recent version tag reachable from HEAD — where a changelog's range starts.
|
|
51
|
+
* @param {Object} opts
|
|
52
|
+
* @param {string} opts.cwd
|
|
53
|
+
* @param {boolean} [opts.fetchAll=true] Whether to fetch all tags from all remotes before finding the latest tag.
|
|
54
|
+
* @returns {Promise<string>}
|
|
55
|
+
*/
|
|
56
|
+
export declare function findLatestTaggedVersion(opts: {
|
|
57
|
+
cwd: string;
|
|
58
|
+
fetchAll?: boolean;
|
|
59
|
+
}): Promise<string>;
|
package/build/utils/github.d.mts
CHANGED
|
@@ -47,3 +47,11 @@ export declare function endToEndGhAuthGetToken({ log }?: {
|
|
|
47
47
|
* @returns {Promise<void>}
|
|
48
48
|
*/
|
|
49
49
|
export declare function clearGitHubAuth(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Returns when a rate-limited request may be retried, or `null` for other errors.
|
|
52
|
+
* https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api#exceeding-the-rate-limit
|
|
53
|
+
*
|
|
54
|
+
* @param {unknown} error
|
|
55
|
+
* @returns {Date | null}
|
|
56
|
+
*/
|
|
57
|
+
export declare function getRateLimitRetryTime(error: unknown): Date | null;
|
package/build/utils/pnpm.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/** Version that `publish-new-package` publishes to reserve the name of a new package. */
|
|
3
|
+
export declare const PLACEHOLDER_VERSION = "0.0.1";
|
|
2
4
|
export type PrivatePackage = {
|
|
3
5
|
/**
|
|
4
6
|
* - Package name
|
|
@@ -134,6 +136,53 @@ export declare function getReleaseVersion(cwd?: string): Promise<string | null>;
|
|
|
134
136
|
* @returns {Promise<PublicPackage[]>} The subset needing a manual first publish
|
|
135
137
|
*/
|
|
136
138
|
export declare function getPackagesNeedingManualPublish(packages: PublicPackage[]): Promise<PublicPackage[]>;
|
|
139
|
+
export type RegistryPackage = {
|
|
140
|
+
/**
|
|
141
|
+
* - Dist-tags of the package
|
|
142
|
+
*/
|
|
143
|
+
distTags: Record<string, string>;
|
|
144
|
+
/**
|
|
145
|
+
* - Published versions of the package
|
|
146
|
+
*/
|
|
147
|
+
versions: string[];
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* @typedef {Object} RegistryPackage
|
|
151
|
+
* @property {Record<string, string>} distTags - Dist-tags of the package
|
|
152
|
+
* @property {string[]} versions - Published versions of the package
|
|
153
|
+
*/
|
|
154
|
+
/**
|
|
155
|
+
* Read the dist-tags and the published versions of each package with `pnpm view`, so
|
|
156
|
+
* the lookup uses the same registry configuration and credentials as `pnpm publish`.
|
|
157
|
+
*
|
|
158
|
+
* @param {PublicPackage[]} packages - Packages to read
|
|
159
|
+
* @returns {Promise<Map<string, RegistryPackage | null>>} By package name, null for a package that is not on the registry
|
|
160
|
+
*/
|
|
161
|
+
export declare function getRegistryPackages(packages: PublicPackage[]): Promise<Map<string, RegistryPackage | null>>;
|
|
162
|
+
export type DistTagConflict = {
|
|
163
|
+
/**
|
|
164
|
+
* - Package to publish
|
|
165
|
+
*/
|
|
166
|
+
pkg: PublicPackage;
|
|
167
|
+
/**
|
|
168
|
+
* - Why the dist-tag would move to the wrong release line
|
|
169
|
+
*/
|
|
170
|
+
reason: string;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* @typedef {Object} DistTagConflict
|
|
174
|
+
* @property {PublicPackage} pkg - Package to publish
|
|
175
|
+
* @property {string} reason - Why the dist-tag would move to the wrong release line
|
|
176
|
+
*/
|
|
177
|
+
/**
|
|
178
|
+
* Find the packages whose publish with `tag` would move the dist-tag to the wrong release line.
|
|
179
|
+
*
|
|
180
|
+
* @param {PublicPackage[]} packages - Packages to publish
|
|
181
|
+
* @param {string} tag - Dist-tag to publish with
|
|
182
|
+
* @param {Map<string, RegistryPackage | null>} registryPackages - Registry data from {@link getRegistryPackages}
|
|
183
|
+
* @returns {DistTagConflict[]}
|
|
184
|
+
*/
|
|
185
|
+
export declare function getDistTagConflicts(packages: PublicPackage[], tag: string, registryPackages: Map<string, RegistryPackage | null>): DistTagConflict[];
|
|
137
186
|
/**
|
|
138
187
|
* Get package version info from registry.
|
|
139
188
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/internal-code-infra",
|
|
3
|
-
"version": "0.1.1-canary.
|
|
3
|
+
"version": "0.1.1-canary.21",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "Infra scripts and configs to be used across MUI repos.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,42 +53,45 @@
|
|
|
53
53
|
"code-infra": "./bin/code-infra.mjs"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@argos-ci/core": "6.8.
|
|
57
|
-
"@babel/cli": "^8.0.
|
|
58
|
-
"@babel/core": "^8.0.
|
|
56
|
+
"@argos-ci/core": "6.8.8",
|
|
57
|
+
"@babel/cli": "^8.0.6",
|
|
58
|
+
"@babel/core": "^8.0.7",
|
|
59
|
+
"@babel/helper-compilation-targets": "^8.0.7",
|
|
59
60
|
"@babel/plugin-syntax-jsx": "^8.0.1",
|
|
60
|
-
"@babel/plugin-syntax-typescript": "^8.0.
|
|
61
|
+
"@babel/plugin-syntax-typescript": "^8.0.3",
|
|
61
62
|
"@babel/plugin-transform-react-pure-annotations": "^8.0.1",
|
|
62
|
-
"@babel/plugin-transform-runtime": "^8.0.
|
|
63
|
-
"@babel/preset-env": "^8.0.
|
|
63
|
+
"@babel/plugin-transform-runtime": "^8.0.6",
|
|
64
|
+
"@babel/preset-env": "^8.0.7",
|
|
64
65
|
"@babel/preset-react": "^8.0.1",
|
|
65
|
-
"@babel/preset-typescript": "^8.0.
|
|
66
|
+
"@babel/preset-typescript": "^8.0.7",
|
|
66
67
|
"@eslint/compat": "^2.1.1",
|
|
67
68
|
"@eslint/js": "^10.0.1",
|
|
68
|
-
"@eslint/json": "^2.1.
|
|
69
|
-
"@inquirer/confirm": "^6.3.
|
|
70
|
-
"@inquirer/select": "^5.2.
|
|
71
|
-
"@mui/internal-babel-plugin-display-name": "2.0.1-canary.
|
|
72
|
-
"@mui/internal-babel-plugin-minify-errors": "3.0.1-canary.
|
|
73
|
-
"@mui/internal-babel-plugin-resolve-imports": "3.0.1-canary.
|
|
74
|
-
"@napi-rs/keyring": "^2.
|
|
69
|
+
"@eslint/json": "^2.1.1",
|
|
70
|
+
"@inquirer/confirm": "^6.3.3",
|
|
71
|
+
"@inquirer/select": "^5.2.6",
|
|
72
|
+
"@mui/internal-babel-plugin-display-name": "2.0.1-canary.2",
|
|
73
|
+
"@mui/internal-babel-plugin-minify-errors": "3.0.1-canary.2",
|
|
74
|
+
"@mui/internal-babel-plugin-resolve-imports": "3.0.1-canary.3",
|
|
75
|
+
"@napi-rs/keyring": "^2.1.1",
|
|
75
76
|
"@octokit/auth-action": "^6.0.3",
|
|
76
77
|
"@octokit/oauth-methods": "^6.0.5",
|
|
78
|
+
"@octokit/plugin-retry": "^8.1.1",
|
|
79
|
+
"@octokit/plugin-throttling": "^11.0.5",
|
|
77
80
|
"@octokit/rest": "^22.0.1",
|
|
78
|
-
"@pnpm/config.version-policy": "^1100.2.
|
|
81
|
+
"@pnpm/config.version-policy": "^1100.2.8",
|
|
79
82
|
"@pnpm/find-workspace-dir": "^1000.1.5",
|
|
80
83
|
"@pnpm/parse-wanted-dependency": "^1001.0.0",
|
|
81
|
-
"@typescript-eslint/types": "^8.
|
|
82
|
-
"@typescript-eslint/utils": "^8.
|
|
84
|
+
"@typescript-eslint/types": "^8.71.2",
|
|
85
|
+
"@typescript-eslint/utils": "^8.71.2",
|
|
83
86
|
"@vitest/eslint-plugin": "^1.6.27",
|
|
84
87
|
"babel-plugin-optimize-clsx": "^2.6.2",
|
|
85
88
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
86
|
-
"babel-plugin-transform-import-meta": "^3.
|
|
89
|
+
"babel-plugin-transform-import-meta": "^3.1.0",
|
|
87
90
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
|
88
91
|
"babel-plugin-transform-remove-imports": "^1.8.1",
|
|
89
|
-
"chalk": "^6.0.
|
|
92
|
+
"chalk": "^6.0.1",
|
|
90
93
|
"clipboardy": "^5.3.2",
|
|
91
|
-
"content-type": "^3.1.
|
|
94
|
+
"content-type": "^3.1.1",
|
|
92
95
|
"env-ci": "^11.2.0",
|
|
93
96
|
"es-toolkit": "^1.52.0",
|
|
94
97
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -98,19 +101,20 @@
|
|
|
98
101
|
"eslint-plugin-import": "^2.32.0",
|
|
99
102
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
100
103
|
"eslint-plugin-mdx": "^3.8.1",
|
|
104
|
+
"eslint-plugin-package-json": "^1.10.1",
|
|
101
105
|
"eslint-plugin-react": "^7.37.5",
|
|
102
106
|
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
|
103
107
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
104
108
|
"eslint-plugin-testing-library": "^7.16.2",
|
|
105
|
-
"execa": "^10.
|
|
109
|
+
"execa": "^10.1.1",
|
|
106
110
|
"git-url-parse": "^16.1.0",
|
|
107
|
-
"globals": "^17.
|
|
111
|
+
"globals": "^17.13.0",
|
|
108
112
|
"globby": "^16.2.4",
|
|
109
|
-
"html-validate": "^11.
|
|
113
|
+
"html-validate": "^11.16.2",
|
|
110
114
|
"minimatch": "^10.2.6",
|
|
111
115
|
"node-html-parser": "^9.0.4",
|
|
112
|
-
"open": "^11.0.
|
|
113
|
-
"postcss-styled-syntax": "^0.7.
|
|
116
|
+
"open": "^11.0.4",
|
|
117
|
+
"postcss-styled-syntax": "^0.7.4",
|
|
114
118
|
"regexp.escape": "^2.0.1",
|
|
115
119
|
"rehype-slug": "^6.0.0",
|
|
116
120
|
"rehype-stringify": "^10.0.1",
|
|
@@ -133,12 +137,12 @@
|
|
|
133
137
|
"resolve-pkg-maps": "^1.0.0",
|
|
134
138
|
"semver": "^7.8.5",
|
|
135
139
|
"stylelint-config-standard": "^40.0.0",
|
|
136
|
-
"typescript-eslint": "^8.
|
|
140
|
+
"typescript-eslint": "^8.71.2",
|
|
137
141
|
"unified": "^11.0.5",
|
|
138
142
|
"unified-lint-rule": "^3.0.1",
|
|
139
143
|
"unist-util-visit": "^5.1.0",
|
|
140
144
|
"yaml": "^2.9.1",
|
|
141
|
-
"yargs": "^18.
|
|
145
|
+
"yargs": "^18.2.0"
|
|
142
146
|
},
|
|
143
147
|
"peerDependencies": {
|
|
144
148
|
"@next/eslint-plugin-next": "*",
|
|
@@ -162,17 +166,16 @@
|
|
|
162
166
|
"@types/mdast": "4.0.4",
|
|
163
167
|
"@types/regexp.escape": "2.0.0",
|
|
164
168
|
"@types/yargs": "17.0.35",
|
|
165
|
-
"@typescript-eslint/parser": "8.
|
|
166
|
-
"@typescript-eslint/rule-tester": "8.
|
|
169
|
+
"@typescript-eslint/parser": "8.71.2",
|
|
170
|
+
"@typescript-eslint/rule-tester": "8.71.2",
|
|
167
171
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
168
|
-
"eslint": "10.
|
|
172
|
+
"eslint": "10.12.0",
|
|
169
173
|
"get-port": "7.2.0",
|
|
170
|
-
"prettier": "3.9.
|
|
174
|
+
"prettier": "3.9.10",
|
|
171
175
|
"remark": "15.0.1",
|
|
172
176
|
"remark-mdx": "3.1.1",
|
|
173
177
|
"serve": "14.2.6",
|
|
174
|
-
"typescript": "npm:@typescript/typescript6@6.0.2"
|
|
175
|
-
"typescript-eslint": "8.70.0"
|
|
178
|
+
"typescript": "npm:@typescript/typescript6@6.0.2"
|
|
176
179
|
},
|
|
177
180
|
"files": [
|
|
178
181
|
"bin",
|
|
@@ -187,7 +190,7 @@
|
|
|
187
190
|
"publishConfig": {
|
|
188
191
|
"access": "public"
|
|
189
192
|
},
|
|
190
|
-
"gitSha": "
|
|
193
|
+
"gitSha": "e8aec3f286672d4639af7b385ef313c3d8ec74f3",
|
|
191
194
|
"scripts": {
|
|
192
195
|
"build": "tsc -p tsconfig.build.json",
|
|
193
196
|
"typescript": "tsc -noEmit",
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
import { retry } from '@octokit/plugin-retry';
|
|
2
|
+
import { throttling } from '@octokit/plugin-throttling';
|
|
1
3
|
import { Octokit } from '@octokit/rest';
|
|
2
|
-
import {
|
|
4
|
+
import { mapAsync } from 'es-toolkit/array';
|
|
3
5
|
|
|
4
|
-
import { getRepositoryInfo } from '../utils/git.mjs';
|
|
5
6
|
import { persistentAuthStrategy } from '../utils/github.mjs';
|
|
6
7
|
|
|
8
|
+
const ThrottledOctokit = Octokit.plugin(throttling, retry);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Waits out short rate limits. Longer ones fail with the original error.
|
|
12
|
+
*
|
|
13
|
+
* @param {number} retryAfter - Seconds until the request may be retried
|
|
14
|
+
* @param {unknown} options
|
|
15
|
+
* @param {unknown} octokit
|
|
16
|
+
* @param {number} retryCount
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
19
|
+
function shouldRetryRateLimit(retryAfter, options, octokit, retryCount) {
|
|
20
|
+
return retryAfter <= 60 && retryCount < 3;
|
|
21
|
+
}
|
|
22
|
+
|
|
7
23
|
/**
|
|
8
24
|
* @typedef {import('@octokit/rest').Octokit} OctokitType
|
|
9
25
|
*/
|
|
@@ -18,27 +34,9 @@ import { persistentAuthStrategy } from '../utils/github.mjs';
|
|
|
18
34
|
* @property {string} lastRelease
|
|
19
35
|
* @property {string} release
|
|
20
36
|
* @property {string} [org='mui'] - GitHub organization name, defaults to 'mui'
|
|
37
|
+
* @property {(progress: { phase: string; count: number; total: number }) => void} [onProgress] - Called as commits are listed and their pull request details are fetched
|
|
21
38
|
*/
|
|
22
39
|
|
|
23
|
-
/**
|
|
24
|
-
* @param {Object} opts
|
|
25
|
-
* @param {string} opts.cwd
|
|
26
|
-
* @param {boolean} [opts.fetchAll=true] Whether to fetch all tags from all remotes before finding the latest tag.
|
|
27
|
-
* @returns {Promise<string>}
|
|
28
|
-
*/
|
|
29
|
-
export async function findLatestTaggedVersion(opts) {
|
|
30
|
-
const $$ = $({ cwd: opts.cwd });
|
|
31
|
-
const fetchAll = opts.fetchAll ?? true;
|
|
32
|
-
if (fetchAll) {
|
|
33
|
-
const { remoteName } = await getRepositoryInfo();
|
|
34
|
-
// Fetch all tags from the mui remote to ensure we have the latest tags.
|
|
35
|
-
// --force to update any existing tags that may have changed to avoid the clobering error.
|
|
36
|
-
await $$`git fetch --tags --force ${remoteName}`;
|
|
37
|
-
}
|
|
38
|
-
const { stdout } = await $$`git describe --tags --abbrev=0 --match ${'v*'}`; // only include "version-tags"
|
|
39
|
-
return stdout.trim();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
40
|
/**
|
|
43
41
|
* Fetches commits between two refs (lastRelease..release) including PR details.
|
|
44
42
|
* Automatically handles GitHub OAuth authentication if none provided.
|
|
@@ -50,7 +48,13 @@ export async function fetchCommitsBetweenRefs(opts) {
|
|
|
50
48
|
const octokit =
|
|
51
49
|
'octokit' in opts && opts.octokit
|
|
52
50
|
? opts.octokit
|
|
53
|
-
: new
|
|
51
|
+
: new ThrottledOctokit({
|
|
52
|
+
authStrategy: persistentAuthStrategy,
|
|
53
|
+
throttle: {
|
|
54
|
+
onRateLimit: shouldRetryRateLimit,
|
|
55
|
+
onSecondaryRateLimit: shouldRetryRateLimit,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
54
58
|
|
|
55
59
|
return fetchCommitsRest({
|
|
56
60
|
octokit,
|
|
@@ -58,6 +62,7 @@ export async function fetchCommitsBetweenRefs(opts) {
|
|
|
58
62
|
lastRelease: opts.lastRelease,
|
|
59
63
|
release: opts.release,
|
|
60
64
|
org: opts.org ?? 'mui',
|
|
65
|
+
onProgress: opts.onProgress,
|
|
61
66
|
});
|
|
62
67
|
}
|
|
63
68
|
|
|
@@ -70,7 +75,7 @@ export async function fetchCommitsBetweenRefs(opts) {
|
|
|
70
75
|
*
|
|
71
76
|
* @returns {Promise<FetchedCommitDetails[]>}
|
|
72
77
|
*/
|
|
73
|
-
async function fetchCommitsRest({ octokit, repo, lastRelease, release, org = 'mui' }) {
|
|
78
|
+
async function fetchCommitsRest({ octokit, repo, lastRelease, release, org = 'mui', onProgress }) {
|
|
74
79
|
/**
|
|
75
80
|
* @typedef {Awaited<ReturnType<Octokit['repos']['compareCommits']>>['data']['commits']} Commits
|
|
76
81
|
*/
|
|
@@ -90,9 +95,19 @@ async function fetchCommitsRest({ octokit, repo, lastRelease, release, org = 'mu
|
|
|
90
95
|
);
|
|
91
96
|
for await (const response of timeline) {
|
|
92
97
|
results.push(...response.data.commits);
|
|
98
|
+
onProgress?.({
|
|
99
|
+
phase: 'Listing commits',
|
|
100
|
+
count: results.length,
|
|
101
|
+
total: response.data.total_commits,
|
|
102
|
+
});
|
|
93
103
|
}
|
|
94
104
|
|
|
95
|
-
|
|
105
|
+
/**
|
|
106
|
+
* @param {Commits[number]} commit
|
|
107
|
+
* @param {AbortSignal} signal
|
|
108
|
+
* @returns {Promise<FetchedCommitDetails | null>}
|
|
109
|
+
*/
|
|
110
|
+
const fetchCommitDetails = async (commit, signal) => {
|
|
96
111
|
const matches = [...commit.commit.message.matchAll(/#(\d+)/g)];
|
|
97
112
|
// The PR number is always the last match.
|
|
98
113
|
// Sometimes the PR titles include an issue number like this:
|
|
@@ -111,6 +126,7 @@ async function fetchCommitsRest({ octokit, repo, lastRelease, release, org = 'mu
|
|
|
111
126
|
headers: {
|
|
112
127
|
Accept: 'application/vnd.github.text+json',
|
|
113
128
|
},
|
|
129
|
+
request: { signal },
|
|
114
130
|
});
|
|
115
131
|
|
|
116
132
|
const labels = pr.data.labels.map((label) => label.name);
|
|
@@ -132,9 +148,33 @@ async function fetchCommitsRest({ octokit, repo, lastRelease, release, org = 'mu
|
|
|
132
148
|
prTitle: pr.data.title,
|
|
133
149
|
prBody: pr.data.body,
|
|
134
150
|
});
|
|
135
|
-
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// `mapAsync` rejects on the first error but still runs every queued callback.
|
|
154
|
+
// Aborted once it settles, which cancels requests in flight and skips the ones not started yet.
|
|
155
|
+
const controller = new AbortController();
|
|
136
156
|
|
|
137
|
-
|
|
157
|
+
let fetched = 0;
|
|
158
|
+
try {
|
|
159
|
+
const commits = await mapAsync(
|
|
160
|
+
results,
|
|
161
|
+
async (commit) => {
|
|
162
|
+
if (controller.signal.aborted) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
const details = await fetchCommitDetails(commit, controller.signal);
|
|
166
|
+
if (!controller.signal.aborted) {
|
|
167
|
+
fetched += 1;
|
|
168
|
+
onProgress?.({ phase: 'Fetching pull requests', count: fetched, total: results.length });
|
|
169
|
+
}
|
|
170
|
+
return details;
|
|
171
|
+
},
|
|
172
|
+
{ concurrency: 10 },
|
|
173
|
+
);
|
|
174
|
+
return commits.filter((entry) => entry !== null);
|
|
175
|
+
} finally {
|
|
176
|
+
controller.abort();
|
|
177
|
+
}
|
|
138
178
|
}
|
|
139
179
|
|
|
140
180
|
/**
|