Support untagged releases (#19509)
Dan Abramov committed
Jul 31, 2020 at 20:47 UTC
a1c0864d19b16a76a0727934e59406e2d77bd6ee
5 files changed
+59
-10
scripts/release/README.md
+4
-1
@@ -87,6 +87,9 @@ Once this step is complete, you're ready to publish the release:
87
88
```sh
89
scripts/release/publish.js --tags latest
90
+
91
+# Or, if you want to bump "next" as well:
92
+scripts/release/publish.js --tags latest next
93
```
94
95
If the OTP code expires while publishing, re-run this command and answer "y" to the questions about whether it was expected for already published packages.
@@ -172,5 +175,5 @@ Upon completion, this script provides instructions for tagging the Git commit th
175
#### Example usage
176
To publish a release to NPM as both `next` and `latest`:
177
```sh
175
-scripts/release/publish.js --tags latest
178
+scripts/release/publish.js --tags latest next
179
```
scripts/release/publish-commands/confirm-version-and-tags.js
+2
-3
@@ -12,9 +12,8 @@ const run = async ({cwd, packages, tags}) => {
12
clear();
13
14
if (tags.length === 0) {
15
- console.log(
16
- theme`{spinnerSuccess ✓} You are about the publish the following packages without any tags:`
17
- );
15
+ console.error('Expected at least one tag.');
16
+ process.exit(1);
17
} else if (tags.length === 1) {
18
console.log(
19
theme`{spinnerSuccess ✓} You are about the publish the following packages under the tag {tag ${tags}}:`
scripts/release/publish-commands/parse-params.js
+14
-3
@@ -17,6 +17,7 @@ const paramDefinitions = [
17
type: String,
18
multiple: true,
19
description: 'NPM tags to point to the new release.',
20
+ defaultValue: ['untagged'],
21
},
22
{
23
name: 'skipPackages',
@@ -29,10 +30,20 @@ const paramDefinitions = [
30
31
module.exports = () => {
32
const params = commandLineArgs(paramDefinitions);
32
- if (!params.tags || !params.tags.length) {
33
- params.tags = [];
34
- }
33
splitCommaParams(params.skipPackages);
34
splitCommaParams(params.tags);
35
+ params.tags.forEach(tag => {
36
+ switch (tag) {
37
+ case 'latest':
38
+ case 'next':
39
+ case 'experimental':
40
+ case 'untagged':
41
+ break;
42
+ default:
43
+ console.error('Unknown tag: "' + params.tag + '"');
44
+ process.exit(1);
45
+ break;
46
+ }
47
+ });
48
return params;
49
};
scripts/release/publish-commands/publish-to-npm.js
+11
@@ -54,6 +54,17 @@ const run = async ({cwd, dry, packages, tags}, otp) => {
54
)
55
);
56
}
57
+
58
+ if (tags.includes('untagged')) {
59
+ // npm doesn't let us publish without a tag at all,
60
+ // so for one-off publishes we clean it up ourselves.
61
+ if (!dry) {
62
+ await exec(`npm dist-tag rm ${packageName}@untagged --otp=${otp}`);
63
+ }
64
+ console.log(
65
+ theme.command(`npm dist-tag rm ${packageName}@untagged --otp=${otp}`)
66
+ );
67
+ }
68
}
69
}
70
};
scripts/release/publish-commands/validate-tags.js
+28
-3
@@ -18,17 +18,42 @@ const run = async ({cwd, packages, tags}) => {
18
'package.json'
19
);
20
const {version} = await readJson(packageJSONPath);
21
+ const isExperimentalVersion = version.indexOf('experimental') !== -1;
22
if (version.indexOf('0.0.0') === 0) {
23
if (tags.includes('latest')) {
24
+ if (isExperimentalVersion) {
25
+ console.log(
26
+ theme`{error Experimental release} {version ${version}} {error cannot be tagged as} {tag latest}`
27
+ );
28
+ } else {
29
+ console.log(
30
+ theme`{error Next release} {version ${version}} {error cannot be tagged as} {tag latest}`
31
+ );
32
+ }
33
+ process.exit(1);
34
+ }
35
+ if (tags.includes('next') && isExperimentalVersion) {
36
+ console.log(
37
+ theme`{error Experimental release} {version ${version}} {error cannot be tagged as} {tag next}`
38
+ );
39
+ process.exit(1);
40
+ }
41
+ if (tags.includes('experimental') && !isExperimentalVersion) {
42
console.log(
24
- theme`{error Next release} {version ${version}} {error cannot be tagged as} {tag latest}`
43
+ theme`{error Next release} {version ${version}} {error cannot be tagged as} {tag experimental}`
44
);
45
process.exit(1);
46
}
47
} else {
29
- if (tags.includes('next')) {
48
+ if (!tags.includes('latest')) {
49
+ console.log(
50
+ theme`{error Stable release} {version ${version}} {error must always be tagged as} {tag latest}`
51
+ );
52
+ process.exit(1);
53
+ }
54
+ if (tags.includes('experimental')) {
55
console.log(
31
- theme`{error Stable release} {version ${version}} {error cannot be tagged as} {tag next}`
56
+ theme`{error Stable release} {version ${version}} {error cannot be tagged as} {tag experimental}`
57
);
58
process.exit(1);
59
}