This pull request refactors the core logic of the package to use the
`@semantic-release/core` engine directly, removes legacy and duplicated
code, and centralizes configuration. The changes simplify the codebase
by delegating most of the release logic to the upstream core package,
making the CLI wrapper thinner and easier to maintain. Several internal
utility files for branch and tag handling are also removed, as their
logic is now handled by `@semantic-release/core`.
### Migration to Core Engine
* The CLI now delegates release logic to `@semantic-release/core`, using
its `resolveConfig`, `getLogger`, and other helpers, instead of
maintaining a custom implementation. This reduces maintenance overhead
and ensures alignment with the core release logic.
* The documentation is updated to explain that `semantic-release` uses
`@semantic-release/core` as its engine, and provides guidance for
advanced use cases.
### Configuration and Defaults
* A new `SEMANTIC_RELEASE_DEFAULT_CONFIG` constant is introduced,
centralizing the default plugin stack for releases.
### Codebase Simplification
* Removes internal implementations for branch expansion, tag retrieval,
and normalization, as well as related validation and error handling
logic. These are now handled by the core engine.
for #2543
BREAKING CHANGE: semantic-release is now ESM-only. since it is used through its own executable, the impact on consuming projects should be minimal
BREAKING CHANGE: references to plugin files in configs need to include the file extension because of executing in an ESM context
BREAKING CHANGE: this feature change the way semantic-release keep track of the channels on which a version has been released.
It now use a JSON object stored in a [Git note](https://git-scm.com/docs/git-notes) instead of Git tags formatted as v{version}@{channel}.
The tags formatted as v{version}@{channel} will now be ignored. If you have made releases with v16.0.0 on branches other than the default one you will have to update your repository.
The changes to make consist in:
- Finding all the versions that have been released on a branch other than the default one by searching for all tags formatted v{version}@{channel}
- For each of those version:
- Create a tag without the {@channel} if none doesn't already exists
- Add a Git note to the tag without the {@channel} containing the channels on which the version was released formatted as `{"channels":["channel1","channel2"]}` and using `null` for the default channel (for example.`{"channels":[null,"channel1","channel2"]}`)
- Push the tags and notes
- Update the GitHub releases that refer to a tag formatted as v{version}@{channel} to use the tag without it
- Delete the tags formatted as v{version}@{channel}
- Add only the most recent release to a channel (rather than adding all the one not added yet)
- Avoid attempting to ad the version twice in case that version is already present in multiple upper branches
- Allow to configure multiple branches to release from
- Allow to define a distribution channel associated with each branch
- Manage the availability on distribution channels based on git merges
- Support regular releases, maintenance releases and pre-releases
- Add the `addChannel` plugin step to make an existing release available on a different distribution channel
BREAKING CHANGE: the `branch` option has been removed in favor of `branches`
The new `branches` option expect either an Array or a single branch definition. To migrate your configuration:
- If you want to publish package from multiple branches, please the configuration documentation
- If you use the default configuration and want to publish only from `master`: nothing to change
- If you use the `branch` configuration and want to publish only from one branch: replace `branch` by `branches` (`"branch": "my-release-branch"` => `"branches": "my-release-branch"`)
- Allow to run semantic-release (via API) from anywhere passing the current working directory.
- Allows to simplify the tests and to run them in parallel in both the core and plugins.
Each `generateNotes` plugin will be called in the order defined and will receive the concatenation of the previous one in `nextRelease.notes`.
That gives each plugin the ability to test if there is a notes part that will precede it's own.
Each plugin is expected to return it's own part of the release notes only. **semantic-release** will take care of concatenating all the notes parts.