feat: Refactor CLI to run with one command, improve logs, modularize, add tests

- Run with one command and do not rely on error exit codes to stop the process when a release is not necessary
- Break `index.js` in smaller modules in order to improve testability and simplify the code
- Add several missing unit and integration tests to reach 100% coverage
- Integration tests now test end to end, including publishing to Github (with http://www.mock-server.com on Docker)
- Use `tj/commander.js` to print an help message, verify and parse CLI arguments
- Semantic-release can now be called via Javascript API: `require('semantic-release')(options)`
- Remove npmlog dependency and add more log messages
- Logger is now passed to plugins
- Add debug logs with `visionmedia/debug`. `debug` is enabled for both semantic-release and plugins with `--debug`
- Use `kevva/npm-conf` in place of the deprecated `npm/npmconf`
- Pass lastRelease, nextRelease and commits to generate-notes plugin
- In dry-run mode, print the release note instead of publishing it to Github as draft, and skip the CI verifications
- The dry-run mode does not require npm and Github TOKEN to be set anymore and can be run locally

BREAKING CHANGE: Semantic-Release must now be executed with `semantic-release` instead of `semantic-release pre && npm publish && semantic-release post`.
BREAKING CHANGE: The `semantic-release` command now returns with exit code 0 on expected exception (no release has to be done, running on a PR, gitHead not found, other CI job failed etc...). It only returns with 1 when there is an unexpected error (code error in a plugin, plugin not found, git command cannot be run etc..).
BREAKING CHANGE: Calling the `semantic-release` command with unexpected argument(s) now exit with 1 and print an help message.
BREAKING CHANGE: Semantic-Release does not rely on `npmlog` anymore and the log level cannot be configured. Debug logs can be activated with CLI option `--debug` or with environment variable `DEBUG=semantic-release:*`
BREAKING CHANGE: The CLI options `--debug` doesn't enable the dry-run mode anymore but activate the debugs. The dry run mode is now set with the CLI command `--dry-run` or `-d`.
This commit is contained in:
Pierre-Denis Vanduynslager
2017-10-27 18:07:13 -07:00
committed by Gregor Martynus
parent 1bd095d26c
commit e2a8a5cd32
39 changed files with 1857 additions and 1041 deletions
+28 -9
View File
@@ -83,11 +83,17 @@ When `semantic-release` is set up it will do that after every successful continu
If you fear the loss of control over timing and marketing implications of software releases you should know that `semantic-release` supports [release channels](https://github.com/npm/npm/issues/2718) using `npm`’s [dist-tags](https://docs.npmjs.com/cli/dist-tag). This way you can keep control over what your users end up using by default, you can decide when to promote an automatically released version to the stable channel, and you can choose which versions to write blogposts and tweets about. You can use the same mechanism to [support older versions of your software](https://gist.github.com/boennemann/54042374e49c7ade8910), for example with important security fixes.
This is what happens in series:
When pushing new commits with `git push` a CI build is triggered. After running the tests the command `semantic-release` will execute the following tasks in series:
| 1. `git push` | 2. `semantic-release pre` | 3. `npm publish` | 4. `semantic-release post` |
| :--- | :--- | :--- | :---- |
| New code is pushed and triggers a CI build. | Based on all commits that happened since the last release, the new version number gets written to the `package.json`. | The new version gets published to `npm`. | A changelog gets generated and a [release](https://help.github.com/articles/about-releases/) (including a git tag) on GitHub gets created. |
| Step | Description |
| ------------------ | ------------------------------------------------------------------------------------------- |
| Verify Conditions` | Run the [verifyConditions](#verifyConditions) plugin) |
| Get last release` | Obtain last release with the [getLastRelease](#getLastRelease) plugin |
| Analyze commits | Determine the type of release to do with the [analyzeCommits](#analyzeCommits) plugin |
| Verify release | Call the [verifyRelease](#verifyRelease) plugin |
| npm publish | Update the version in `package.json` and call `npm publish` |
| Generate notes | Generate release notes with plugin [generateNotes](#generateNotes) |
| Github release | A git tag and [Github release](https://help.github.com/articles/about-releases/) is created |
_Note:_ The current release/tag implementation is tied to GitHub, but could be opened up to Bitbucket, GitLab, et al. Feel free to send PRs for these services.
@@ -147,14 +153,25 @@ _[This is what happens under the hood.](https://github.com/semantic-release/cli#
You can pass options either via command line (in [kebab-case](https://lodash.com/docs#kebabCase)) or in the `release` field of your `package.json` (in [camelCase](https://lodash.com/docs#camelCase)). The following two examples are the same, but CLI arguments take precedence.
| CLI | package.json |
| --- | --- |
| <pre><code>semantic-release pre --no-debug</code><pre> | <pre><code><div>//package.json</div><div>"release": {</div><div> "debug": false</div><div>}</div></code></pre><pre><code>semantic-release pre</code></pre> |
##### CLI
```bash
semantic-release --branch next
```
##### package.json
```json
"release": {
"branch": "next"
}
```
```bash
semantic-release
```
These options are currently available:
- `branch`: The branch on which releases should happen. Default: `'master'`
- `debug`: If true doesn’t actually publish to npm or write things to file. Default: `!process.env.CI`
- `dry-run`: Dry-run mode, skipping verifyConditions, publishing and release, printing next version and release notes
- `debug`: Output debugging information
- `githubToken`: The token used to authenticate with GitHub. Default: `process.env.GH_TOKEN`
- `githubUrl`: Optional. Pass your GitHub Enterprise endpoint.
- `githubApiPathPrefix`: Optional. The path prefix for your GitHub Enterprise API.
@@ -181,11 +198,12 @@ There are numerous steps where you can customize `semantic-release`’s behaviou
"path": "./path/to/a/module",
"additional": "config"
}
}
}
```
```
semantic-release pre --analyze-commits="npm-module-name"
semantic-release --analyze-commits="npm-module-name"
```
A plugin itself is an async function that always receives three arguments.
@@ -215,6 +233,7 @@ Have a look at the [default implementation](https://github.com/semantic-release/
### `generateNotes`
This plugin is responsible for generating release notes. Call the callback with the notes as a string. Have a look at the [default implementation](https://github.com/semantic-release/release-notes-generator/).
It receives a `commits` array, the `lastRelease` and `nextRelease` inside `config`.
### `verifyConditions`