Skip to content

Commit fbf5985

Browse files
aduthtyxla
andauthored
Packages: Add support for publishing stable release of pre-release package (#74332)
* Packages: Add support for publishing stable release of pre-release package * Add code syntax highlighting for version specifiers Co-authored-by: Marin Atanasov <[email protected]> * Add test case for no effect on stable versions * TypeScript-ify common bin script * Revert "TypeScript-ify common bin script" This reverts commit 96dbb11. --------- Co-authored-by: Marin Atanasov <[email protected]> Co-authored-by: aduth <[email protected]> Co-authored-by: tyxla <[email protected]>
1 parent a5f842a commit fbf5985

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

bin/plugin/commands/common.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ function calculateVersionBumpFromChangelog(
6565
break;
6666
}
6767

68+
// Promote a pre-1.0 package to stable 1.0.0 release. Stop processing.
69+
if (
70+
lineNormalized.startsWith( '### stable release' ) &&
71+
semver.lt( currentVersion, '1.0.0' )
72+
) {
73+
versionBump = 'major';
74+
break;
75+
}
76+
6877
// A major version bump required for stable packages. Stop processing.
6978
if ( lineNormalized.startsWith( '### breaking change' ) ) {
7079
if ( semver.lt( currentVersion, '1.0.0' ) ) {

bin/plugin/commands/test/common.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ describe( 'calculateVersionBumpFromChangelog', () => {
7171
).toBe( 'major' );
7272
} );
7373

74+
it( 'should have no effect to use stable release heading on stable package', () => {
75+
expect(
76+
calculateVersionBumpFromChangelog(
77+
[
78+
'First line',
79+
'## Unreleased',
80+
'### Stable Release',
81+
'This package is now considered stable.',
82+
'Fifth line',
83+
],
84+
'patch',
85+
'1.0.0'
86+
)
87+
).toBe( 'patch' );
88+
} );
89+
7490
describe( 'prerelease versions', () => {
7591
it( 'should not bump the major even if breaking changes detected', () => {
7692
expect(
@@ -87,5 +103,21 @@ describe( 'calculateVersionBumpFromChangelog', () => {
87103
)
88104
).toBe( 'minor' );
89105
} );
106+
107+
it( 'should bump the major when stable release heading detected', () => {
108+
expect(
109+
calculateVersionBumpFromChangelog(
110+
[
111+
'First line',
112+
'## Unreleased',
113+
'### Stable Release',
114+
'This package is now considered stable.',
115+
'Fifth line',
116+
],
117+
'patch',
118+
'0.1.0'
119+
)
120+
).toBe( 'major' );
121+
} );
90122
} );
91123
} );

packages/README.md

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@ Packages are the first layer of architecture and organization in Gutenberg. They
88

99
1. **Each package should have a single, clear purpose.**
1010

11-
It should be immediately obvious why the package exists.
11+
It should be immediately obvious why the package exists.
1212

1313
2. **Every package must include a README.**
1414

15-
This is the first place contributors look to understand scope and usage.
15+
This is the first place contributors look to understand scope and usage.
1616

1717
3. **Any prerequisites must be documented.**
1818

19-
Generic packages without prerequisites are better, but packages with some prerequisites are acceptable. Examples of prerequisites: API endpoints that must exist, authentication assumptions, environment dependencies. These should be clearly stated in the README.
19+
Generic packages without prerequisites are better, but packages with some prerequisites are acceptable. Examples of prerequisites: API endpoints that must exist, authentication assumptions, environment dependencies. These should be clearly stated in the README.
2020

2121
4. **Public APIs should have documentation.**
2222

23-
Either inline in the README or linked to external docs.
23+
Either inline in the README or linked to external docs.
2424

2525
5. **Avoid utility and kitchen-sink packages.**
2626

27-
They tend to grow without a coherent domain and become junk drawers.
27+
They tend to grow without a coherent domain and become junk drawers.
2828

2929
6. **Avoid broad, catch-all scopes.**
3030

31-
For example: "Reusable WordPress components" or "Utilities for different use cases." These create unclear ownership and encourage uncontrolled growth. Instead, define a specific domain or purpose.
31+
For example: "Reusable WordPress components" or "Utilities for different use cases." These create unclear ownership and encourage uncontrolled growth. Instead, define a specific domain or purpose.
3232

3333
7. **Default to bundled packages (no globals, no modules) unless necessary.**
3434

35-
In Gutenberg, we should default to "bundled" packages unless there's a specific need for globals or modules. See the [@wordpress/build README](../wp-build/README.md) for more information on package configuration.
35+
In Gutenberg, we should default to "bundled" packages unless there's a specific need for globals or modules. See the [@wordpress/build README](../wp-build/README.md) for more information on package configuration.
3636

3737
For more information on the build system and package configuration, see the [@wordpress/build README](../wp-build/README.md).
3838

@@ -141,14 +141,16 @@ Omit `wpScript` (or explicitly set to `false`) for packages designed solely as d
141141
```
142142

143143
**Examples of packages that should not expose to the `wp` global:**
144-
- Utility packages used internally by other packages
145-
- Shared logic or helpers without a direct WordPress use case
146-
- Intermediate packages intended only as dependencies of other `@wordpress/*` packages
144+
145+
- Utility packages used internally by other packages
146+
- Shared logic or helpers without a direct WordPress use case
147+
- Intermediate packages intended only as dependencies of other `@wordpress/*` packages
147148

148149
When a package omits `wpScript` or sets it to `false`, it:
149-
- Will not be exposed as a WordPress script (not available via the `wp` global)
150-
- Can still be used as a dependency by other packages (via npm imports)
151-
- Should still be published to npm to support backporting to WordPress core releases
150+
151+
- Will not be exposed as a WordPress script (not available via the `wp` global)
152+
- Can still be used as a dependency by other packages (via npm imports)
153+
- Should still be published to npm to support backporting to WordPress core releases
152154

153155
### Truly Private Packages
154156

@@ -270,14 +272,39 @@ _Example:_
270272
- Fixed an off-by-one error with the `sum` function.
271273
```
272274

275+
### Promoting a Pre-Release Package to Stable (1.0.0)
276+
277+
The automated package publishing workflow will at most bump the minor version of a pre-release package (those having a version like `0.x.x`), even if it includes breaking changes. This is consistent with semantic versioning, where `0.x` versions are intended for initial development where the API may change frequently.
278+
279+
When a package's API is considered stable and ready for production use, it should be promoted to version 1.0.0. This is done by adding a "Stable Release" section to the `CHANGELOG.md` file:
280+
281+
_Example:_
282+
283+
```md
284+
## Unreleased
285+
286+
### Stable Release
287+
288+
This package is now considered stable and production-ready. The API will follow semantic versioning from this point forward.
289+
290+
### Breaking Changes
291+
292+
- Final API adjustments before 1.0.0 release.
293+
```
294+
295+
The presence of the "Stable Release" heading will cause the automated release process to bump a pre-1.0 package to 1.0.0. The "Stable Release" heading should only be used for pre-1.0 packages, and from that point forward breaking changes will result in major version bumps as expected.
296+
297+
### Changelog Subsections
298+
273299
There are a number of common release subsections you can follow. Each is intended to align to a specific meaning in the context of the [Semantic Versioning (`semver`) specification](https://semver.org/) the project adheres to. It is important that you describe your changes accurately, since this is used in the packages release process to help determine the version of the next release.
274300
275-
- "Breaking Changes" - A backwards-incompatible change which requires specific attention of the impacted developers to reconcile (requires a major version bump).
301+
- "Breaking Changes" - A backwards-incompatible change which requires specific attention of the impacted developers to reconcile (requires a major version bump for stable packages).
276302
- "New Features" - The addition of a new backwards-compatible function or feature to the existing public API (requires a minor version bump).
277303
- "Enhancements" - Backwards-compatible improvements to existing functionality (requires a minor version bump).
278304
- "Deprecations" - Deprecation notices. These do not impact the public interface or behavior of the module (requires a minor version bump).
279305
- "Bug Fixes" - Resolutions to existing buggy behavior (requires a patch version bump).
280306
- "Internal" - Changes which do not have an impact on the public interface or behavior of the module (requires a patch version bump).
307+
- "Stable Release" - Marks a pre-1.0 package as stable and production-ready. This should only be used for packages currently published as a 0.x pre-release, to intentionally communicate that a package's API is now stable and ready for production use.
281308

282309
While other section naming can be used when appropriate, it's important that are expressed clearly to avoid confusion for both the packages releaser and third-party consumers.
283310

0 commit comments

Comments
 (0)