Compare commits
	
		
			3 Commits
		
	
	
		
			master
			...
			beta-test-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d4ed18d184 | ||
|  | 039145ab3e | ||
|  | 75280d28d8 | 
| @ -1,4 +1,2 @@ | ||||
| # style: prettier (#2670) | ||||
| b06c9bbe4c6be121c5561b356d8c465c1cadffba | ||||
| # style: upgraded prettier to v3 (#2863) | ||||
| 272af210523804de782b3076f05e56bcb4aeeb8f | ||||
|  | ||||
							
								
								
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @ -18,8 +18,8 @@ jobs: | ||||
|     name: release | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||||
|       - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 | ||||
|       - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 | ||||
|       - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3 | ||||
|         with: | ||||
|           cache: npm | ||||
|           node-version: lts/* | ||||
|  | ||||
							
								
								
									
										36
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								.github/workflows/scorecard.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,36 +0,0 @@ | ||||
| name: OpenSSF Scorecard | ||||
| "on": | ||||
|   schedule: | ||||
|     - cron: 31 2 * * 1 | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
| permissions: read-all | ||||
| jobs: | ||||
|   analysis: | ||||
|     name: Scorecard analysis | ||||
|     runs-on: ubuntu-latest | ||||
|     permissions: | ||||
|       security-events: write | ||||
|       id-token: write | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||||
|         with: | ||||
|           persist-credentials: false | ||||
|       - name: Run analysis | ||||
|         uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 | ||||
|         with: | ||||
|           results_file: results.sarif | ||||
|           results_format: sarif | ||||
|           publish_results: true | ||||
|       - name: Upload artifact | ||||
|         uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 | ||||
|         with: | ||||
|           name: SARIF file | ||||
|           path: results.sarif | ||||
|           retention-days: 5 | ||||
|       - name: Upload to code-scanning | ||||
|         uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 | ||||
|         with: | ||||
|           sarif_file: results.sarif | ||||
							
								
								
									
										58
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @ -15,66 +15,42 @@ on: | ||||
| permissions: | ||||
|   contents: read # to fetch code (actions/checkout) | ||||
| 
 | ||||
| env: | ||||
|   FORCE_COLOR: 1 | ||||
|   NPM_CONFIG_COLOR: always | ||||
| 
 | ||||
| jobs: | ||||
|   # verify against ranges defined as supported in engines.node | ||||
|   test_matrix: | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node-version: | ||||
|           - 20.8.1 | ||||
|           - 20 | ||||
|           - 21 | ||||
|           - 18.0.0 | ||||
|           - 19 | ||||
| 
 | ||||
|     runs-on: ubuntu-latest | ||||
|     timeout-minutes: 5 | ||||
|     timeout-minutes: 10 | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||||
|       - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 | ||||
|       - run: git config --global user.name github-actions | ||||
|       - run: git config --global user.email github-actions@github.com | ||||
|       - name: Use Node.js ${{ matrix.node-version }} | ||||
|         uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 | ||||
|         uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node-version }} | ||||
|           cache: npm | ||||
|       - run: npm clean-install | ||||
|       - run: npm audit signatures | ||||
|       - run: npm test | ||||
| 
 | ||||
|   # verify against the node version defined for development in the .nvmrc | ||||
|   test_dev: | ||||
|     runs-on: ubuntu-latest | ||||
|     timeout-minutes: 5 | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||||
|       - run: git config --global user.name github-actions | ||||
|       - run: git config --global user.email github-actions@github.com | ||||
|       - name: Use Node.js from .nvmrc | ||||
|         uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 | ||||
|         with: | ||||
|           node-version-file: .nvmrc | ||||
|           cache: npm | ||||
|       - run: npm clean-install | ||||
|       - run: npm audit signatures | ||||
|       - run: npm test | ||||
|       - name: Ensure dependencies are compatible with the version of node | ||||
|         run: npx ls-engines | ||||
|       - run: npm run test:ci | ||||
| 
 | ||||
|   # separate job to set as required in branch protection, | ||||
|   # as the build names above change each time Node versions change | ||||
|   test: | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: | ||||
|       - test_dev | ||||
|       - test_matrix | ||||
|     if: ${{ !cancelled() }} | ||||
|     needs: test_matrix | ||||
|     steps: | ||||
|       - name: All matrix versions passed | ||||
|         if: ${{ !(contains(needs.*.result, 'failure')) }} | ||||
|         run: exit 0 | ||||
|       - name: Some matrix version failed | ||||
|         if: ${{ contains(needs.*.result, 'failure') }} | ||||
|         run: exit 1 | ||||
|       - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 | ||||
|       - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3 | ||||
|         with: | ||||
|           node-version: lts/* | ||||
|           cache: npm | ||||
|       - run: npm clean-install | ||||
|       - run: npm audit signatures | ||||
|       - run: npm run lint | ||||
|  | ||||
| @ -146,7 +146,7 @@ If possible, make [atomic commits](https://en.wikipedia.org/wiki/Atomic_commit), | ||||
| 
 | ||||
| - a commit should contain exactly one self-contained functional change | ||||
| - a functional change should be contained in exactly one commit | ||||
| - a commit should not create an inconsistent state (such as test errors, linting errors, partial fix, feature without documentation, etc...) | ||||
| - a commit should not create an inconsistent state (such as test errors, linting errors, partial fix, feature with documentation etc...) | ||||
| 
 | ||||
| A complex feature can be broken down into multiple commits as long as each one maintains a consistent state and consists of a self-contained change. | ||||
| 
 | ||||
| @ -241,82 +241,42 @@ $ git clone https://github.com/semantic-release/<repo-name> | ||||
| $ cd <repo-name> | ||||
| # Assign the original repo to a remote called "upstream" | ||||
| $ git remote add upstream https://github.com/semantic-release/<repo-name> | ||||
| # Switch your node version to the version defined by the project as the development version | ||||
| # This step assumes you have already installed and configured https://github.com/nvm-sh/nvm | ||||
| # You may need to run `nvm install` if you have not already installed the development node version | ||||
| $ nvm use | ||||
| # Install the dependencies | ||||
| $ npm install | ||||
| ``` | ||||
| 
 | ||||
| ### Verification | ||||
| ### Lint | ||||
| 
 | ||||
| The `test` script is structured to execute as much of the verification for the project as possible. | ||||
| Ensuring that the `test` script fully passes in the node version defined as the development version in the `.nvmrc` | ||||
| minimizes the chances of the test workflow failing after pushing your changes. | ||||
| All the [semantic-release](https://github.com/semantic-release) repositories use [XO](https://github.com/sindresorhus/xo) for linting and [Prettier](https://prettier.io) for formatting. | ||||
| Prettier formatting will be automatically verified and fixed by XO. | ||||
| 
 | ||||
| > [!IMPORTANT] | ||||
| > Before pushing your code changes, be sure to run the verification for the project with `npm test`. | ||||
| Before pushing your code changes make sure there are no linting errors with `npm run lint`. | ||||
| 
 | ||||
| [npm-run-all2](https://www.npmjs.com/package/npm-run-all2) is used to enable running multiple independent lint and test | ||||
| scripts together from the `test` script. | ||||
| This enables the test script to not only run all scripts, but also parallelize some of the scripts to optimize the overall | ||||
| time required for verification. | ||||
| **Tips**: | ||||
| 
 | ||||
| When a failure occurs with the `test`, the output can be a bit confusing because there may be output from multiple parallel | ||||
| scripts mixed together. | ||||
| To investigate the failure with cleaner output, re-run the problematic script directly using the script name from the label | ||||
| included on the left side of the output | ||||
| - Most linting errors can be automatically fixed with `npm run lint -- --fix`. | ||||
| - Install the [XO plugin](https://github.com/sindresorhus/xo#editor-plugins) for your editor to see linting errors directly in your editor and automatically fix them on save. | ||||
| 
 | ||||
| ```shell | ||||
| $ npm run <script-name> | ||||
| ``` | ||||
| ### Tests | ||||
| 
 | ||||
| #### Lint | ||||
| 
 | ||||
| ##### Prettier | ||||
| 
 | ||||
| All the [semantic-release](https://github.com/semantic-release) repositories use [Prettier](https://prettier.io) for formatting. | ||||
| Prettier formatting will be automatically verified by the `lint:prettier` script, included in the `test` script. | ||||
| 
 | ||||
| > [!NOTE] | ||||
| > Most linting errors can be automatically fixed with `npm run lint:prettier:fix`. | ||||
| 
 | ||||
| ##### Other Lint Tools | ||||
| 
 | ||||
| Other tools are used for specific compatibility concerns, but are less likely to result in failures in common contributions. | ||||
| Please follow the guidance of these tools if failures are encountered. | ||||
| 
 | ||||
| #### Tests | ||||
| 
 | ||||
| > [!NOTE] | ||||
| > Before pushing your code changes make sure all **tests pass** and the unit test **coverage is 100%**: | ||||
| Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. | ||||
| 
 | ||||
| All the [semantic-release](https://github.com/semantic-release) repositories use [AVA](https://github.com/avajs/ava) for writing and running tests. | ||||
| 
 | ||||
| During development, you can: | ||||
| Before pushing your code changes make sure all **tests pass** and the **coverage is 100%**: | ||||
| 
 | ||||
| ```bash | ||||
| $ npm run test | ||||
| ``` | ||||
| 
 | ||||
| **Tips:** During development you can: | ||||
| 
 | ||||
| - run only a subset of test files with `ava <glob>`, for example `ava test/mytestfile.test.js` | ||||
| - run in watch mode with `ava -w` to automatically run a test file when you modify it | ||||
| - run only the test you are working on by adding [`.only` to the test definition](https://github.com/avajs/ava#running-specific-tests) | ||||
| 
 | ||||
| ##### Unit Tests | ||||
| 
 | ||||
| ```bash | ||||
| $ npm run test:unit | ||||
| ``` | ||||
| 
 | ||||
| ##### Integration Tests | ||||
| 
 | ||||
| > [!IMPORTANT] | ||||
| > Running the integration test requires you to install [Docker](https://docs.docker.com/engine/installation) on your machine. | ||||
| 
 | ||||
| ```bash | ||||
| $ npm run test:integration | ||||
| ``` | ||||
| 
 | ||||
| ### Commits | ||||
| 
 | ||||
| All the [semantic-release](https://github.com/semantic-release) repositories use [Commitizen](https://github.com/commitizen/cz-cli) to help you create [valid commit messages](#commit-message-guidelines). | ||||
| 
 | ||||
| Assuming you have [installed Commitizen](https://github.com/commitizen/cz-cli#installing-the-command-line-tool), run `git cz` to start the interactive commit message CLI rather than `git commit` when committing. | ||||
| After staging your changes with `git add`, run `npm run cm` to start the interactive commit message CLI. | ||||
|  | ||||
							
								
								
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							| @ -9,8 +9,8 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  | ||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							| @ -7,9 +7,6 @@ | ||||
|   <a href="https://github.com/semantic-release/semantic-release/actions?query=workflow%3ATest+branch%3Amaster"> | ||||
|     <img alt="Build states" src="https://github.com/semantic-release/semantic-release/workflows/Test/badge.svg"> | ||||
|   </a> | ||||
|   <a href="https://securityscorecards.dev/viewer/?uri=github.com/semantic-release/semantic-release"> | ||||
|     <img alt="OpenSSF Scorecard" src="https://api.securityscorecards.dev/projects/github.com/semantic-release/semantic-release/badge"> | ||||
|   </a> | ||||
|   <a href="#badge"> | ||||
|     <img alt="semantic-release: angular" src="https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release"> | ||||
|   </a> | ||||
| @ -69,7 +66,7 @@ The table below shows which commit message gets you which release type when `sem | ||||
| ### Automation with CI | ||||
| 
 | ||||
| **semantic-release** is meant to be executed on the CI environment after every successful build on the release branch. | ||||
| This way no human is directly involved in the release process and the releases are guaranteed to be [unromantic and unsentimental](https://github.com/dominictarr/sentimental-versioning#readme). | ||||
| This way no human is directly involved in the release process and the releases are guaranteed to be [unromantic and unsentimental](http://sentimentalversioning.org). | ||||
| 
 | ||||
| ### Triggering a release | ||||
| 
 | ||||
| @ -110,9 +107,9 @@ In order to use **semantic-release** you need: | ||||
| ## Documentation | ||||
| 
 | ||||
| - Usage | ||||
|   - [Getting started](docs/usage/getting-started.md) | ||||
|   - [Installation](docs/usage/installation.md) | ||||
|   - [CI Configuration](docs/usage/ci-configuration.md) | ||||
|   - [Getting started](docs/usage/getting-started.md#getting-started) | ||||
|   - [Installation](docs/usage/installation.md#installation) | ||||
|   - [CI Configuration](docs/usage/ci-configuration.md#ci-configuration) | ||||
|   - [Configuration](docs/usage/configuration.md#configuration) | ||||
|   - [Plugins](docs/usage/plugins.md) | ||||
|   - [Workflow configuration](docs/usage/workflow-configuration.md) | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| - [Getting started](docs/usage/getting-started.md) | ||||
| - [Getting started](docs/usage/getting-started.md#getting-started) | ||||
| - [Installation](docs/usage/installation.md) | ||||
| - [CI Configuration](docs/usage/ci-configuration.md) | ||||
| - [Configuration](docs/usage/configuration.md) | ||||
|  | ||||
| @ -127,7 +127,7 @@ It allows to configure **semantic-release** to write errors to a specific stream | ||||
| 
 | ||||
| Type: `Object` `Boolean`<br> | ||||
| 
 | ||||
| An object with [`lastRelease`](#lastrelease), [`nextRelease`](#nextrelease), [`commits`](#commits) and [`releases`](#releases) if a release is published or `false` if no release was published. | ||||
| And object with [`lastRelease`](#lastrelease), [`nextRelease`](#nextrelease), [`commits`](#commits) and [`releases`](#releases) if a release is published or `false` if no release was published. | ||||
| 
 | ||||
| #### lastRelease | ||||
| 
 | ||||
| @ -159,7 +159,7 @@ Example: | ||||
| 
 | ||||
| Type: `Array<Object>` | ||||
| 
 | ||||
| The list of commit(s) included in the new release.<br> | ||||
| The list of commit included in the new release.<br> | ||||
| Each commit object has the following properties: | ||||
| 
 | ||||
| | Name            | Type     | Description                                     | | ||||
|  | ||||
| @ -84,11 +84,6 @@ | ||||
|   - `verifyRelease`: Checks and warns (does not error by default) if the version numbers found on maven central and within the Git project differ by quite a bit | ||||
|   - `prepare`: Changes the version number in the `pom.xml` (or all `pom.xml` files in maven projects with multiple `pom.xml` files) and optionally creates a commit with this version number and pushes it to `master` | ||||
|   - `publish`: Runs `mvn deploy` to deploy to maven central and optionally will update to next snapshot version and merge changes to development branch | ||||
| - [maven-semantic-release](https://github.com/terrestris/maven-semantic-release) (alternative version) | ||||
|   - `verifyConditions`: Verifies that the `mvn` command exists. | ||||
|   - `prepare`: Changes version number in `pom.xml` and optionally in all child modules. | ||||
|   - `publish`: Runs one of the mvn targets `deploy`, `package jib:build` or `deploy jib:build`. | ||||
|   - `success`: Optionally sets new snapshot version and commits it. | ||||
| - [semantic-release-ado](https://github.com/lluchmk/semantic-release-ado) | ||||
|   - `prepare`: Stores the version number as an Azure DevOps pipeline variable available to downstream steps on the job | ||||
| - [gradle-semantic-release](https://github.com/KengoTODA/gradle-semantic-release-plugin) | ||||
| @ -112,7 +107,7 @@ | ||||
|   - `verifyConditions`: Verify the presence and the validity of the authentication and the assets option configuration. | ||||
|   - `publish`: Publish a Gitea release, optionally uploading file assets. | ||||
|   - `addChannel`: Update a Gitea release's pre-release field. | ||||
| - [semantic-release-replace-plugin](https://github.com/jpoehnelt/semantic-release-replace-plugin) | ||||
| - [@google/semantic-release-replace-plugin](https://github.com/google/semantic-release-replace-plugin) | ||||
|   - `prepare`: Replace version strings in files using regex and glob. | ||||
| - [semantic-release-rubygem](https://github.com/Gusto/semantic-release-rubygem) | ||||
|   - `verifyConditions`: Locate and validate a `.gemspec` file, locate and validate a `lib/**/version.rb` file, verify the presence of the `GEM_HOST_API_KEY` environment variable, and create a credentials file with the API key. | ||||
| @ -179,9 +174,6 @@ | ||||
| - [semantic-release-coralogix](https://github.com/adobe/semantic-release-coralogix) | ||||
|   - `verifyConditions` Verified that required credentials are provided and API is accessible | ||||
|   - `publish` add a release tag to Coralogix | ||||
| - [semantic-release-jira-notes](https://github.com/iamludal/semantic-release-jira-notes) | ||||
|   - `verifyConditions`: Validate the config options. | ||||
|   - `generateNotes`: Generate the release notes with links to JIRA issues. | ||||
| - [semantic-release-major-tag](https://github.com/doteric/semantic-release-major-tag) | ||||
|   - `success` Create major version tag, for example `v1`. | ||||
| - [semantic-release-yarn](https://github.com/hongaar/semantic-release-yarn) | ||||
| @ -190,7 +182,3 @@ | ||||
|   - `prepare` Update the `package.json` version and create the package tarball. | ||||
|   - `addChannel` Add a tag for the release. | ||||
|   - `publish` Publish to the npm registry. | ||||
| - [semantic-release-pub](https://github.com/zeshuaro/semantic-release-pub) | ||||
|   - `verifyConditions`: Verify the presence of the `pub.dev` authentication and release configuration | ||||
|   - `prepare`: Update the `pubspec.yaml` version | ||||
|   - `publish`: Publish the package onto the `pub.dev` registry | ||||
|  | ||||
| @ -6,11 +6,6 @@ The [Authentication](../../usage/ci-configuration.md#authentication) environment | ||||
| 
 | ||||
| **Note**: Make sure to configure your release branch as [protected](https://docs.gitlab.com/ce/user/project/protected_branches.html) in order for the CI/CD build to access the protected variables. | ||||
| 
 | ||||
| ## npm provenance | ||||
| 
 | ||||
| Since GitLab CI is a [supported provider](https://docs.npmjs.com/generating-provenance-statements#provenance-limitations) for [npm provenance](https://docs.npmjs.com/generating-provenance-statements), it is recommended to enable this to increase supply-chain security for your npm packages. | ||||
| Find more detail about configuring npm to publish with provenance through semantic-release [in the documentation for our npm plugin](https://github.com/semantic-release/npm#npm-provenance). | ||||
| 
 | ||||
| ## Node project configuration | ||||
| 
 | ||||
| GitLab CI supports [Pipelines](https://docs.gitlab.com/ee/ci/pipelines.html) allowing to test on multiple Node versions and publishing a release only when all test pass. | ||||
|  | ||||
| @ -195,7 +195,7 @@ If you need more control over the timing of releases, see [Triggering a release] | ||||
| 
 | ||||
| ## Can I set the initial release version of my package to `0.0.1`? | ||||
| 
 | ||||
| This is not supported by semantic-release. [Semantic Versioning](https://semver.org/) rules apply differently to major version zero and supporting those differences is out of scope and not one of the goals of the semantic-release project. | ||||
| This is not supported by **semantic-release** as it's not considered a good practice, mostly because [Semantic Versioning](https://semver.org) rules applies differently to major version zero. | ||||
| 
 | ||||
| If your project is under heavy development, with frequent breaking changes, and is not production ready yet we recommend [publishing pre-releases](../recipes/release-workflow/pre-releases.md#publishing-pre-releases). | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| # Node version requirement | ||||
| 
 | ||||
| **semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 20.8.1 or higher**. | ||||
| **semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 18.0.0 or higher**. | ||||
| 
 | ||||
| **semantic-release** is meant to be used in a CI environment as a development support tool, not as a production dependency. | ||||
| Therefore, the only constraint is to run the `semantic-release` in a CI environment providing version of Node that meets our version requirement. | ||||
|  | ||||
| @ -40,17 +40,6 @@ The following three examples are the same. | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| - Via `release.config.cjs` file: | ||||
| 
 | ||||
| ```js | ||||
| /** | ||||
|  * @type {import('semantic-release').GlobalConfig} | ||||
|  */ | ||||
| module.exports = { | ||||
|   branches: ["master", "next"], | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| - Via CLI argument: | ||||
| 
 | ||||
| ```bash | ||||
|  | ||||
| @ -6,3 +6,16 @@ In order to use **semantic-release** you must follow these steps: | ||||
| 2. Configure your Continuous Integration service to [run **semantic-release**](./ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded) | ||||
| 3. Configure your Git repository and package manager repository [authentication](ci-configuration.md#authentication) in your Continuous Integration service | ||||
| 4. Configure **semantic-release** [options and plugins](./configuration.md#configuration) | ||||
| 
 | ||||
| Alternatively those steps can be easily done with the [**semantic-release** interactive CLI](https://github.com/semantic-release/cli): | ||||
| 
 | ||||
| ```bash | ||||
| cd your-module | ||||
| npx semantic-release-cli setup | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| See the [semantic-release-cli](https://github.com/semantic-release/cli#what-it-does) documentation for more details. | ||||
| 
 | ||||
| **Note**: only a limited number of options, CI services and plugins are currently supported by `semantic-release-cli`. | ||||
|  | ||||
							
								
								
									
										711
									
								
								index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										711
									
								
								index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1,711 +0,0 @@ | ||||
| declare interface AggregateError extends Error { | ||||
|   errors: any[]; | ||||
| } | ||||
| 
 | ||||
| declare module "semantic-release" { | ||||
|   import { Signale } from "signale"; | ||||
|   export interface EnvCi { | ||||
|     /** | ||||
|      * Boolean, true if the environment is a CI environment | ||||
|      */ | ||||
|     isCi: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Commit hash | ||||
|      */ | ||||
|     commit: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Current branch name | ||||
|      */ | ||||
|     branch: string; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Base context used in every semantic release step. | ||||
|    */ | ||||
|   export interface BaseContext { | ||||
|     /** | ||||
|      * stdout for semantic-release process | ||||
|      */ | ||||
|     stdout: NodeJS.WriteStream; | ||||
| 
 | ||||
|     /** | ||||
|      * stderr for semantic-release process | ||||
|      */ | ||||
|     stderr: NodeJS.WriteStream; | ||||
| 
 | ||||
|     /** | ||||
|      * Signale console loger instance. | ||||
|      * | ||||
|      * Has error, log and success methods. | ||||
|      */ | ||||
|     logger: Signale<"error" | "log" | "success">; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the verify conditions step. | ||||
|    */ | ||||
|   export interface VerifyConditionsContext extends BaseContext { | ||||
|     /** | ||||
|      * The current working directory to use. It should be configured to | ||||
|      * the root of the Git repository to release from. | ||||
|      * | ||||
|      * It allows to run semantic-release from a specific path without | ||||
|      * having to change the local process cwd with process.chdir(). | ||||
|      * | ||||
|      * @default process.cwd | ||||
|      */ | ||||
|     cwd?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The environment variables to use. | ||||
|      * | ||||
|      * It allows to run semantic-release with specific environment | ||||
|      * variables without having to modify the local process.env. | ||||
|      * | ||||
|      * @default process.env | ||||
|      */ | ||||
|     env: Record<string, string>; | ||||
| 
 | ||||
|     /** | ||||
|      * Information about the CI environment. | ||||
|      */ | ||||
|     envCi: EnvCi; | ||||
| 
 | ||||
|     /** | ||||
|      * Information of the current branch | ||||
|      */ | ||||
|     branch: BranchObject; | ||||
| 
 | ||||
|     /** | ||||
|      * Information on branches | ||||
|      */ | ||||
|     branches: ReadonlyArray<BranchObject>; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the analyze commits step. | ||||
|    */ | ||||
|   export interface AnalyzeCommitsContext extends VerifyConditionsContext { | ||||
|     /** | ||||
|      * List of commits taken into account when determining the new version. | ||||
|      */ | ||||
|     commits: ReadonlyArray<Commit>; | ||||
| 
 | ||||
|     /** | ||||
|      * List of releases | ||||
|      */ | ||||
|     releases: ReadonlyArray<Release>; | ||||
| 
 | ||||
|     /** | ||||
|      * Last release | ||||
|      */ | ||||
|     lastRelease: LastRelease; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the verify release step. | ||||
|    */ | ||||
|   export interface VerifyReleaseContext extends AnalyzeCommitsContext { | ||||
|     /** | ||||
|      * The next release. | ||||
|      */ | ||||
|     nextRelease: NextRelease; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the generate notes step. | ||||
|    */ | ||||
|   export type GenerateNotesContext = VerifyReleaseContext; | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the add channel step. | ||||
|    */ | ||||
|   export type AddChannelContext = VerifyReleaseContext; | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the prepare step. | ||||
|    */ | ||||
|   export type PrepareContext = VerifyReleaseContext; | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the publish step. | ||||
|    */ | ||||
|   export type PublishContext = VerifyReleaseContext; | ||||
| 
 | ||||
|   /** | ||||
|    * Context used for the success step. | ||||
|    */ | ||||
|   export type SuccessContext = VerifyReleaseContext; | ||||
| 
 | ||||
|   export interface FailContext extends BaseContext { | ||||
|     /** | ||||
|      * Errors that occurred during the release process. | ||||
|      */ | ||||
|     errors: AggregateError; | ||||
|   } | ||||
| 
 | ||||
|   export interface Commit { | ||||
|     /** | ||||
|      * The commit abbreviated and full hash. | ||||
|      */ | ||||
|     commit: { | ||||
|       /** | ||||
|        * The commit hash. | ||||
|        */ | ||||
|       long: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The commit abbreviated hash. | ||||
|        */ | ||||
|       short: string; | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit abbreviated and full tree hash. | ||||
|      */ | ||||
|     tree: { | ||||
|       /** | ||||
|        * The commit tree hash. | ||||
|        */ | ||||
|       long: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The commit abbreviated tree hash. | ||||
|        */ | ||||
|       short: string; | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit author information. | ||||
|      */ | ||||
|     author: { | ||||
|       /** | ||||
|        * The commit author name. | ||||
|        */ | ||||
|       name: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The commit author email. | ||||
|        */ | ||||
|       email: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The commit author date. | ||||
|        */ | ||||
|       short: string; | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * The committer information. | ||||
|      */ | ||||
|     committer: { | ||||
|       /** | ||||
|        * The committer name. | ||||
|        */ | ||||
|       name: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The committer email. | ||||
|        */ | ||||
|       email: string; | ||||
| 
 | ||||
|       /** | ||||
|        * The committer date. | ||||
|        */ | ||||
|       short: string; | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit subject. | ||||
|      */ | ||||
|     subject: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit body. | ||||
|      */ | ||||
|     body: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit full message (subject and body). | ||||
|      */ | ||||
|     message: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The commit hash. | ||||
|      */ | ||||
|     hash: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The committer date. | ||||
|      */ | ||||
|     committerDate: string; | ||||
|   } | ||||
| 
 | ||||
|   export interface BranchObject { | ||||
|     /** | ||||
|      * The name of git branch. | ||||
|      * | ||||
|      * A `name` is required for all types of branch. It can be defined as a | ||||
|      * [glob](https://github.com/micromatch/micromatch#matching-features)
 | ||||
|      * in which case the definition will be expanded to one per matching | ||||
|      * branch existing in the repository. | ||||
|      * | ||||
|      * If `name` doesn't match any branch existing in the repository, the | ||||
|      * definition will be ignored. For example, the default configuration | ||||
|      * includes the definition `next` and `next-major` which will become | ||||
|      * active only  when the branches `next` and/or `next-major` are | ||||
|      * created in the repository. | ||||
|      */ | ||||
|     name: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The distribution channel on which to publish releases from this | ||||
|      * branch. | ||||
|      * | ||||
|      * If this field is set to `false`, then the branch will be released | ||||
|      * on the default distribution channel (for example the `@latest` | ||||
|      * [dist-tag](https://docs.npmjs.com/cli/dist-tag) for npm). This is
 | ||||
|      * also the default behavior for the first | ||||
|      * [release branch](https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#release-branches)
 | ||||
|      * if the channel property is not set. | ||||
|      * | ||||
|      * For all other branches, if the channel property is not set, then the | ||||
|      * channel name will be the same as the branch name. | ||||
|      * | ||||
|      * The value of `channel`, if defined as a string, is generated with | ||||
|      * [Lodash template](https://lodash.com/docs#template) with the
 | ||||
|      * variable `name` set to the branch name. | ||||
|      * | ||||
|      * For example `{name: 'next', channel: 'channel-${name}'}` will be | ||||
|      * expanded to `{name: 'next', channel: 'channel-next'}`. | ||||
|      */ | ||||
|     channel?: string | false | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The range of [semantic versions](https://semver.org/) to support on
 | ||||
|      * this branch. | ||||
|      * | ||||
|      * A `range` only applies to maintenance branches and must be formatted | ||||
|      * like `N.N.x` or `N.x` (`N` is a number). If no range is specified | ||||
|      * but the `name` is formatted as a range, then the branch will be | ||||
|      * considered a maintenance branch and the `name` value will be used | ||||
|      * for the `range`. | ||||
|      * | ||||
|      * Required for maintenance branches, unless `name` is formatted like | ||||
|      * `N.N.x` or `N.x` (`N` is a number). | ||||
|      */ | ||||
|     range?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The pre-release identifier to append to [semantic versions](https://semver.org/)
 | ||||
|      * released from this branch. | ||||
|      * | ||||
|      * A `prerelease` property applies only to pre-release branches and | ||||
|      * the `prerelease` value must be valid per the [Semantic Versioning | ||||
|      * Specification](https://semver.org/#spec-item-9). It will determine
 | ||||
|      * the name of versions. For example if `prerelease` is set to | ||||
|      * `"beta"`, the version will be formatted like `2.0.0-beta.1`, | ||||
|      * `2.0.0-beta.2`, etc. | ||||
|      * | ||||
|      * The value of `prerelease`, if defined as a string, is generated with | ||||
|      * [Lodash template](https://lodash.com/docs#template) with the
 | ||||
|      * variable `name` set to the name of the branch. | ||||
|      * | ||||
|      * If the `prerelease property is set to `true` then the name of the
 | ||||
|      * branch is used as the pre-release identifier. | ||||
|      * | ||||
|      * Required for pre-release branches. | ||||
|      */ | ||||
|     prerelease?: string | boolean | undefined; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Specifies a git branch holding commits to analyze and code to release. | ||||
|    * | ||||
|    * Each branch may be defined either by a string or an object. Specifying | ||||
|    * a string is a shortcut for specifying that string as the `name` field, | ||||
|    * for example `"master"` expands to `{name: "master"}`. | ||||
|    */ | ||||
|   export type BranchSpec = string | BranchObject; | ||||
| 
 | ||||
|   /** | ||||
|    * A semver release type. | ||||
|    * See https://github.com/semantic-release/commit-analyzer/blob/master/lib/default-release-types.js
 | ||||
|    */ | ||||
|   export type ReleaseType = "prerelease" | "prepatch" | "patch" | "preminor" | "minor" | "premajor" | "major"; | ||||
| 
 | ||||
|   /** | ||||
|    * Details of a release published by a publish plugin. | ||||
|    */ | ||||
|   export interface Release { | ||||
|     /** | ||||
|      * The release name, only if set by the corresponding publish plugin. | ||||
|      */ | ||||
|     name?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The release URL, only if set by the corresponding publish plugin. | ||||
|      */ | ||||
|     url?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The semver export type of the release. | ||||
|      */ | ||||
|     type: ReleaseType; | ||||
| 
 | ||||
|     /** | ||||
|      * The version of the release. | ||||
|      */ | ||||
|     version: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The sha of the last commit being part of the release. | ||||
|      */ | ||||
|     gitHead: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The Git tag associated with the release. | ||||
|      */ | ||||
|     gitTag: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The release notes for the release. | ||||
|      */ | ||||
|     notes: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The name of the plugin that published the release. | ||||
|      */ | ||||
|     pluginName: string; | ||||
|   } | ||||
| 
 | ||||
|   export interface LastRelease { | ||||
|     /** | ||||
|      * The version name of the release. | ||||
|      */ | ||||
|     version: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The Git tag of the release. | ||||
|      */ | ||||
|     gitTag: string; | ||||
| 
 | ||||
|     /** | ||||
|      * List of channels the release was published to. | ||||
|      */ | ||||
|     channels: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * The Git checksum of the last commit of the release. | ||||
|      */ | ||||
|     gitHead: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The Release name | ||||
|      */ | ||||
|     name: string; | ||||
|   } | ||||
| 
 | ||||
|   export interface NextRelease extends Omit<LastRelease, "channels"> { | ||||
|     /** | ||||
|      * The semver export type of the release. | ||||
|      */ | ||||
|     type: ReleaseType; | ||||
| 
 | ||||
|     /** | ||||
|      * The release channel of the release. | ||||
|      */ | ||||
|     channel: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The release notes of the next release. | ||||
|      */ | ||||
|     notes?: string | undefined; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Specifies a plugin to use. | ||||
|    * | ||||
|    * The plugin is specified by its module name. | ||||
|    * | ||||
|    * To pass options to a plugin, specify an array containing the plugin module | ||||
|    * name and an options object. | ||||
|    */ | ||||
|   export type PluginSpec<T = any> = string | [string, T]; | ||||
| 
 | ||||
|   /** | ||||
|    * semantic-release options, after normalization and defaults have been | ||||
|    * applied. | ||||
|    */ | ||||
|   export interface GlobalConfig extends Options { | ||||
|     /** | ||||
|      * The branches on which releases should happen. By default | ||||
|      * **semantic-release** will release: | ||||
|      * | ||||
|      *  * regular releases to the default distribution channel from the | ||||
|      *    branch `master` | ||||
|      *  * regular releases to a distribution channel matching the branch | ||||
|      *    name from any existing branch with a name matching a maintenance | ||||
|      *    release range (`N.N.x` or `N.x.x` or `N.x` with `N` being a | ||||
|      *    number) | ||||
|      *  * regular releases to the `next` distribution channel from the | ||||
|      *    branch `next` if it exists | ||||
|      *  * regular releases to the `next-major` distribution channel from | ||||
|      *    the branch `next-major` if it exists. | ||||
|      *  * prereleases to the `beta` distribution channel from the branch | ||||
|      *    `beta` if it exists | ||||
|      *  * prereleases to the `alpha` distribution channel from the branch | ||||
|      *    `alpha` if it exists | ||||
|      * | ||||
|      * **Note**: If your repository does not have a release branch, then | ||||
|      * **semantic-release** will fail with an `ERELEASEBRANCHES` error | ||||
|      * message. If you are using the default configuration, you can fix | ||||
|      * this error by pushing a `master` branch. | ||||
|      * | ||||
|      * **Note**: Once **semantic-release** is configured, any user with the | ||||
|      * permission to push commits on one of those branches will be able to | ||||
|      * publish a release. It is recommended to protect those branches, for | ||||
|      * example with [GitHub protected branches](https://help.github.com/articles/about-protected-branches).
 | ||||
|      * | ||||
|      * See [Workflow configuration](https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#workflow-configuration)
 | ||||
|      * for more details. | ||||
|      */ | ||||
|     branches: ReadonlyArray<BranchSpec> | BranchSpec; | ||||
| 
 | ||||
|     /** | ||||
|      * The git repository URL. | ||||
|      * | ||||
|      * Any valid git url format is supported (see | ||||
|      * [git protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols))
 | ||||
|      * | ||||
|      * Default: `repository` property in `package.json`, or git origin url. | ||||
|      */ | ||||
|     repositoryUrl: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The git tag format used by **semantic-release** to identify | ||||
|      * releases. The tag name is generated with [Lodash template](https://lodash.com/docs#template)
 | ||||
|      * and will be compiled with the `version` variable. | ||||
|      * | ||||
|      * **Note**: The `tagFormat` must contain the `version` variable | ||||
|      * exactly once and compile to a | ||||
|      * [valid git reference](https://git-scm.com/docs/git-check-ref-format#_description).
 | ||||
|      */ | ||||
|     tagFormat: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Define the list of plugins to use. Plugins will run in series, in | ||||
|      * the order defined, for each [step](https://semantic-release.gitbook.io/semantic-release/#release-steps)
 | ||||
|      * if they implement it. | ||||
|      * | ||||
|      * Plugins configuration can be defined by wrapping the name and an | ||||
|      * options object in an array. | ||||
|      * | ||||
|      * See [Plugins configuration](https://semantic-release.gitbook.io/semantic-release/usage/plugins#plugins)
 | ||||
|      * for more details. | ||||
|      * | ||||
|      * Default: `[
 | ||||
|      *     "@semantic-release/commit-analyzer", | ||||
|      *     "@semantic-release/release-notes-generator", | ||||
|      *     "@semantic-release/npm", | ||||
|      *     "@semantic-release/github" | ||||
|      * ]` | ||||
|      */ | ||||
|     plugins: ReadonlyArray<PluginSpec>; | ||||
|   } | ||||
| 
 | ||||
|   /** semantic-release configuration specific for API usage. */ | ||||
|   export interface Config { | ||||
|     /** | ||||
|      * The current working directory to use. It should be configured to | ||||
|      * the root of the Git repository to release from. | ||||
|      * | ||||
|      * It allows to run semantic-release from a specific path without | ||||
|      * having to change the local process cwd with process.chdir(). | ||||
|      * | ||||
|      * @default process.cwd | ||||
|      */ | ||||
|     cwd?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The environment variables to use. | ||||
|      * | ||||
|      * It allows to run semantic-release with specific environment | ||||
|      * variables without having to modify the local process.env. | ||||
|      * | ||||
|      * @default process.env | ||||
|      */ | ||||
|     env?: Record<string, any> | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The writable stream used to log information. | ||||
|      * | ||||
|      * It allows to configure semantic-release to write logs to a specific | ||||
|      * stream rather than the local process.stdout. | ||||
|      * | ||||
|      * @default process.stdout | ||||
|      */ | ||||
|     stdout?: NodeJS.WriteStream | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The writable stream used to log errors. | ||||
|      * | ||||
|      * It allows to configure semantic-release to write errors to a | ||||
|      * specific stream rather than the local process.stderr. | ||||
|      * | ||||
|      * @default process.stderr | ||||
|      */ | ||||
|     stderr?: NodeJS.WriteStream | undefined; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * semantic-release options. | ||||
|    * | ||||
|    * Can be used to set any core option or plugin options. | ||||
|    * Each option will take precedence over options configured in the | ||||
|    * configuration file and shareable configurations. | ||||
|    */ | ||||
|   export interface Options { | ||||
|     /** | ||||
|      * List of modules or file paths containing a | ||||
|      * [shareable configuration](https://semantic-release.gitbook.io/semantic-release/usage/shareable-configurations).
 | ||||
|      * If multiple shareable configurations are set, they will be imported | ||||
|      * in the order defined with each configuration option taking | ||||
|      * precedence over the options defined in a previous shareable | ||||
|      * configuration. | ||||
|      * | ||||
|      * **Note**: Options defined via CLI arguments or in the configuration | ||||
|      * file will take precedence over the ones defined in any shareable | ||||
|      * configuration. | ||||
|      */ | ||||
|     extends?: ReadonlyArray<string> | string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The branches on which releases should happen. By default | ||||
|      * **semantic-release** will release: | ||||
|      * | ||||
|      *  * regular releases to the default distribution channel from the | ||||
|      *    branch `master` | ||||
|      *  * regular releases to a distribution channel matching the branch | ||||
|      *    name from any existing branch with a name matching a maintenance | ||||
|      *    release range (`N.N.x` or `N.x.x` or `N.x` with `N` being a | ||||
|      *    number) | ||||
|      *  * regular releases to the `next` distribution channel from the | ||||
|      *    branch `next` if it exists | ||||
|      *  * regular releases to the `next-major` distribution channel from | ||||
|      *    the branch `next-major` if it exists. | ||||
|      *  * prereleases to the `beta` distribution channel from the branch | ||||
|      *    `beta` if it exists | ||||
|      *  * prereleases to the `alpha` distribution channel from the branch | ||||
|      *    `alpha` if it exists | ||||
|      * | ||||
|      * **Note**: If your repository does not have a release branch, then | ||||
|      * **semantic-release** will fail with an `ERELEASEBRANCHES` error | ||||
|      * message. If you are using the default configuration, you can fix | ||||
|      * this error by pushing a `master` branch. | ||||
|      * | ||||
|      * **Note**: Once **semantic-release** is configured, any user with the | ||||
|      * permission to push commits on one of those branches will be able to | ||||
|      * publish a release. It is recommended to protect those branches, for | ||||
|      * example with [GitHub protected branches](https://help.github.com/articles/about-protected-branches).
 | ||||
|      * | ||||
|      * See [Workflow configuration](https://semantic-release.gitbook.io/semantic-release/usage/workflow-configuration#workflow-configuration)
 | ||||
|      * for more details. | ||||
|      */ | ||||
|     branches?: ReadonlyArray<BranchSpec> | BranchSpec | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The git repository URL. | ||||
|      * | ||||
|      * Any valid git url format is supported (see | ||||
|      * [git protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols))
 | ||||
|      * | ||||
|      * Default: `repository` property in `package.json`, or git origin url. | ||||
|      */ | ||||
|     repositoryUrl?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * The git tag format used by **semantic-release** to identify | ||||
|      * releases. The tag name is generated with [Lodash template](https://lodash.com/docs#template)
 | ||||
|      * and will be compiled with the `version` variable. | ||||
|      * | ||||
|      * **Note**: The `tagFormat` must contain the `version` variable | ||||
|      * exactly once and compile to a | ||||
|      * [valid git reference](https://git-scm.com/docs/git-check-ref-format#_description).
 | ||||
|      */ | ||||
|     tagFormat?: string | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * Define the list of plugins to use. Plugins will run in series, in | ||||
|      * the order defined, for each [step](https://semantic-release.gitbook.io/semantic-release/#release-steps)
 | ||||
|      * if they implement it. | ||||
|      * | ||||
|      * Plugins configuration can be defined by wrapping the name and an | ||||
|      * options object in an array. | ||||
|      * | ||||
|      * See [Plugins configuration](https://semantic-release.gitbook.io/semantic-release/usage/plugins#plugins)
 | ||||
|      * for more details. | ||||
|      * | ||||
|      * Default: `[
 | ||||
|      *     "@semantic-release/commit-analyzer", | ||||
|      *     "@semantic-release/release-notes-generator", | ||||
|      *     "@semantic-release/npm", | ||||
|      *     "@semantic-release/github" | ||||
|      * ]` | ||||
|      */ | ||||
|     plugins?: ReadonlyArray<PluginSpec> | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * Dry-run mode, skip publishing, print next version and release notes. | ||||
|      */ | ||||
|     dryRun?: boolean | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * Set to false to skip Continuous Integration environment verifications. | ||||
|      * This allows for making releases from a local machine. | ||||
|      */ | ||||
|     ci?: boolean | undefined; | ||||
| 
 | ||||
|     /** | ||||
|      * Any other options supported by plugins. | ||||
|      */ | ||||
|     [name: string]: any; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * An object with details of the release if a release was published, or | ||||
|    * false if no release was published. | ||||
|    */ | ||||
|   export type Result = | ||||
|     | false | ||||
|     | { | ||||
|         /** | ||||
|          * Information related to the last release found. | ||||
|          */ | ||||
|         lastRelease: LastRelease; | ||||
| 
 | ||||
|         /** | ||||
|          * The list of commits included in the new release. | ||||
|          */ | ||||
|         commits: Commit[]; | ||||
| 
 | ||||
|         /** | ||||
|          * Information related to the newly published release. | ||||
|          */ | ||||
|         nextRelease: NextRelease; | ||||
| 
 | ||||
|         /** | ||||
|          * The list of releases published, one release per publish plugin. | ||||
|          */ | ||||
|         releases: Release[]; | ||||
|       }; | ||||
| 
 | ||||
|   /** | ||||
|    * Run semantic-release and returns a Promise that resolves to a Result | ||||
|    * object. | ||||
|    * @async | ||||
|    */ | ||||
|   export default function (options: Options, environment?: Config): Promise<Result>; | ||||
| } | ||||
							
								
								
									
										11
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								index.js
									
									
									
									
									
								
							| @ -123,15 +123,12 @@ async function run(context, plugins) { | ||||
|       if (options.dryRun) { | ||||
|         logger.warn(`Skip ${nextRelease.gitTag} tag creation in dry-run mode`); | ||||
|       } else { | ||||
|         await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitTag, { | ||||
|         await addNote({ channels: [...currentRelease.channels, nextRelease.channel] }, nextRelease.gitHead, { | ||||
|           cwd, | ||||
|           env, | ||||
|         }); | ||||
|         await push(options.repositoryUrl, { cwd, env }); | ||||
|         await pushNotes(options.repositoryUrl, nextRelease.gitTag, { | ||||
|           cwd, | ||||
|           env, | ||||
|         }); | ||||
|         await pushNotes(options.repositoryUrl, { cwd, env }); | ||||
|         logger.success( | ||||
|           `Add ${nextRelease.channel ? `channel ${nextRelease.channel}` : "default channel"} to tag ${ | ||||
|             nextRelease.gitTag | ||||
| @ -206,9 +203,9 @@ async function run(context, plugins) { | ||||
|   } else { | ||||
|     // Create the tag before calling the publish plugins as some require the tag to exists
 | ||||
|     await tag(nextRelease.gitTag, nextRelease.gitHead, { cwd, env }); | ||||
|     await addNote({ channels: [nextRelease.channel] }, nextRelease.gitTag, { cwd, env }); | ||||
|     await addNote({ channels: [nextRelease.channel] }, nextRelease.gitHead, { cwd, env }); | ||||
|     await push(options.repositoryUrl, { cwd, env }); | ||||
|     await pushNotes(options.repositoryUrl, nextRelease.gitTag, { cwd, env }); | ||||
|     await pushNotes(options.repositoryUrl, { cwd, env }); | ||||
|     logger.success(`Created tag ${nextRelease.gitTag}`); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -60,7 +60,7 @@ export function release({ release }) { | ||||
|     return release; | ||||
|   } | ||||
| 
 | ||||
|   // The initial lastVersion is the last release from the base branch of `FIRST_RELEASE` (1.0.0)
 | ||||
|   // The intial lastVersion is the last release from the base branch of `FIRST_RELEASE` (1.0.0)
 | ||||
|   let lastVersion = getLatestVersion(tagsToVersions(release[0].tags)) || FIRST_RELEASE; | ||||
| 
 | ||||
|   return release.map(({ name, tags, channel, ...rest }, idx) => { | ||||
|  | ||||
| @ -1,10 +1,11 @@ | ||||
| import { dirname } from "node:path"; | ||||
| import { dirname, resolve } from "node:path"; | ||||
| import { fileURLToPath } from "node:url"; | ||||
| import { createRequire } from "node:module"; | ||||
| 
 | ||||
| import { castArray, isNil, isPlainObject, isString, pickBy } from "lodash-es"; | ||||
| import { readPackageUp } from "read-pkg-up"; | ||||
| import { cosmiconfig } from "cosmiconfig"; | ||||
| import importFrom from "import-from-esm"; | ||||
| import resolveFrom from "resolve-from"; | ||||
| import debugConfig from "debug"; | ||||
| import { repoUrl } from "./git.js"; | ||||
| import PLUGINS_DEFINITIONS from "./definitions/plugins.js"; | ||||
| @ -13,6 +14,7 @@ import { parseConfig, validatePlugin } from "./plugins/utils.js"; | ||||
| 
 | ||||
| const debug = debugConfig("semantic-release:config"); | ||||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||||
| const require = createRequire(import.meta.url); | ||||
| 
 | ||||
| const CONFIG_NAME = "release"; | ||||
| 
 | ||||
| @ -33,7 +35,7 @@ export default async (context, cliOptions) => { | ||||
|     options = { | ||||
|       ...(await castArray(extendPaths).reduce(async (eventualResult, extendPath) => { | ||||
|         const result = await eventualResult; | ||||
|         const extendsOptions = (await importFrom.silent(__dirname, extendPath)) || (await importFrom(cwd, extendPath)); | ||||
|         const extendsOptions = require(resolveFrom.silent(__dirname, extendPath) || resolveFrom(cwd, extendPath)); | ||||
| 
 | ||||
|         // For each plugin defined in a shareable config, save in `pluginsPath` the extendable config path,
 | ||||
|         // so those plugin will be loaded relative to the config file
 | ||||
| @ -74,8 +76,8 @@ export default async (context, cliOptions) => { | ||||
|     plugins: [ | ||||
|       "@semantic-release/commit-analyzer", | ||||
|       "@semantic-release/release-notes-generator", | ||||
|       //"@semantic-release/npm",
 | ||||
|       //"@semantic-release/github",
 | ||||
|       "@semantic-release/npm", | ||||
|       "@semantic-release/github", | ||||
|     ], | ||||
|     // Remove `null` and `undefined` options, so they can be replaced with default ones
 | ||||
|     ...pickBy(options, (option) => !isNil(option)), | ||||
|  | ||||
| @ -36,7 +36,7 @@ function formatAuthUrl(protocol, repositoryUrl, gitCredentials) { | ||||
|  * @param {Object} context semantic-release context. | ||||
|  * @param {String} authUrl Repository URL to verify | ||||
|  * | ||||
|  * @return {String} The authUrl as is if the connection was successful, null otherwise | ||||
|  * @return {String} The authUrl as is if the connection was successfull, null otherwise | ||||
|  */ | ||||
| async function ensureValidAuthUrl({ cwd, env, branch }, authUrl) { | ||||
|   try { | ||||
|  | ||||
| @ -30,11 +30,7 @@ export default ({ branch, options: { tagFormat } }, { before } = {}) => { | ||||
|   const [{ version, gitTag, channels } = {}] = branch.tags | ||||
|     .filter( | ||||
|       (tag) => | ||||
|         ((branch.type === "prerelease" && | ||||
|           tag.channels.some((channel) => isSameChannel(branch.channel, channel)) && | ||||
|           semver | ||||
|             .parse(tag.version) | ||||
|             .prerelease.includes(branch.prerelease === true ? branch.name : branch.prerelease)) || | ||||
|         ((branch.type === "prerelease" && tag.channels.some((channel) => isSameChannel(branch.channel, channel))) || | ||||
|           !semver.prerelease(tag.version)) && | ||||
|         (isUndefined(before) || semver.lt(tag.version, before)) | ||||
|     ) | ||||
|  | ||||
							
								
								
									
										49
									
								
								lib/git.js
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								lib/git.js
									
									
									
									
									
								
							| @ -2,7 +2,6 @@ import gitLogParser from "git-log-parser"; | ||||
| import getStream from "get-stream"; | ||||
| import { execa } from "execa"; | ||||
| import debugGit from "debug"; | ||||
| import { merge } from "lodash-es"; | ||||
| import { GIT_NOTE_REF } from "./definitions/constants.js"; | ||||
| 
 | ||||
| const debug = debugGit("semantic-release:git"); | ||||
| @ -142,9 +141,13 @@ export async function fetch(repositoryUrl, branch, ciBranch, execaOptions) { | ||||
|  */ | ||||
| export async function fetchNotes(repositoryUrl, execaOptions) { | ||||
|   try { | ||||
|     await execa("git", ["fetch", "--unshallow", repositoryUrl, `+refs/notes/*:refs/notes/*`], execaOptions); | ||||
|     await execa( | ||||
|       "git", | ||||
|       ["fetch", "--unshallow", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], | ||||
|       execaOptions | ||||
|     ); | ||||
|   } catch { | ||||
|     await execa("git", ["fetch", repositoryUrl, `+refs/notes/*:refs/notes/*`], { | ||||
|     await execa("git", ["fetch", repositoryUrl, `+refs/notes/${GIT_NOTE_REF}:refs/notes/${GIT_NOTE_REF}`], { | ||||
|       ...execaOptions, | ||||
|       reject: false, | ||||
|     }); | ||||
| @ -243,8 +246,8 @@ export async function push(repositoryUrl, execaOptions) { | ||||
|  * | ||||
|  * @throws {Error} if the push failed. | ||||
|  */ | ||||
| export async function pushNotes(repositoryUrl, ref, execaOptions) { | ||||
|   await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}-${ref}`], execaOptions); | ||||
| export async function pushNotes(repositoryUrl, execaOptions) { | ||||
|   await execa("git", ["push", repositoryUrl, `refs/notes/${GIT_NOTE_REF}`], execaOptions); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -304,26 +307,8 @@ export async function isBranchUpToDate(repositoryUrl, branch, execaOptions) { | ||||
|  * @return {Object} the parsed JSON note if there is one, an empty object otherwise. | ||||
|  */ | ||||
| export async function getNote(ref, execaOptions) { | ||||
|   const handleError = (error) => { | ||||
|     if (error.exitCode === 1) { | ||||
|       return { stdout: "{}" }; | ||||
|     } | ||||
| 
 | ||||
|     debug(error); | ||||
|     throw error; | ||||
|   }; | ||||
| 
 | ||||
|   try { | ||||
|     return merge( | ||||
|       JSON.parse( | ||||
|         // Used for retro-compatibility
 | ||||
|         (await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions).catch(handleError)).stdout | ||||
|       ), | ||||
|       JSON.parse( | ||||
|         (await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "show", ref], execaOptions).catch(handleError)) | ||||
|           .stdout | ||||
|       ) | ||||
|     ); | ||||
|     return JSON.parse((await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout); | ||||
|   } catch (error) { | ||||
|     if (error.exitCode === 1) { | ||||
|       return {}; | ||||
| @ -342,19 +327,5 @@ export async function getNote(ref, execaOptions) { | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  */ | ||||
| export async function addNote(note, ref, execaOptions) { | ||||
|   await execa( | ||||
|     "git", | ||||
|     ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "add", "-f", "-m", JSON.stringify(note), ref], | ||||
|     execaOptions | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the reference of a tag | ||||
|  * | ||||
|  * @param {String} tag The tag name to get the reference of. | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  **/ | ||||
| export async function getTagRef(tag, execaOptions) { | ||||
|   return (await execa("git", ["show-ref", tag, "--hash"], execaOptions)).stdout; | ||||
|   await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-f", "-m", JSON.stringify(note), ref], execaOptions); | ||||
| } | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								media/semantic-release-cli.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/semantic-release-cli.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 65 KiB | 
							
								
								
									
										18523
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										18523
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										93
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								package.json
									
									
									
									
									
								
							| @ -6,8 +6,7 @@ | ||||
|   "author": "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)", | ||||
|   "ava": { | ||||
|     "files": [ | ||||
|       "test/**/*.test.js", | ||||
|       "!test/integration.test.js" | ||||
|       "test/**/*.test.js" | ||||
|     ], | ||||
|     "nodeArguments": [ | ||||
|       "--loader=testdouble", | ||||
| @ -27,30 +26,29 @@ | ||||
|     "Matt Travi <npm@travi.org> (https://matt.travi.org/)" | ||||
|   ], | ||||
|   "dependencies": { | ||||
|     "@semantic-release/commit-analyzer": "^11.0.0", | ||||
|     "@semantic-release/error": "^4.0.0", | ||||
|     "@semantic-release/github": "^9.0.0", | ||||
|     "@semantic-release/npm": "^11.0.0", | ||||
|     "@semantic-release/release-notes-generator": "^12.0.0", | ||||
|     "aggregate-error": "^5.0.0", | ||||
|     "cosmiconfig": "^9.0.0", | ||||
|     "@semantic-release/commit-analyzer": "^10.0.0-beta.1", | ||||
|     "@semantic-release/error": "^3.0.0", | ||||
|     "@semantic-release/github": "9.0.0-beta.2", | ||||
|     "@semantic-release/npm": "^10.0.2", | ||||
|     "@semantic-release/release-notes-generator": "^11.0.0", | ||||
|     "aggregate-error": "^4.0.1", | ||||
|     "cosmiconfig": "^8.0.0", | ||||
|     "debug": "^4.0.0", | ||||
|     "env-ci": "^11.0.0", | ||||
|     "execa": "^8.0.0", | ||||
|     "figures": "^6.0.0", | ||||
|     "env-ci": "^9.0.0", | ||||
|     "execa": "^7.0.0", | ||||
|     "figures": "^5.0.0", | ||||
|     "find-versions": "^5.1.0", | ||||
|     "get-stream": "^6.0.0", | ||||
|     "git-log-parser": "^1.2.0", | ||||
|     "hook-std": "^3.0.0", | ||||
|     "hosted-git-info": "^7.0.0", | ||||
|     "import-from-esm": "^1.3.1", | ||||
|     "hosted-git-info": "^6.0.0", | ||||
|     "lodash-es": "^4.17.21", | ||||
|     "marked": "^11.0.0", | ||||
|     "marked-terminal": "^7.0.0", | ||||
|     "marked": "^4.1.0", | ||||
|     "marked-terminal": "^5.1.1", | ||||
|     "micromatch": "^4.0.2", | ||||
|     "p-each-series": "^3.0.0", | ||||
|     "p-reduce": "^3.0.0", | ||||
|     "read-pkg-up": "^11.0.0", | ||||
|     "read-pkg-up": "^9.1.0", | ||||
|     "resolve-from": "^5.0.0", | ||||
|     "semver": "^7.3.2", | ||||
|     "semver-diff": "^4.0.0", | ||||
| @ -58,37 +56,31 @@ | ||||
|     "yargs": "^17.5.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "ava": "6.1.1", | ||||
|     "c8": "9.1.0", | ||||
|     "ava": "5.2.0", | ||||
|     "c8": "7.14.0", | ||||
|     "clear-module": "4.1.2", | ||||
|     "codecov": "3.8.3", | ||||
|     "cz-conventional-changelog": "3.3.0", | ||||
|     "dockerode": "4.0.2", | ||||
|     "dockerode": "3.3.5", | ||||
|     "file-url": "4.0.0", | ||||
|     "fs-extra": "11.2.0", | ||||
|     "got": "14.2.0", | ||||
|     "fs-extra": "11.1.1", | ||||
|     "got": "12.6.0", | ||||
|     "js-yaml": "4.1.0", | ||||
|     "lockfile-lint": "4.12.1", | ||||
|     "ls-engines": "0.9.1", | ||||
|     "mockserver-client": "5.15.0", | ||||
|     "nock": "13.5.1", | ||||
|     "npm-run-all2": "6.1.2", | ||||
|     "p-retry": "6.2.0", | ||||
|     "prettier": "3.2.5", | ||||
|     "publint": "0.2.7", | ||||
|     "sinon": "17.0.1", | ||||
|     "nock": "13.3.1", | ||||
|     "p-retry": "5.1.2", | ||||
|     "prettier": "2.8.8", | ||||
|     "sinon": "15.1.0", | ||||
|     "stream-buffers": "3.0.2", | ||||
|     "tempy": "3.1.0", | ||||
|     "testdouble": "3.20.1" | ||||
|     "tempy": "3.0.0", | ||||
|     "testdouble": "3.18.0" | ||||
|   }, | ||||
|   "engines": { | ||||
|     "node": ">=20.8.1" | ||||
|     "node": ">=18" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "bin", | ||||
|     "docs", | ||||
|     "lib", | ||||
|     "index.d.ts", | ||||
|     "index.js", | ||||
|     "cli.js" | ||||
|   ], | ||||
| @ -105,8 +97,7 @@ | ||||
|     "version" | ||||
|   ], | ||||
|   "license": "MIT", | ||||
|   "main": "./index.js", | ||||
|   "types": "index.d.ts", | ||||
|   "main": "index.js", | ||||
|   "c8": { | ||||
|     "include": [ | ||||
|       "lib/**/*.js", | ||||
| @ -120,14 +111,6 @@ | ||||
|     ], | ||||
|     "all": true | ||||
|   }, | ||||
|   "lockfile-lint": { | ||||
|     "path": "package-lock.json", | ||||
|     "type": "npm", | ||||
|     "validate-https": true, | ||||
|     "allowed-hosts": [ | ||||
|       "npm" | ||||
|     ] | ||||
|   }, | ||||
|   "prettier": { | ||||
|     "printWidth": 120, | ||||
|     "trailingComma": "es5" | ||||
| @ -140,26 +123,18 @@ | ||||
|     "type": "git", | ||||
|     "url": "git+https://github.com/semantic-release/semantic-release.git" | ||||
|   }, | ||||
|   "config": { | ||||
|     "commitizen": { | ||||
|       "path": "./node_modules/cz-conventional-changelog" | ||||
|     } | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "codecov": "codecov -f coverage/coverage-final.json", | ||||
|     "lint:prettier": "prettier --check \"*.{js,json,md}\" \".github/**/*.{md,yml}\" \"docs/**/*.md\" \"{bin,lib,test}/**/*.js\"", | ||||
|     "lint:prettier:fix": "prettier --write \"*.{js,json,md}\" \".github/**/*.{md,yml}\" \"docs/**/*.md\" \"{bin,lib,test}/**/*.js\"", | ||||
|     "lint:lockfile": "lockfile-lint", | ||||
|     "lint:engines": "ls-engines", | ||||
|     "lint:publish": "publint --strict", | ||||
|     "lint": "prettier --check \"*.{js,json,md}\" \".github/**/*.{md,yml}\" \"docs/**/*.md\" \"{bin,lib,test}/**/*.js\"", | ||||
|     "lint:fix": "prettier --write \"*.{js,json,md}\" \".github/**/*.{md,yml}\" \"docs/**/*.md\" \"{bin,lib,test}/**/*.js\"", | ||||
|     "pretest": "npm run lint", | ||||
|     "semantic-release": "./bin/semantic-release.js", | ||||
|     "test": "npm-run-all --print-label --parallel lint:* --parallel test:*", | ||||
|     "test:unit": "c8 ava --verbose", | ||||
|     "test:integration": "ava --verbose test/integration.test.js" | ||||
|     "test": "c8 ava --verbose", | ||||
|     "test:ci": "c8 ava --verbose" | ||||
|   }, | ||||
|   "renovate": { | ||||
|     "extends": [ | ||||
|       "github>semantic-release/.github:renovate-config" | ||||
|       "github>semantic-release/.github" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -389,92 +389,6 @@ test.serial('Read configuration from an array of paths in "extends"', async (t) | ||||
|   t.deepEqual(result, { options: expectedOptions, plugins: pluginsConfig }); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Read configuration from an array of CJS files in "extends"', async (t) => { | ||||
|   // Create a git repository, set the current working directory at the root of the repo
 | ||||
|   const { cwd } = await gitRepo(); | ||||
|   const pkgOptions = { extends: ["./shareable1.cjs", "./shareable2.cjs"] }; | ||||
|   const options1 = { | ||||
|     verifyRelease: "verifyRelease1", | ||||
|     analyzeCommits: { path: "analyzeCommits1", param: "analyzeCommits_param1" }, | ||||
|     branches: ["test_branch"], | ||||
|     repositoryUrl: "https://host.null/owner/module.git", | ||||
|   }; | ||||
|   const options2 = { | ||||
|     verifyRelease: "verifyRelease2", | ||||
|     generateNotes: "generateNotes2", | ||||
|     analyzeCommits: { path: "analyzeCommits2", param: "analyzeCommits_param2" }, | ||||
|     branches: ["test_branch"], | ||||
|     tagFormat: `v\${version}`, | ||||
|     plugins: false, | ||||
|   }; | ||||
|   // Create package.json and shareable.json in repository root
 | ||||
|   await outputJson(path.resolve(cwd, "package.json"), { release: pkgOptions }); | ||||
|   await writeFile(path.resolve(cwd, "shareable1.cjs"), `module.exports = ${JSON.stringify(options1)}`); | ||||
|   await writeFile(path.resolve(cwd, "shareable2.cjs"), `module.exports = ${JSON.stringify(options2)}`); | ||||
|   const expectedOptions = { ...options1, ...options2, branches: ["test_branch"] }; | ||||
|   // Verify the plugins module is called with the plugin options from shareable1.mjs and shareable2.mjs
 | ||||
|   td.when( | ||||
|     plugins( | ||||
|       { options: expectedOptions, cwd }, | ||||
|       { | ||||
|         verifyRelease1: "./shareable1.cjs", | ||||
|         verifyRelease2: "./shareable2.cjs", | ||||
|         generateNotes2: "./shareable2.cjs", | ||||
|         analyzeCommits1: "./shareable1.cjs", | ||||
|         analyzeCommits2: "./shareable2.cjs", | ||||
|       } | ||||
|     ) | ||||
|   ).thenResolve(pluginsConfig); | ||||
| 
 | ||||
|   const result = await t.context.getConfig({ cwd }); | ||||
| 
 | ||||
|   // Verify the options contains the plugin config from shareable1.json and shareable2.json
 | ||||
|   t.deepEqual(result, { options: expectedOptions, plugins: pluginsConfig }); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Read configuration from an array of ESM files in "extends"', async (t) => { | ||||
|   // Create a git repository, set the current working directory at the root of the repo
 | ||||
|   const { cwd } = await gitRepo(); | ||||
|   const pkgOptions = { extends: ["./shareable1.mjs", "./shareable2.mjs"] }; | ||||
|   const options1 = { | ||||
|     verifyRelease: "verifyRelease1", | ||||
|     analyzeCommits: { path: "analyzeCommits1", param: "analyzeCommits_param1" }, | ||||
|     branches: ["test_branch"], | ||||
|     repositoryUrl: "https://host.null/owner/module.git", | ||||
|   }; | ||||
|   const options2 = { | ||||
|     verifyRelease: "verifyRelease2", | ||||
|     generateNotes: "generateNotes2", | ||||
|     analyzeCommits: { path: "analyzeCommits2", param: "analyzeCommits_param2" }, | ||||
|     branches: ["test_branch"], | ||||
|     tagFormat: `v\${version}`, | ||||
|     plugins: false, | ||||
|   }; | ||||
|   // Create package.json and shareable.json in repository root
 | ||||
|   await outputJson(path.resolve(cwd, "package.json"), { release: pkgOptions }); | ||||
|   await writeFile(path.resolve(cwd, "shareable1.mjs"), `export default ${JSON.stringify(options1)}`); | ||||
|   await writeFile(path.resolve(cwd, "shareable2.mjs"), `export default ${JSON.stringify(options2)}`); | ||||
|   const expectedOptions = { ...options1, ...options2, branches: ["test_branch"] }; | ||||
|   // Verify the plugins module is called with the plugin options from shareable1.mjs and shareable2.mjs
 | ||||
|   td.when( | ||||
|     plugins( | ||||
|       { options: expectedOptions, cwd }, | ||||
|       { | ||||
|         verifyRelease1: "./shareable1.mjs", | ||||
|         verifyRelease2: "./shareable2.mjs", | ||||
|         generateNotes2: "./shareable2.mjs", | ||||
|         analyzeCommits1: "./shareable1.mjs", | ||||
|         analyzeCommits2: "./shareable2.mjs", | ||||
|       } | ||||
|     ) | ||||
|   ).thenResolve(pluginsConfig); | ||||
| 
 | ||||
|   const result = await t.context.getConfig({ cwd }); | ||||
| 
 | ||||
|   // Verify the options contains the plugin config from shareable1.json and shareable2.json
 | ||||
|   t.deepEqual(result, { options: expectedOptions, plugins: pluginsConfig }); | ||||
| }); | ||||
| 
 | ||||
| test.serial('Prioritize configuration from config file over "extends"', async (t) => { | ||||
|   // Create a git repository, set the current working directory at the root of the repo
 | ||||
|   const { cwd } = await gitRepo(); | ||||
|  | ||||
| @ -43,43 +43,6 @@ test("Get the highest prerelease valid tag, ignoring other tags from other prere | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| test("Get the correct prerelease tag, when other prereleases share the same git HEAD", (t) => { | ||||
|   const testConfig = { | ||||
|     branch: { | ||||
|       name: "alpha", | ||||
|       prerelease: "alpha", | ||||
|       channel: "alpha", | ||||
|       tags: [ | ||||
|         { version: "1.0.0-beta.1", gitTag: "v1.0.0-beta.1", gitHead: "v1.0.0-beta.1", channels: ["beta"] }, | ||||
|         { version: "1.0.0-beta.2", gitTag: "v1.0.0-beta.2", gitHead: "v1.0.0-alpha.1", channels: ["alpha", "beta"] }, | ||||
|         { version: "1.0.0-alpha.1", gitTag: "v1.0.0-alpha.1", gitHead: "v1.0.0-alpha.1", channels: ["alpha", "beta"] }, | ||||
|       ], | ||||
|       type: "prerelease", | ||||
|     }, | ||||
|     options: { tagFormat: `v\${version}`, debug: true }, | ||||
|   }; | ||||
|   const firstResult = getLastRelease(testConfig); | ||||
| 
 | ||||
|   t.deepEqual(firstResult, { | ||||
|     version: "1.0.0-alpha.1", | ||||
|     gitTag: "v1.0.0-alpha.1", | ||||
|     name: "v1.0.0-alpha.1", | ||||
|     gitHead: "v1.0.0-alpha.1", | ||||
|     channels: ["alpha", "beta"], | ||||
|   }); | ||||
| 
 | ||||
|   testConfig.branch.prerelease = true; | ||||
|   const secondResult = getLastRelease(testConfig); | ||||
| 
 | ||||
|   t.deepEqual(secondResult, { | ||||
|     version: "1.0.0-alpha.1", | ||||
|     gitTag: "v1.0.0-alpha.1", | ||||
|     name: "v1.0.0-alpha.1", | ||||
|     gitHead: "v1.0.0-alpha.1", | ||||
|     channels: ["alpha", "beta"], | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| test("Return empty object if no valid tag is found", (t) => { | ||||
|   const result = getLastRelease({ | ||||
|     branch: { | ||||
|  | ||||
| @ -275,24 +275,3 @@ test("Increase version for release on prerelease branch when there is no regular | ||||
|     "1.0.0-beta.2" | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| test("Increase patch when previous version shares HEAD with other releases", (t) => { | ||||
|   t.is( | ||||
|     getNextVersion({ | ||||
|       branch: { | ||||
|         name: "alpha", | ||||
|         type: "prerelease", | ||||
|         prerelease: "alpha", | ||||
|         tags: [ | ||||
|           { gitTag: "v1.0.0-beta.1", version: "1.0.0-beta.1", channels: ["beta"] }, | ||||
|           { gitTag: "v1.0.0-beta.2", version: "1.0.0-beta.2", channels: ["alpha", "beta"] }, | ||||
|           { gitTag: "v1.0.0-alpha.1", version: "1.0.0-alpha.1", channels: ["alpha", "beta"] }, | ||||
|         ], | ||||
|       }, | ||||
|       nextRelease: { type: "patch", channel: "alpha" }, | ||||
|       lastRelease: { version: "v1.0.0-alpha.1", channels: ["alpha", "beta"] }, | ||||
|       logger: t.context.logger, | ||||
|     }), | ||||
|     "1.0.0-alpha.2" | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| @ -43,7 +43,7 @@ export async function initGit(withRemote) { | ||||
|  * | ||||
|  * @param {Boolean} withRemote `true` to create a shallow clone of a bare repository. | ||||
|  * @param {String} [branch='master'] The branch to initialize. | ||||
|  * @return {Promise<Object>} The path of the clone if `withRemote` is `true`, the path of the repository otherwise. | ||||
|  * @return {String} The path of the clone if `withRemote` is `true`, the path of the repository otherwise. | ||||
|  */ | ||||
| export async function gitRepo(withRemote, branch = "master") { | ||||
|   let { cwd, repositoryUrl } = await initGit(withRemote); | ||||
| @ -90,7 +90,9 @@ export async function gitCommits(messages, execaOptions) { | ||||
|   await pEachSeries( | ||||
|     messages, | ||||
|     async (message) => | ||||
|       (await execa("git", ["commit", "-m", message, "--allow-empty", "--no-gpg-sign"], execaOptions)).stdout | ||||
|       ( | ||||
|         await execa("git", ["commit", "-m", message, "--allow-empty", "--no-gpg-sign"], execaOptions) | ||||
|       ).stdout | ||||
|   ); | ||||
|   return (await gitGetCommits(undefined, execaOptions)).slice(0, messages.length); | ||||
| } | ||||
| @ -98,7 +100,7 @@ export async function gitCommits(messages, execaOptions) { | ||||
| /** | ||||
|  * Get the list of parsed commits since a git reference. | ||||
|  * | ||||
|  * @param {String} [from] Git reference from which to search commits. | ||||
|  * @param {String} [from] Git reference from which to seach commits. | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  * | ||||
|  * @return {Array<Object>} The list of parsed commits. | ||||
| @ -240,7 +242,7 @@ export async function gitTagHead(tagName, execaOptions) { | ||||
|  * Get the first commit sha referenced by the tag `tagName` in the remote repository. | ||||
|  * | ||||
|  * @param {String} repositoryUrl The repository remote URL. | ||||
|  * @param {String} tagName The tag name to search for. | ||||
|  * @param {String} tagName The tag name to seach for. | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  * | ||||
|  * @return {String} The sha of the commit associated with `tagName` on the remote repository. | ||||
| @ -315,7 +317,7 @@ export async function rebase(ref, execaOptions) { | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  */ | ||||
| export async function gitAddNote(note, ref, execaOptions) { | ||||
|   await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "add", "-m", note, ref], execaOptions); | ||||
|   await execa("git", ["notes", "--ref", GIT_NOTE_REF, "add", "-m", note, ref], execaOptions); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -325,5 +327,5 @@ export async function gitAddNote(note, ref, execaOptions) { | ||||
|  * @param {Object} [execaOpts] Options to pass to `execa`. | ||||
|  */ | ||||
| export async function gitGetNote(ref, execaOptions) { | ||||
|   return (await execa("git", ["notes", "--ref", `${GIT_NOTE_REF}-${ref}`, "show", ref], execaOptions)).stdout; | ||||
|   return (await execa("git", ["notes", "--ref", GIT_NOTE_REF, "show", ref], execaOptions)).stdout; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import Docker from "dockerode"; | ||||
| import getStream from "get-stream"; | ||||
| import pRetry from "p-retry"; | ||||
| import { gitShallowClone, initBareRepo } from "./git-utils.js"; | ||||
| 
 | ||||
| @ -14,20 +15,11 @@ let container; | ||||
| export const gitCredential = `${GIT_USERNAME}:${GIT_PASSWORD}`; | ||||
| 
 | ||||
| /** | ||||
|  * Download the `gitbox` Docker image | ||||
|  */ | ||||
| export function pull() { | ||||
|   return docker.pull(IMAGE).then((stream) => { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       docker.modem.followProgress(stream, (err, res) => (err ? reject(err) : resolve(res))); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * create a new container and start it. | ||||
|  * Download the `gitbox` Docker image, create a new container and start it. | ||||
|  */ | ||||
| export async function start() { | ||||
|   await getStream(await docker.pull(IMAGE)); | ||||
| 
 | ||||
|   container = await docker.createContainer({ | ||||
|     Tty: true, | ||||
|     Image: IMAGE, | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import Docker from "dockerode"; | ||||
| import getStream from "get-stream"; | ||||
| import got from "got"; | ||||
| import pRetry from "p-retry"; | ||||
| import { mockServerClient } from "mockserver-client"; | ||||
| @ -10,20 +11,11 @@ const docker = new Docker(); | ||||
| let container; | ||||
| 
 | ||||
| /** | ||||
|  * Download the `mockserver` Docker image, | ||||
|  */ | ||||
| export function pull() { | ||||
|   return docker.pull(IMAGE).then((stream) => { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       docker.modem.followProgress(stream, (err, res) => (err ? reject(err) : resolve(res))); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * create a new container and start it. | ||||
|  * Download the `mockserver` Docker image, create a new container and start it. | ||||
|  */ | ||||
| export async function start() { | ||||
|   await getStream(await docker.pull(IMAGE)); | ||||
| 
 | ||||
|   container = await docker.createContainer({ | ||||
|     Tty: true, | ||||
|     Image: IMAGE, | ||||
|  | ||||
| @ -2,6 +2,7 @@ import path, { dirname } from "node:path"; | ||||
| import { fileURLToPath } from "node:url"; | ||||
| import { setTimeout } from "node:timers/promises"; | ||||
| import Docker from "dockerode"; | ||||
| import getStream from "get-stream"; | ||||
| import got from "got"; | ||||
| import pRetry from "p-retry"; | ||||
| 
 | ||||
| @ -16,20 +17,11 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); | ||||
| let container, npmToken; | ||||
| 
 | ||||
| /** | ||||
|  * Download the `npm-registry-docker` Docker image | ||||
|  */ | ||||
| export function pull() { | ||||
|   return docker.pull(IMAGE).then((stream) => { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       docker.modem.followProgress(stream, (err, res) => (err ? reject(err) : resolve(res))); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * create a new container and start it. | ||||
|  * Download the `npm-registry-docker` Docker image, create a new container and start it. | ||||
|  */ | ||||
| export async function start() { | ||||
|   await getStream(await docker.pull(IMAGE)); | ||||
| 
 | ||||
|   container = await docker.createContainer({ | ||||
|     Tty: true, | ||||
|     Image: IMAGE, | ||||
|  | ||||
| @ -11,7 +11,7 @@ test("Replace multiple sensitive environment variable values", (t) => { | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| test("Replace multiple occurrences of sensitive environment variable values", (t) => { | ||||
| test("Replace multiple occurences of sensitive environment variable values", (t) => { | ||||
|   const env = { secretKey: "secret" }; | ||||
|   t.is( | ||||
|     hideSensitive(env)(`https://user:${env.secretKey}@host.com?token=${env.secretKey}`), | ||||
|  | ||||
| @ -1853,19 +1853,10 @@ test.serial("Throw an Error if plugin returns an unexpected value", async (t) => | ||||
|   await td.replaceEsm("../lib/get-logger.js", null, () => t.context.logger); | ||||
|   await td.replaceEsm("env-ci", null, () => ({ isCi: true, branch: "master", isPr: false })); | ||||
|   const semanticRelease = (await import("../index.js")).default; | ||||
| 
 | ||||
|   let error; | ||||
|   try { | ||||
|     await semanticRelease(options, { | ||||
|       cwd, | ||||
|       env: {}, | ||||
|       stdout: new WritableStreamBuffer(), | ||||
|       stderr: new WritableStreamBuffer(), | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     error = e; | ||||
|   } | ||||
|   t.is(error.code, "EANALYZECOMMITSOUTPUT"); | ||||
|   const error = await t.throwsAsync( | ||||
|     semanticRelease(options, { cwd, env: {}, stdout: new WritableStreamBuffer(), stderr: new WritableStreamBuffer() }), | ||||
|     { instanceOf: SemanticReleaseError } | ||||
|   ); | ||||
|   t.regex(error.details, /string/); | ||||
| }); | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,7 @@ let env; | ||||
| 
 | ||||
| // Environment variables used only for the local npm command used to do verification
 | ||||
| const npmTestEnv = { | ||||
|   ...processEnvWithoutGitHubActionsVariables, | ||||
|   ...process.env, | ||||
|   ...npmRegistry.authEnv(), | ||||
|   npm_config_registry: npmRegistry.url, | ||||
| }; | ||||
| @ -47,7 +47,6 @@ const pluginLogEnv = path.resolve("./test/fixtures/plugin-log-env"); | ||||
| const pluginEsmNamedExports = path.resolve("./test/fixtures/plugin-esm-named-exports"); | ||||
| 
 | ||||
| test.before(async () => { | ||||
|   await Promise.all([gitbox.pull(), npmRegistry.pull(), mockServer.pull()]); | ||||
|   await Promise.all([gitbox.start(), npmRegistry.start(), mockServer.start()]); | ||||
| 
 | ||||
|   env = { | ||||
| @ -516,8 +515,8 @@ test("Pass options via CLI arguments", async (t) => { | ||||
| }); | ||||
| 
 | ||||
| test("Run via JS API", async (t) => { | ||||
|   await td.replaceEsm("../lib/logger", null, { log: () => {}, error: () => {}, stdout: () => {} }); | ||||
|   await td.replaceEsm("env-ci", null, () => ({ isCi: true, branch: "master", isPr: false })); | ||||
|   td.replace("../lib/logger", { log: () => {}, error: () => {}, stdout: () => {} }); | ||||
|   td.replace("env-ci", () => ({ isCi: true, branch: "master", isPr: false })); | ||||
|   const semanticRelease = (await import("../index.js")).default; | ||||
|   const packageName = "test-js-api"; | ||||
|   const owner = "git"; | ||||
|  | ||||
| @ -96,7 +96,7 @@ test("Normalize and load plugin from function", async (t) => { | ||||
|   t.is(typeof plugin, "function"); | ||||
| }); | ||||
| 
 | ||||
| test("Normalize and load plugin that returns multiple functions", async (t) => { | ||||
| test("Normalize and load plugin that retuns multiple functions", async (t) => { | ||||
|   const plugin = await normalize( | ||||
|     { cwd, options: {}, logger: t.context.logger }, | ||||
|     "verifyConditions", | ||||
|  | ||||
| @ -52,7 +52,7 @@ test("validateStep: optional plugin configuration", (t) => { | ||||
|   t.true(validateStep(type, { path: () => {}, options: "value" })); | ||||
|   t.false(validateStep(type, { path: null })); | ||||
| 
 | ||||
|   // Considered as an Array of 2 definitions and not as one Array definition in case of a multiple plugin type
 | ||||
|   // Considered as an Array of 2 definitions and not as one Array definition in case of a muliple plugin type
 | ||||
|   t.false(validateStep(type, [() => {}, { options: "value" }])); | ||||
|   t.false(validateStep(type, ["plugin-path.js", { options: "value" }])); | ||||
| 
 | ||||
| @ -134,7 +134,7 @@ test("validateStep: required plugin configuration", (t) => { | ||||
|   t.true(validateStep(type, { path: () => {}, options: "value" })); | ||||
|   t.false(validateStep(type, { path: null })); | ||||
| 
 | ||||
|   // Considered as an Array of 2 definitions and not as one Array definition in the case of a multiple plugin type
 | ||||
|   // Considered as an Array of 2 definitions and not as one Array definition in the case of a muliple plugin type
 | ||||
|   t.false(validateStep(type, [() => {}, { options: "value" }])); | ||||
|   t.false(validateStep(type, ["plugin-path.js", { options: "value" }])); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user