UNPKG

@ethima/semantic-release-configuration

Version:

A shareable semantic release configuration supporting a range of languages and platforms supported by the Ethima organization.

321 lines (259 loc) 16.2 kB
# Semantic Release Configuration A shareable [semantic release](https://semantic-release.gitbook.io) configuration supporting a range of languages and platforms supported by the @ethima organization. ## Features - Analyzes commits using [`@semantic-release/commit-analyzer`][semantic-release-commit-analyzer-plugin-url] and the [`conventional-changelog-conventionalcommits` preset][conventionalcommits-preset-url] implementing the [Conventional Commits specification][conventionalcommits-url]. - Generates release notes using [`@semantic-release/release-notes-generator`][semantic-release-notes-generator-plugin-url]. - Updates templated content in files, e.g. a project's root-level `README.md`, with updated version information using [`semantic-release-replace-plugin`][semantic-release-replace-plugin-url] and [`@semantic-release/git`][semantic-release-git-plugin-url]. - Maintains a `CHANGELOG.md` from the generated release notes using [`@semantic-release/changelog`][semantic-release-changelog-plugin-url] and [`@semantic-release/git`][semantic-release-git-plugin-url]. - (Conditionally) maintains NPM package files, i.e. `package.json`, `package-lock.json` (if committed), and publishes using [`@semantic-release/npm`][semantic-release-npm-plugin-url] and [`@semantic-release/git`][semantic-release-git-plugin-url]. - (Conditionally) maintains Julia package files, i.e. `version` fields in `Project.toml` files, using [`semantic-release-replace-plugin`][semantic-release-replace-plugin-url] and [`@semantic-release/git`][semantic-release-git-plugin-url]. - Publishes releases to the relevant hosting platform, i.e. GitHub or GitLab, using the platform-specific release plugins [`@semantic-release/github`][semantic-release-github-plugin-url] or [`@semantic-release/gitlab`][semantic-release-gitlab-plugin-url] respectively. ## Usage - Create the [relevant authentication token][semantic-release-authentication-url] for the platform on which the project using this configuration is hosted. This secret will be used by the main `semantic-release` tool for pushing tags as well as the platform-specific plugin i.e. [GitHub][semantic-release-github-plugin-auth-url] or [GitLab][semantic-release-gitlab-plugin-auth-url]. For improved security, _use a unique token for every project this configuration is used in_! - Use this shareable semantic release configuration by including it in the [`extends`][semantic-release-extends-configuration-url] configuration for the project to be semantically released. - When using this shareable semantic release configuration on GitHub, be sure to read the instructions below on the `primary_release_branch` configuration and provide an appropriate value if necessary. ### Configuration The semantic release configuration has several configuration options itself. Some of this configuration, like sensitive tokens such as `GH_TOKEN`, `GITLAB_TOKEN` and `NPM_TOKEN`, should be configured through environment variables. Other configuration options have more complex values and are not suitable for configuration through environment variables. These configuration options can be configured through a file. The [`cosmiconfig` library][cosmiconfig-url] is used for this purpose. This library will search for an `ethima` configuration file as explained in the introduction of its `README`, e.g. a JSON or YAML-formatted `.ethimarc` or `.config/ethimarc` file, JavaScript in a `.ethimarc.js`, etc. The available configuration options are explained in detail in the sections describing the functionality they apply to. ### Branches By default, `semantic-release` accepts [_at most_ 3 "release branches"][semantic-release-branches-url]. This configuration provides a mechanism to work around this limitation by detecting the type of the active branch and only configuring `semantic-release` to act on the primary release branch and the active branch, enabling the use of more "release branches". The primary release branch is _always_ configured as `semantic-release` requires at least one "release branch" to be defined. Additionally, this configuration extends the allowed patterns for "maintenance" and "prerelease" branches. Specifically `semantic-release` only supports [`N.N.x`, `N.x.x` and `N.x` patterns][semantic-release-branch-patterns-url] where `N` is a number. When using this configuration `N`, `N.N`, `N.y`, `N.y.z` and `N.N.z` (suffix) patterns are also supported. The configuration distinguishes three types of branches: - The "primary release branch" which is the branch from which the most up-to-date release gets cut. - "Maintenance branches" which represent a specific subset of releases that can be used for maintenance releases after the "primary release branch" has moved ahead to a newer version. For instance, a `release-2` branch when the primary release branch targets releases for version 3 or up, or a `release-1.2` branch for releases within the v1.2.z range after the `release-1` branch has started to target v1.3.z. - "Prerelease branches" which can be used to "gate" releases, e.g. to accumulate a number of changes to release at once instead of releasing on every single merge into a "release branch", i.e. the "primary release branch" or a "maintenance branch". These branches typically follow the naming convention of the other "release branches" but with a different prefix, e.g. `next-2` corresponds to prereleases for `release-2`, `next-1.2.z` corresponds to releases for `release-1.2.z`, etc. The "prerelease branch" for the "primary release branch" is a special case which only consists of the prefix used to indicate "prerelease branches", e.g. `next`. The tags associated with a "prerelease branch" receive an additional suffix. Note that "breaking" or "feature" "prerelease branches" will accept prereleases for the next "breaking" or "feature" version as, according to the [semantic versioning specification][semantic-versioning-prerelease-precedence-url], these versions technically fall within the upper bounded version range represented by the "prerelease branch". For instance, a feature commit on the `next-3.1` branch will be accepted and results in the publication of `3.2.0-rc.1` from that branch. If that same commit would have been made on the `release-3.1` branch it would not have been accepted. Various aspects of branch and tag naming can be configured through the mechanisms [outlined above](#configuration). The folowing branch-related configuration options are available: | Configuration option | Description | Environment Variable | | --------------------------- | ----------------------------------------------------------------------------------- | --------------------------- | | `branch_prefix_separator` | Specifies the character(s) used to separate the branch prefixes from version ranges | `BRANCH_PREFIX_SEPARATOR` | | `maintenance_branch_prefix` | Specifies the prefix used for "maintenance branches" | `MAINTENANCE_BRANCH_PREFIX` | | `prerelease_branch_prefix` | Specifies the prefix used for "prerelease branches" | `PRERELEASE_BRANCH_PREFIX` | | `prerelease_branch_prefix` | Specifies the suffix used for tags created from "prerelease branches" | `PRERELEASE_TAG_SUFFIX` | | `primary_release_branch` | Indicates the name of the "primary release branch" | `PRIMARY_RELEASE_BRANCH` | The default configuration is ```js { branch_prefix_separator: "-", maintenance_branch_prefix: "release" prerelease_branch_prefix: "next", prerelease_tag_suffix: "rc", primary_release_branch: env.CI_DEFAULT_BRANCH || "main", } ``` The branch for which a release is intended to be triggered should be provided as a `CURRENT_BRANCH` environment variable before instantiating this configuration. For common platforms, i.e. GitLab CI and GitHub Actions, this value will be automatically derived from known environment variables specific to each platform. ### Changelog Maintenance A changelog is maintained using the release notes generated by the semantic release tooling. This changelog is maintained in a `CHANGELOG.md` in the root of a project by default. This path can be configured by adding a `changelog_filename` property to a file-based configuration as described in [the configuration section](#configuration). ### JavaScript Packages JavaScript packages are detected based on the presence of a `package.json` file in the root of the project. - Create an [NPM token][npm-token-url] to be able to publish to an NPM registry. Make the token available as an `NPM_TOKEN` CI/CD variable of the project using the configuration. See [the plugin's configuration instructions][semantic-release-npm-plugin-configuration-url] for details and alternatives. ### Julia Packages Julia packages are detected based on the presence of a `Project.toml` file in the root of the project. The configuration is not able to automatically register releases with the General registry. Newly created releases should be registered using [JuliaHub's _Register Packages_ interface][juliahub-register-package-url]. ### Templated Content in Files The configuration will look for `__NEXT_SEMANTIC_RELEASE_VERSION__` tokens in templates in files specified in the `files_with_versioned_templates` configuration and replace them with the version that is being released. This is, for instance, useful for automatically keeping installation instructions up-to-date. The configuration defaults to a project's root-level `README.md`. Templated content has the following token-based structure: - A `BEGIN_VERSIONED_TEMPLATE` token, - the template itself with one or more `__NEXT_SEMANTIC_RELEASE_VERSION__` tokens, - an `END_VERSIONED_TEMPLATE` token, - (optionally) content that was previously templated and which will be discarded, - an `END_VERSIONED_TEMPLATE_REPLACEMENT` token. The `BEGIN_VERSIONED_TEMPLATE`, `END_VERSIONED_TEMPLATE` and `END_VERSIONED_TEMPLATE_REPLACEMENT` tokens must each be on their own line. These lines may be indented and contain other content that is exempt from replacements, e.g. comment markers to ensure the templates do not affect surrounding code or documentation. The exact tokens may differ per file-type, [see the source code for available configurations](./src/versioned-templates.js). For instance, Markdown files can use HTML block comments and may replace the literal `END_VERSIONED_TEMPLATE` token with an "end comment" token. More concretely a section in a `README.md` that looks like ```markdown <!-- BEGIN_VERSIONED_TEMPLATE The next semantically released version will be v__NEXT_SEMANTIC_RELEASE_VERSION__! --> <!-- END_VERSIONED_TEMPLATE_REPLACEMENT --> ``` would, after a v1.2.3 release using the configuration has been triggered, become ```markdown <!-- BEGIN_VERSIONED_TEMPLATE The next semantically released version will be v__NEXT_SEMANTIC_RELEASE_VERSION__! --> The next semantically released version will be v1.2.3! <!-- END_VERSIONED_TEMPLATE_REPLACEMENT --> ``` Note that the `v` is in the template! The version as derived by the semantic release tooling does not contain that prefix. #### Configuring which files to update The templated content feature uses [the `replace-in-file` library][replace-in-file-url] to perform the actual replacements. In which files templates should be replaced, can be configured by adding a `files_with_versioned_templates` key specifying an array of filenames and globs to a configuration file as described in the [configuration section](#configuration). For instance: ```json { "files_with_versioned_templates": [ "README.md", "some/other/file.md", "a/glob/for/multiple/markdown/files/*.md", "src/**/*.js" ] } ``` #### Preventing individual templates from being updated Configuring which files to ignore when updating templated content is a very coarse approach which may not always be suitable. In cases where a more fine-grained approach is necessary, replacements in individual templates can be prevented by modifying (one of) the tokens in those templates. For instance by including a non-visible whitespace character, e.g. [a _Zero Width Non-Joiner (ZWNJ)_ character](https://unicode-table.com/en/200C/). A sufficient approach is to modify the starting token, so that the template is no longer recognized as one. Using the suggested ZWNJ character the starting token becomes `<!--‌ BEGIN_VERSIONED_TEMPLATE`. Note that when using this approach, although the templates/tokens _visually_ look like versions that should be replaced, they cannot be copied and pasted as examples as the resulting copies will also contain the non-visible whitespace character. When using this approach be sure to indicate this as to not confuse readers as to why replacements may not be working! ## Troubleshooting ### Publishing the initial release of a scoped JavaScript package Creating the initial release of a scoped JavaScript may fail if the package is intended to be public and the person creating the release not having paid for private packages. This results in an error similar to ``` npm ERR! 402 Payment Required - PUT https://registry.npmjs.org/@<scope>%2f<package-name> - You must sign up for private packages ``` When this happens, publish the initial release manually using `npm publish --access=public` after making sure the local copy of the project to be released is up-to-date. When this happens, it is typically also necessary to create the initial GitHub release by hand from the tag and changelog that was created by the [`semantic-release`][semantic-release-url] tooling. [conventionalcommits-url]: https://www.conventionalcommits.org [conventionalcommits-preset-url]: https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits [cosmiconfig-url]: https://www.npmjs.com/package/cosmiconfig [gitlab-predefined-variables-url]: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html [juliahub-register-package-url]: https://juliahub.com/ui/Registrator [npm-token-url]: https://docs.npmjs.com/creating-and-viewing-access-tokens#creating-granular-access-tokens-on-the-website [replace-in-file-url]: https://www.npmjs.com/package/replace-in-file [semantic-release-authentication-url]: https://semantic-release.gitbook.io/semantic-release/usage/ci-configuration#authentication [semantic-release-branch-patterns-url]: https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#range [semantic-release-branches-url]: https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#release-branches [semantic-release-changelog-plugin-url]: https://github.com/semantic-release/changelog [semantic-release-commit-analyzer-plugin-url]: https://github.com/semantic-release/commit-analyzer [semantic-release-extends-configuration-url]: https://semantic-release.gitbook.io/semantic-release/usage/configuration#extends [semantic-release-git-plugin-url]: https://github.com/semantic-release/git [semantic-release-github-plugin-url]: https://github.com/semantic-release/github [semantic-release-github-plugin-auth-url]: https://github.com/semantic-release/github#github-authentication [semantic-release-gitlab-plugin-url]: https://github.com/semantic-release/gitlab [semantic-release-gitlab-plugin-auth-url]: https://github.com/semantic-release/gitlab#gitlab-authentication [semantic-release-notes-generator-plugin-url]: https://github.com/semantic-release/release-notes-generator [semantic-release-npm-plugin-configuration-url]: https://github.com/semantic-release/npm#npm-registry-authentication [semantic-release-npm-plugin-url]: https://www.npmjs.com/package/@semantic-release/npm [semantic-release-replace-plugin-url]: https://github.com/jpoehnelt/semantic-release-replace-plugin [semantic-release-url]: https://semantic-release.gitbook.io/ [semantic-versioning-prerelease-precedence-url]: https://semver.org/#spec-item-9