Compare commits
+2
-2
@@ -7,11 +7,11 @@ node_js:
|
||||
- 10
|
||||
- 8
|
||||
|
||||
# Trigger a push build on caribou and greenkeeper branches + PRs build on every branches
|
||||
# Trigger a push build on master and greenkeeper branches + PRs build on every branches
|
||||
# Avoid double build on PRs (See https://github.com/travis-ci/travis-ci/issues/1147)
|
||||
branches:
|
||||
only:
|
||||
- caribou
|
||||
- master
|
||||
- /^greenkeeper.*$/
|
||||
|
||||
# Retry install on fail to avoid failing a build on network/disk/external errors
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<h1 align="center" style="border-bottom: none;">📦🚀 semantic-release</h1>
|
||||
<h3 align="center">Fully automated version management and package publishing</h3>
|
||||
<p align="center">
|
||||
<a href="https://gitter.im/semantic-release/semantic-release">
|
||||
<img alt="Gitter" src="https://badges.gitter.im/semantic-release/semantic-release.svg">
|
||||
<a href="https://spectrum.chat/semantic-release">
|
||||
<img alt="Join the community on Spectrum" src="https://withspectrum.github.io/badge/badge.svg">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/semantic-release/semantic-release">
|
||||
<img alt="Travis" src="https://img.shields.io/travis/semantic-release/semantic-release/caribou.svg">
|
||||
<img alt="Travis" src="https://img.shields.io/travis/semantic-release/semantic-release/master.svg">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/semantic-release/semantic-release">
|
||||
<img alt="Codecov" src="https://img.shields.io/codecov/c/github/semantic-release/semantic-release/caribou.svg">
|
||||
<img alt="Codecov" src="https://img.shields.io/codecov/c/github/semantic-release/semantic-release/master.svg">
|
||||
</a>
|
||||
<a href="https://greenkeeper.io">
|
||||
<img alt="Greenkeeper" src="https://badges.greenkeeper.io/semantic-release/semantic-release.svg">
|
||||
@@ -124,7 +124,7 @@ After running the tests, the command `semantic-release` will execute the followi
|
||||
## Get help
|
||||
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/semantic-release)
|
||||
- [Gitter chat](https://gitter.im/semantic-release/semantic-release)
|
||||
- [Spectrum community](https://spectrum.chat/semantic-release)
|
||||
- [Twitter](https://twitter.com/SemanticRelease)
|
||||
|
||||
## Badge
|
||||
|
||||
@@ -16,7 +16,7 @@ if (!semver.satisfies(process.version, pkg.engines.node)) {
|
||||
console.error(
|
||||
`[semantic-release]: node version ${pkg.engines.node} is required. Found ${process.version}.
|
||||
|
||||
See https://github.com/semantic-release/semantic-release/blob/caribou/docs/support/node-version.md for more details and solutions.`
|
||||
See https://github.com/semantic-release/semantic-release/blob/master/docs/support/node-version.md for more details and solutions.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -47,11 +47,6 @@ Usage:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the `noCi` options as yargs sets the `ci` options instead (because arg starts with `--no`)
|
||||
if (opts.ci === false) {
|
||||
opts.noCi = true;
|
||||
}
|
||||
|
||||
if (opts.debug) {
|
||||
// Debug must be enabled before other requires in order to work
|
||||
require('debug').enable('semantic-release:*');
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
codecov:
|
||||
branch: caribou
|
||||
@@ -26,23 +26,27 @@
|
||||
- [@semantic-release/exec](https://github.com/semantic-release/exec)
|
||||
- `verifyConditions`: Execute a shell command to verify if the release should happen
|
||||
- `analyzeCommits`: Execute a shell command to determine the type of release
|
||||
- `verifyRelease`: Execute a shell command to verifying a release that was determined before and is about to be published.
|
||||
- `verifyRelease`: Execute a shell command to verifying a release that was determined before and is about to be published
|
||||
- `generateNotes`: Execute a shell command to generate the release note
|
||||
- `prepare`: Execute a shell command to prepare the release
|
||||
- `publish`: Execute a shell command to publish the release
|
||||
- `success`: Execute a shell command to notify of a new release
|
||||
- `fail`: Execute a shell command to notify of a failed release
|
||||
- [@semantic-release/apm](https://github.com/semantic-release/apm)
|
||||
- `verifyConditions`: Verify the presence of the `ATOM_ACCESS_TOKEN` environment variable and the [`apm`](https://github.com/atom/apm) CLI
|
||||
- `prepare`: Update the `package.json` version with [`npm version`](https://docs.npmjs.com/cli/version)
|
||||
- `publish`: Publish the [Atom package](https://flight-manual.atom.io/hacking-atom/sections/publishing)
|
||||
|
||||
## Community plugins
|
||||
|
||||
[Open a Pull Request](https://github.com/semantic-release/semantic-release/blob/caribou/CONTRIBUTING.md#submitting-a-pull-request) to add your plugin to the list.
|
||||
[Open a Pull Request](https://github.com/semantic-release/semantic-release/blob/master/CONTRIBUTING.md#submitting-a-pull-request) to add your plugin to the list.
|
||||
|
||||
- [semantic-release-docker](https://github.com/felixfbecker/semantic-release-docker)
|
||||
- `verifyConditions`: Verify that all needed configuration is present and login to the Docker registry.
|
||||
- `publish`: Tag the image specified by `name` with the new version, push it to Docker Hub and update the latest tag.
|
||||
- `publish`: Tag the image specified by `name` with the new version, push it to Docker Hub and update the latest tag
|
||||
- [semantic-release-gcr](https://github.com/carlos-cubas/semantic-release-gcr)
|
||||
- `verifyConditions`: Verify that all needed configuration is present and login to the Docker registry.
|
||||
- `publish`: Tag the image specified by `name` with the new version, push it to Docker Hub and update the latest tag.
|
||||
- `verifyConditions`: Verify that all needed configuration is present and login to the Docker registry
|
||||
- `publish`: Tag the image specified by `name` with the new version, push it to Docker Hub and update the latest tag
|
||||
- [semantic-release-vsce](https://github.com/raix/semantic-release-vsce)
|
||||
- `verifyConditions`: Verify the presence and the validity of the vsce authentication and release configuration
|
||||
- `prepare`: Create a `.vsix` for distribution
|
||||
@@ -51,14 +55,19 @@
|
||||
- `verifyConditions`: Check the dependencies format against a regexp before a release
|
||||
- [semantic-release-chrome](https://github.com/GabrielDuarteM/semantic-release-chrome)
|
||||
- `verifyConditions`: Verify the presence of the authentication (set via environment variables)
|
||||
- `prepare`: Write the correct version to the manifest.json and creates a zip file of the whole dist folder
|
||||
- `prepare`: Write the correct version to the `manifest.json` and creates a zip file of the whole dist folder
|
||||
- `publish`: Uploads the generated zip file to the webstore, and publish the item
|
||||
- [semantic-release-firefox](https://github.com/felixfbecker/semantic-release-firefox)
|
||||
- `verifyConditions`: Verify the presence of the authentication (set via environment variables)
|
||||
- `prepare`: Write the correct version to the manifest.json, creates a xpi file of the dist folder and a zip of the sources
|
||||
- `prepare`: Write the correct version to the `manifest.json`, creates a `xpi` file of the dist folder and a zip of the sources
|
||||
- `publish`: Submit the generated archives to the webstore for review, and publish the item including release notes
|
||||
- [semantic-release-gerrit](https://github.com/pascalMN/semantic-release-gerrit)
|
||||
- `generateNotes`: Generate release notes with Gerrit reviews URL
|
||||
- [semantic-release-expo](https://github.com/bycedric/semantic-release-expo)
|
||||
- `verifyConditions`: Verify Expo manifest(s) are readable and valid.
|
||||
- `prepare`: Update version, ios build number and android version code in the Expo manifest(s).
|
||||
- [maven-semantic-release](https://github.com/conveyal/maven-semantic-release)
|
||||
- `verifyConditions`: Verifies that the `pom.xml` file and other files exist and are setup to allow releases
|
||||
- `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
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
## CI configurations
|
||||
- [CircleCI 2.0 workflows](circleci-workflows.md)
|
||||
- [Travis CI](travis.md)
|
||||
- [Travis CI with build stages](travis-build-stages.md)
|
||||
- [GitLab CI](gitlab-ci.md)
|
||||
|
||||
## Git hosted services
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
The [Authentication](../usage/ci-configuration.md#authentication) environment variables can be configured in [CircleCi Project Settings](https://circleci.com/docs/2.0/env-vars/#adding-environment-variables-in-the-app)..
|
||||
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/ci-configuration.md#automatic-setup-with-semantic-release-cli).
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/getting-started.md#getting-started).
|
||||
|
||||
## Multiple Node jobs configuration
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
# Using semantic-release with [Travis CI build stages](https://docs.travis-ci.com/user/build-stages)
|
||||
|
||||
## Environment variables
|
||||
|
||||
The [Authentication](../usage/ci-configuration.md#authentication) environment variables can be configured in [Travis Repository Settings](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-Settings) or with the [travis env set CLI](https://github.com/travis-ci/travis.rb#env).
|
||||
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/ci-configuration.md#automatic-setup-with-semantic-release-cli).
|
||||
|
||||
## Multiple Node jobs configuration
|
||||
|
||||
### `.travis.yml` configuration for multiple Node jobs
|
||||
|
||||
This example is a minimal configuration for **semantic-release** with a build running Node 6 and 8. See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
|
||||
This example creates a `release` [build stage](https://docs.travis-ci.com/user/build-stages) that [runs `semantic-release` only after all test jobs are successful](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded).
|
||||
|
||||
It's recommended to run the `semantic-release` command in the [Travis `deploy` step](https://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle) so if an error occurs the build will fail and Travis will send a notification.
|
||||
|
||||
**Note**: It's not recommended to run the `semantic-release` command in the Travis `script` step as each script in this step will be executed regardless of the outcome of the previous one. See [travis-ci/travis-ci#1066](https://github.com/travis-ci/travis-ci/issues/1066).
|
||||
|
||||
**Advanced configuration**: Running the tests in the `script` step of the `release` stage is not necessary as the previous stage(s) already ran them. To increase speed, the `script` step of the `release` stage can be overwritten to skip the tests. Note that other commands such as build or compilation might still be required.
|
||||
|
||||
```yaml
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 8
|
||||
- 6
|
||||
|
||||
jobs:
|
||||
include:
|
||||
# Define the release stage that runs semantic-release
|
||||
- stage: release
|
||||
node_js: lts/*
|
||||
# Advanced: optionally overwrite your default `script` step to skip the tests
|
||||
# script: skip
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
- npx semantic-release
|
||||
```
|
||||
|
||||
### `package.json` configuration for multiple Node jobs
|
||||
|
||||
A `package.json` is required only for [local](../usage/installation.md#local-installation) **semantic-release** installation.
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"semantic-release": "^15.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Non-JavaScript projects configuration
|
||||
|
||||
For projects that require to be tested with one or multiple version of a Non-JavaScript [language](https://docs.travis-ci.com/user/languages), optionally on multiple [Operating Systems](https://docs.travis-ci.com/user/multi-os).
|
||||
|
||||
This recipe cover the Travis specifics only. See [Non JavaScript projects recipe](../support/FAQ.md#can-i-use-semantic-release-to-publish-non-javascript-packages) for more information on the **semantic-release** configuration.
|
||||
|
||||
### `.travis.yml` configuration for non-JavaScript projects
|
||||
|
||||
This example is a minimal configuration for **semantic-release** with a build running [Go 1.6 and 1.7](https://docs.travis-ci.com/user/languages/go). See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
|
||||
This example creates a `release` [build stage](https://docs.travis-ci.com/user/build-stages) that [runs `semantic-release` only after all test jobs are successful](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded).
|
||||
|
||||
It's recommended to run the `semantic-release` command in the [Travis `deploy` step](https://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle) so if an error occurs the build will fail and Travis will send a notification.
|
||||
|
||||
**Note**: It's not recommended to run the `semantic-release` command in the Travis `script` step as each script in this step will be executed regardless of the outcome of the previous one. See [travis-ci/travis-ci#1066](https://github.com/travis-ci/travis-ci/issues/1066).
|
||||
|
||||
**Advanced configuration**: Running the tests in the `script` step of the `release` stage is not necessary as the previous stage(s) already ran them. To increase speed, the `script` step of the `release` stage can be overwritten to skip the tests. Note that other commands such as build or compilation might still be required.
|
||||
|
||||
```yaml
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
|
||||
jobs:
|
||||
include:
|
||||
# Define the release stage that runs semantic-release
|
||||
- stage: release
|
||||
# Advanced: optionally overwrite your default `script` step to skip the tests
|
||||
# script:
|
||||
# - make
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
# Use nvm to install and use the Node LTS version (nvm is installed on all Travis images)
|
||||
- nvm install lts/*
|
||||
- npx semantic-release
|
||||
```
|
||||
+38
-72
@@ -4,62 +4,22 @@
|
||||
|
||||
The [Authentication](../usage/ci-configuration.md#authentication) environment variables can be configured in [Travis Repository Settings](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-Settings) or with the [travis env set CLI](https://github.com/travis-ci/travis.rb#env).
|
||||
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/ci-configuration.md#automatic-setup-with-semantic-release-cli).
|
||||
Alternatively, the default `NPM_TOKEN` and `GH_TOKEN` can be easily [setup with semantic-release-cli](../usage/getting-started.md#getting-started).
|
||||
|
||||
## Single Node job configuration
|
||||
## Node.js projects configuration
|
||||
|
||||
For projects that require to be tested only with a single [Node version](https://docs.travis-ci.com/user/getting-started/#Selecting-a-different-programming-language) on [one Operating System](https://docs.travis-ci.com/user/getting-started/#Selecting-infrastructure-(optional)).
|
||||
|
||||
**Note**: [Node 8 is the minimal version required](../support/FAQ.md#why-does-semantic-release-require-node-version--83).
|
||||
|
||||
### `.travis.yml` configuration for single Node job
|
||||
|
||||
This example is a minimal configuration for semantic-release with a build running Node 8 on Linux. See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
|
||||
It's recommended to run the `semantic-release` command in the [Travis `deploy` step](https://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle) so if an error occurs the build will fail and Travis will send a notification.
|
||||
|
||||
**Note**: It's not recommended to run the `semantic-release` command in the Travis `script` step as each script in this step will be executed regardless of the outcome of the previous one. See [travis-ci/travis-ci#1066](https://github.com/travis-ci/travis-ci/issues/1066).
|
||||
|
||||
```yaml
|
||||
language: node_js
|
||||
|
||||
node_js: 8
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
- npx semantic-release
|
||||
```
|
||||
|
||||
### `package.json` configuration for single Node job
|
||||
|
||||
A `package.json` is required only for [local](../usage/installation.md#local-installation) **semantic-release** installation.
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"semantic-release": "^11.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Node jobs configuration
|
||||
|
||||
For projects that require to be tested with multiple [Node versions](https://docs.travis-ci.com/user/languages/javascript-with-nodejs/#Specifying-Node.js-versions) and/or on multiple [Operating Systems](https://docs.travis-ci.com/user/multi-os).
|
||||
|
||||
**Note**: At least one job must run a [Node >= 8 version](../support/FAQ.md#why-does-semantic-release-require-node-version--83).
|
||||
|
||||
### `.travis.yml` configuration for multiple Node jobs
|
||||
### `.travis.yml` configuration for multiple Node.js jobs
|
||||
|
||||
This example is a minimal configuration for **semantic-release** with a build running Node 6 and 8. See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
|
||||
This example uses [`travis-deploy-once`](https://github.com/semantic-release/travis-deploy-once) in order to [Run `semantic-release` only after all tests succeeded](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded). Alternatively you can use [Travis CI Build Stages recipe](travis-build-stages.md).
|
||||
This example creates a `release` [build stage](https://docs.travis-ci.com/user/build-stages) that [runs `semantic-release` only after all test jobs are successful](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded).
|
||||
|
||||
It's recommended to run the `semantic-release` command in the [Travis `deploy` step](https://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle) so if an error occurs the build will fail and Travis will send a notification.
|
||||
|
||||
**Note**: It's not recommended to run the `semantic-release` command in the Travis `script` step as each script in this step will be executed regardless of the outcome of the previous one. See [travis-ci/travis-ci#1066](https://github.com/travis-ci/travis-ci/issues/1066).
|
||||
|
||||
**Advanced configuration**: Running the tests in the `script` step of the `release` stage is not necessary as the previous stage(s) already ran them. To increase speed, the `script` step of the `release` stage can be overwritten to skip the tests. Note that other commands such as build or compilation might still be required.
|
||||
|
||||
```yaml
|
||||
language: node_js
|
||||
|
||||
@@ -67,15 +27,20 @@ node_js:
|
||||
- 8
|
||||
- 6
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
- npx travis-deploy-once "npx semantic-release"
|
||||
jobs:
|
||||
include:
|
||||
# Define the release stage that runs semantic-release
|
||||
- stage: release
|
||||
node_js: lts/*
|
||||
# Advanced: optionally overwrite your default `script` step to skip the tests
|
||||
# script: skip
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
- npx semantic-release
|
||||
```
|
||||
|
||||
**Note**: See the `travis-deploy-once` [`pro`](https://github.com/semantic-release/travis-deploy-once#-p---pro) and [`travis-url`](https://github.com/semantic-release/travis-deploy-once#-u---travis-url) options for using with [Travis Pro](https://docs.travis-ci.com/user/travis-pro) and [Travis Enterprise](https://enterprise.travis-ci.com).
|
||||
|
||||
### `package.json` configuration for multiple Node jobs
|
||||
|
||||
A `package.json` is required only for [local](../usage/installation.md#local-installation) **semantic-release** installation.
|
||||
@@ -83,13 +48,12 @@ A `package.json` is required only for [local](../usage/installation.md#local-ins
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"semantic-release": "^15.0.0",
|
||||
"travis-deploy-once": "^5.0.0"
|
||||
"semantic-release": "^15.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Non-JavaScript projects configuration
|
||||
## Non-Node.js projects configuration
|
||||
|
||||
For projects that require to be tested with one or multiple version of a Non-JavaScript [language](https://docs.travis-ci.com/user/languages), optionally on multiple [Operating Systems](https://docs.travis-ci.com/user/multi-os).
|
||||
|
||||
@@ -97,14 +61,16 @@ This recipe cover the Travis specifics only. See [Non JavaScript projects recipe
|
||||
|
||||
### `.travis.yml` configuration for non-JavaScript projects
|
||||
|
||||
This example is a minimal configuration for **semantic-release** with a build running [Go 1.6 and 1.7](https://docs.travis-ci.com/user/languages/go) on Linux and OSX. See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
This example is a minimal configuration for **semantic-release** with a build running [Go 1.6 and 1.7](https://docs.travis-ci.com/user/languages/go). See [Travis - Customizing the Build](https://docs.travis-ci.com/user/customizing-the-build) for additional configuration options.
|
||||
|
||||
This example uses [`travis-deploy-once`](https://github.com/semantic-release/travis-deploy-once) in order to [run `semantic-release` only after all tests succeeded](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded). Alternatively you can use [Travis CI Build Stages recipe](travis-build-stages.md).
|
||||
This example creates a `release` [build stage](https://docs.travis-ci.com/user/build-stages) that [runs `semantic-release` only after all test jobs are successful](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded).
|
||||
|
||||
It's recommended to run the `semantic-release` command in the [Travis `deploy` step](https://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle) so if an error occurs the build will fail and Travis will send a notification.
|
||||
|
||||
**Note**: It's not recommended to run the `semantic-release` command in the Travis `script` step as each script in this step will be executed regardless of the outcome of the previous one. See [travis-ci/travis-ci#1066](https://github.com/travis-ci/travis-ci/issues/1066).
|
||||
|
||||
**Advanced configuration**: Running the tests in the `script` step of the `release` stage is not necessary as the previous stage(s) already ran them. To increase speed, the `script` step of the `release` stage can be overwritten to skip the tests. Note that other commands such as build or compilation might still be required.
|
||||
|
||||
```yaml
|
||||
language: go
|
||||
|
||||
@@ -112,18 +78,18 @@ go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
# Use nvm to install and use the Node LTS version (nvm is installed on all Travis images)
|
||||
- nvm install lts/*
|
||||
# Run semantic-release only on one job, after all other are successful
|
||||
- npx travis-deploy-once "npx semantic-release"
|
||||
jobs:
|
||||
include:
|
||||
# Define the release stage that runs semantic-release
|
||||
- stage: release
|
||||
# Advanced: optionally overwrite your default `script` step to skip the tests
|
||||
# script:
|
||||
# - make
|
||||
deploy:
|
||||
provider: script
|
||||
skip_cleanup: true
|
||||
script:
|
||||
# Use nvm to install and use the Node LTS version (nvm is installed on all Travis images)
|
||||
- nvm install lts/*
|
||||
- npx semantic-release
|
||||
```
|
||||
|
||||
**Note**: See the `travis-deploy-once` [`pro`](https://github.com/semantic-release/travis-deploy-once#-p---pro) and [`travis-url`](https://github.com/semantic-release/travis-deploy-once#-u---travis-url) options for using with [Travis Pro](https://docs.travis-ci.com/user/travis-pro) and [Travis Enterprise](https://enterprise.travis-ci.com).
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
|
||||
- ["Introducing Reliable Dependency and Release Management for npm Packages" - Gregor Martynus](https://www.youtube.com/watch?v=R2RJWLcfzwc)
|
||||
- ["Kill all humans" - Jan Lehnardt](https://www.youtube.com/watch?v=ZXyx_1kN1L8&t=2s)
|
||||
- [Publishing JavaScript Packages" - JavaScript Air](https://javascriptair.com/episodes/2016-07-20)
|
||||
- ["Publishing JavaScript Packages" - JavaScript Air](https://javascriptair.com/episodes/2016-07-20)
|
||||
- ["Managing Dependencies like a boss 😎" - JavaScript Air](https://javascriptair.com/episodes/2016-08-17)
|
||||
- ["Dependency Hell Just Froze Over" - Stephan Bönnemann](https://www.youtube.com/watch?v=PA139CERNbc)
|
||||
- [“semantic-release Q&A with Kent C. Dodds”](https://www.youtube.com/watch?v=g6y3DnhkjrI)
|
||||
- [“We fail to follow SemVer – and why it needn’t matter” - Stephan Bönnemann](https://www.youtube.com/watch?v=tc2UgG5L7WM)
|
||||
- ["semantic-release Q&A with Kent C. Dodds"](https://www.youtube.com/watch?v=g6y3DnhkjrI)
|
||||
- ["We fail to follow SemVer – and why it needn’t matter" - Stephan Bönnemann](https://www.youtube.com/watch?v=tc2UgG5L7WM)
|
||||
|
||||
## Articles
|
||||
|
||||
- [“Introduction to SemVer” - Irina Gebauer](https://blog.greenkeeper.io/introduction-to-semver-d272990c44f2)
|
||||
- ["Introduction to SemVer" - Irina Gebauer](https://blog.greenkeeper.io/introduction-to-semver-d272990c44f2)
|
||||
- ["Introduction to Semantic Release" - liv](https://blog.greenkeeper.io/introduction-to-semantic-release-33f73b117c8)
|
||||
|
||||
## Tutorials
|
||||
|
||||
- [“How to Write a JavaScript Library - Automating Releases with semantic-release” – egghead.io](https://egghead.io/lessons/javascript-automating-releases-with-semantic-release)
|
||||
- ["How to Write a JavaScript Library - Automating Releases with semantic-release" – egghead.io](https://egghead.io/lessons/javascript-automating-releases-with-semantic-release)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Run `semantic-release` only after all tests succeeded
|
||||
|
||||
The `semantic-release` command must be executed only after all the tests in the CI build pass. If the build runs multiple jobs (for example to test on multiple Operating Systems or Node versions) the CI has to be configured to guarantee that the `semantic-release` command is executed only after all jobs are successful. This can be achieved with [Travis Build Stages](https://docs.travis-ci.com/user/build-stages), [CircleCI Workflows](https://circleci.com/docs/2.0/workflows), [Codeship Deployment Pipelines](https://documentation.codeship.com/basic/builds-and-configuration/deployment-pipelines), [GitLab Pipelines](https://docs.gitlab.com/ee/ci/pipelines.html#introduction-to-pipelines-and-jobs), [Wercker Workflows](http://devcenter.wercker.com/docs/workflows), [GoCD Pipelines](https://docs.gocd.org/current/introduction/concepts_in_go.html#pipeline) or specific tools like [`travis-deploy-once`](https://github.com/semantic-release/travis-deploy-once).
|
||||
The `semantic-release` command must be executed only after all the tests in the CI build pass. If the build runs multiple jobs (for example to test on multiple Operating Systems or Node versions) the CI has to be configured to guarantee that the `semantic-release` command is executed only after all jobs are successful. This can be achieved with [Travis Build Stages](https://docs.travis-ci.com/user/build-stages), [CircleCI Workflows](https://circleci.com/docs/2.0/workflows), [Codeship Deployment Pipelines](https://documentation.codeship.com/basic/builds-and-configuration/deployment-pipelines), [GitLab Pipelines](https://docs.gitlab.com/ee/ci/pipelines.html#introduction-to-pipelines-and-jobs), [Codefresh Pipelines](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines), [Wercker Workflows](http://devcenter.wercker.com/docs/workflows) or [GoCD Pipelines](https://docs.gocd.org/current/introduction/concepts_in_go.html#pipeline).
|
||||
|
||||
See [CI configuration recipes](../recipes/README.md#ci-configurations) for more details.
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Configuration
|
||||
|
||||
**semantic-release** configuration consist of:
|
||||
**semantic-release** configuration consists of:
|
||||
- Git repository options ([URL](#repositoryurl), [release branch](#branch) and [tag format](#tagformat))
|
||||
- [plugins](#plugins) definition
|
||||
- run mode ([debug](#debug), [dry run](#dryrun) and [local (no CI)](#ci))
|
||||
|
||||
All those options can be configured directly or by extending a [shareable configuration](shareable-configurations.md).
|
||||
All of these options can be configured directly or by extending a [shareable configuration](shareable-configurations.md).
|
||||
|
||||
Additionally, metadata of Git tags generated by **semantic-release** can be customized via standard [Git environment variables](#git-environment-variables).
|
||||
|
||||
@@ -16,7 +16,7 @@ Additionally, metadata of Git tags generated by **semantic-release** can be cust
|
||||
- A `release.config.js` file that exports an object
|
||||
- A `release` key in the project's `package.json` file
|
||||
|
||||
Alternatively some options can be set via CLI arguments.
|
||||
Alternatively, some options can be set via CLI arguments.
|
||||
|
||||
The following three examples are the same.
|
||||
|
||||
@@ -131,7 +131,9 @@ Type: `Boolean`<br>
|
||||
Default: `false`<br>
|
||||
CLI argument: `--debug`
|
||||
|
||||
Output debugging information. It can also be enabled by setting the `DEBUG` environment variable to `semantic-release:*`.
|
||||
Output debugging information. This can also be enabled by setting the `DEBUG` environment variable to `semantic-release:*`.
|
||||
|
||||
**Note**: The `debug` is used only supported via CLI argument. To enable debug mode from the [JS API](../developer-guide/js-api.md#javascript-api) use `require('debug').enable('semantic-release:*')`.
|
||||
|
||||
## Git environment variables
|
||||
|
||||
@@ -144,7 +146,7 @@ Output debugging information. It can also be enabled by setting the `DEBUG` envi
|
||||
|
||||
## Existing version tags
|
||||
|
||||
**semantic-release** uses [Git tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging) to determine the commits added since the last release. If a release have been published before setting up **semantic-release** you must make sure the most recent commit included in the last published release is in the [release branch](#branch) history and is tagged with the version released, formatted according to the [tag format](#tagformat) configured (defaults to `vx.y.z`).
|
||||
**semantic-release** uses [Git tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging) to determine the commits added since the last release. If a release has been published before setting up **semantic-release** you must make sure the most recent commit included in the last published release is in the [release branch](#branch) history and is tagged with the version released, formatted according to the [tag format](#tagformat) configured (defaults to `vx.y.z`).
|
||||
|
||||
If the previous releases were published with [`npm publish`](https://docs.npmjs.com/cli/publish) this should already be the case.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ const getLastRelease = require('./lib/get-last-release');
|
||||
const {extractErrors} = require('./lib/utils');
|
||||
const getGitAuthUrl = require('./lib/get-git-auth-url');
|
||||
const getLogger = require('./lib/get-logger');
|
||||
const {fetch, verifyAuth, isBranchUpToDate, gitHead: getGitHead, tag, push} = require('./lib/git');
|
||||
const {fetch, verifyAuth, isBranchUpToDate, getGitHead, tag, push} = require('./lib/git');
|
||||
const getError = require('./lib/get-error');
|
||||
const {COMMIT_NAME, COMMIT_EMAIL} = require('./lib/definitions/constants');
|
||||
|
||||
@@ -107,7 +107,7 @@ 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, {cwd, env});
|
||||
await push(options.repositoryUrl, options.branch, {cwd, env});
|
||||
await push(options.repositoryUrl, {cwd, env});
|
||||
logger.success(`Created tag ${nextRelease.gitTag}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ const {RELEASE_TYPE} = require('./constants');
|
||||
|
||||
const homepage = url.format({...url.parse(pkg.homepage), hash: null});
|
||||
const stringify = obj => (isString(obj) ? obj : inspect(obj, {breakLength: Infinity, depth: 2, maxArrayLength: 5}));
|
||||
const linkify = file => `${homepage}/blob/caribou/${file}`;
|
||||
const linkify = file => `${homepage}/blob/master/${file}`;
|
||||
|
||||
module.exports = {
|
||||
ENOGITREPO: ({cwd}) => ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const {isString, isPlainObject} = require('lodash');
|
||||
const {gitHead} = require('../git');
|
||||
const {getGitHead} = require('../git');
|
||||
const hideSensitive = require('../hide-sensitive');
|
||||
const {hideSensitiveValues} = require('../utils');
|
||||
const {RELEASE_TYPE, RELEASE_NOTES_SEPARATOR} = require('./constants');
|
||||
@@ -52,7 +52,7 @@ module.exports = {
|
||||
dryRun: false,
|
||||
pipelineConfig: ({generateNotes}) => ({
|
||||
getNextInput: async context => {
|
||||
const newGitHead = await gitHead({cwd: context.cwd});
|
||||
const newGitHead = await getGitHead({cwd: context.cwd});
|
||||
// If previous prepare plugin has created a commit (gitHead changed)
|
||||
if (context.nextRelease.gitHead !== newGitHead) {
|
||||
context.nextRelease.gitHead = newGitHead;
|
||||
@@ -71,8 +71,8 @@ module.exports = {
|
||||
pipelineConfig: () => ({
|
||||
// Add `nextRelease` and plugin properties to published release
|
||||
transform: (release, step, {nextRelease}) => ({
|
||||
...(isPlainObject(release) ? release : {}),
|
||||
...nextRelease,
|
||||
...(release === false ? {} : nextRelease),
|
||||
...release,
|
||||
...step,
|
||||
}),
|
||||
}),
|
||||
|
||||
+19
-11
@@ -6,6 +6,7 @@ const debug = require('debug')('semantic-release:config');
|
||||
const {repoUrl} = require('./git');
|
||||
const PLUGINS_DEFINITIONS = require('./definitions/plugins');
|
||||
const plugins = require('./plugins');
|
||||
const {validatePlugin, parseConfig} = require('./plugins/utils');
|
||||
|
||||
const CONFIG_NAME = 'release';
|
||||
const CONFIG_FILES = [
|
||||
@@ -26,6 +27,9 @@ module.exports = async (context, opts) => {
|
||||
|
||||
// Merge config file options and CLI/API options
|
||||
let options = {...config, ...opts};
|
||||
if (options.ci === false) {
|
||||
options.noCi = true;
|
||||
}
|
||||
const pluginsPath = {};
|
||||
let extendPaths;
|
||||
({extends: extendPaths, ...options} = options);
|
||||
@@ -37,17 +41,21 @@ module.exports = async (context, opts) => {
|
||||
|
||||
// For each plugin defined in a shareable config, save in `pluginsPath` the extendable config path,
|
||||
// so those plugin will be loaded relatively to the config file
|
||||
Object.entries(extendsOpts).reduce((pluginsPath, [option, value]) => {
|
||||
if (PLUGINS_DEFINITIONS[option] || option === 'plugins') {
|
||||
castArray(value)
|
||||
.filter(plugin => isString(plugin) || (isPlainObject(plugin) && isString(plugin.path)))
|
||||
.map(plugin => (isString(plugin) ? plugin : plugin.path))
|
||||
.forEach(plugin => {
|
||||
pluginsPath[plugin] = extendPath;
|
||||
});
|
||||
}
|
||||
return pluginsPath;
|
||||
}, pluginsPath);
|
||||
Object.entries(extendsOpts)
|
||||
.filter(([, value]) => Boolean(value))
|
||||
.reduce((pluginsPath, [option, value]) => {
|
||||
castArray(value).forEach(plugin => {
|
||||
if (option === 'plugins' && validatePlugin(plugin)) {
|
||||
pluginsPath[parseConfig(plugin)[0]] = extendPath;
|
||||
} else if (
|
||||
PLUGINS_DEFINITIONS[option] &&
|
||||
(isString(plugin) || (isPlainObject(plugin) && isString(plugin.path)))
|
||||
) {
|
||||
pluginsPath[isString(plugin) ? plugin : plugin.path] = extendPath;
|
||||
}
|
||||
});
|
||||
return pluginsPath;
|
||||
}, pluginsPath);
|
||||
|
||||
return {...result, ...extendsOpts};
|
||||
}, {}),
|
||||
|
||||
@@ -2,7 +2,7 @@ const {escapeRegExp, template} = require('lodash');
|
||||
const semver = require('semver');
|
||||
const pLocate = require('p-locate');
|
||||
const debug = require('debug')('semantic-release:get-last-release');
|
||||
const {gitTags, isRefInHistory, gitTagHead} = require('./git');
|
||||
const {getTags, isRefInHistory, getTagHead} = require('./git');
|
||||
|
||||
/**
|
||||
* Last release.
|
||||
@@ -30,7 +30,7 @@ module.exports = async ({cwd, env, options: {tagFormat}, logger}) => {
|
||||
// The `tagFormat` is compiled with space as the `version` as it's an invalid tag character,
|
||||
// so it's guaranteed to no be present in the `tagFormat`.
|
||||
const tagRegexp = `^${escapeRegExp(template(tagFormat)({version: ' '})).replace(' ', '(.+)')}`;
|
||||
const tags = (await gitTags({cwd, env}))
|
||||
const tags = (await getTags({cwd, env}))
|
||||
.map(tag => ({gitTag: tag, version: (tag.match(tagRegexp) || new Array(2))[1]}))
|
||||
.filter(
|
||||
tag => tag.version && semver.valid(semver.clean(tag.version)) && !semver.prerelease(semver.clean(tag.version))
|
||||
@@ -43,7 +43,7 @@ module.exports = async ({cwd, env, options: {tagFormat}, logger}) => {
|
||||
|
||||
if (tag) {
|
||||
logger.log(`Found git tag ${tag.gitTag} associated with version ${tag.version}`);
|
||||
return {gitHead: await gitTagHead(tag.gitTag, {cwd, env}), ...tag};
|
||||
return {gitHead: await getTagHead(tag.gitTag, {cwd, env}), ...tag};
|
||||
}
|
||||
|
||||
logger.log('No git tag version found');
|
||||
|
||||
+15
-16
@@ -4,12 +4,12 @@ const debug = require('debug')('semantic-release:git');
|
||||
/**
|
||||
* Get the commit sha for a given tag.
|
||||
*
|
||||
* @param {string} tagName Tag name for which to retrieve the commit sha.
|
||||
* @param {String} tagName Tag name for which to retrieve the commit sha.
|
||||
* @param {Object} [execaOpts] Options to pass to `execa`.
|
||||
*
|
||||
* @return {string} The commit sha of the tag in parameter or `null`.
|
||||
*/
|
||||
async function gitTagHead(tagName, execaOpts) {
|
||||
async function getTagHead(tagName, execaOpts) {
|
||||
try {
|
||||
return await execa.stdout('git', ['rev-list', '-1', tagName], execaOpts);
|
||||
} catch (error) {
|
||||
@@ -25,20 +25,20 @@ async function gitTagHead(tagName, execaOpts) {
|
||||
* @return {Array<String>} List of git tags.
|
||||
* @throws {Error} If the `git` command fails.
|
||||
*/
|
||||
async function gitTags(execaOpts) {
|
||||
async function getTags(execaOpts) {
|
||||
return (await execa.stdout('git', ['tag'], execaOpts))
|
||||
.split('\n')
|
||||
.map(tag => tag.trim())
|
||||
.filter(tag => Boolean(tag));
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the `ref` is in the direct history of the current branch.
|
||||
*
|
||||
* @param {string} ref The reference to look for.
|
||||
* @param {String} ref The reference to look for.
|
||||
* @param {Object} [execaOpts] Options to pass to `execa`.
|
||||
*
|
||||
* @return {boolean} `true` if the reference is in the history of the current branch, falsy otherwise.
|
||||
* @return {Boolean} `true` if the reference is in the history of the current branch, falsy otherwise.
|
||||
*/
|
||||
async function isRefInHistory(ref, execaOpts) {
|
||||
try {
|
||||
@@ -73,9 +73,9 @@ async function fetch(repositoryUrl, execaOpts) {
|
||||
*
|
||||
* @param {Object} [execaOpts] Options to pass to `execa`.
|
||||
*
|
||||
* @return {string} the sha of the HEAD commit.
|
||||
* @return {String} the sha of the HEAD commit.
|
||||
*/
|
||||
function gitHead(execaOpts) {
|
||||
function getGitHead(execaOpts) {
|
||||
return execa.stdout('git', ['rev-parse', 'HEAD'], execaOpts);
|
||||
}
|
||||
|
||||
@@ -143,22 +143,21 @@ async function tag(tagName, execaOpts) {
|
||||
* Push to the remote repository.
|
||||
*
|
||||
* @param {String} repositoryUrl The remote repository URL.
|
||||
* @param {String} branch The branch to push.
|
||||
* @param {Object} [execaOpts] Options to pass to `execa`.
|
||||
*
|
||||
* @throws {Error} if the push failed.
|
||||
*/
|
||||
async function push(repositoryUrl, branch, execaOpts) {
|
||||
await execa('git', ['push', '--tags', repositoryUrl, `HEAD:${branch}`], execaOpts);
|
||||
async function push(repositoryUrl, execaOpts) {
|
||||
await execa('git', ['push', '--tags', repositoryUrl], execaOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a tag name is a valid Git reference.
|
||||
*
|
||||
* @param {string} tagName the tag name to verify.
|
||||
* @param {String} tagName the tag name to verify.
|
||||
* @param {Object} [execaOpts] Options to pass to `execa`.
|
||||
*
|
||||
* @return {boolean} `true` if valid, falsy otherwise.
|
||||
* @return {Boolean} `true` if valid, falsy otherwise.
|
||||
*/
|
||||
async function verifyTagName(tagName, execaOpts) {
|
||||
try {
|
||||
@@ -186,11 +185,11 @@ async function isBranchUpToDate(branch, execaOpts) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gitTagHead,
|
||||
gitTags,
|
||||
getTagHead,
|
||||
getTags,
|
||||
isRefInHistory,
|
||||
fetch,
|
||||
gitHead,
|
||||
getGitHead,
|
||||
repoUrl,
|
||||
isGitRepo,
|
||||
verifyAuth,
|
||||
|
||||
+4
-7
@@ -24,7 +24,7 @@
|
||||
"@semantic-release/github": "^5.1.0",
|
||||
"@semantic-release/npm": "^5.0.5",
|
||||
"@semantic-release/release-notes-generator": "^7.1.2",
|
||||
"aggregate-error": "^1.0.0",
|
||||
"aggregate-error": "^2.0.0",
|
||||
"cosmiconfig": "^5.0.1",
|
||||
"debug": "^4.0.0",
|
||||
"env-ci": "^3.0.0",
|
||||
@@ -60,10 +60,10 @@
|
||||
"js-yaml": "^3.10.0",
|
||||
"mockserver-client": "^5.1.1",
|
||||
"nock": "^10.0.0",
|
||||
"nyc": "^12.0.1",
|
||||
"p-retry": "^2.0.0",
|
||||
"nyc": "^13.1.0",
|
||||
"p-retry": "^3.0.0",
|
||||
"proxyquire": "^2.0.0",
|
||||
"sinon": "^6.0.0",
|
||||
"sinon": "^7.1.1",
|
||||
"stream-buffers": "^3.0.2",
|
||||
"tempy": "^0.2.1",
|
||||
"xo": "^0.23.0"
|
||||
@@ -112,9 +112,6 @@
|
||||
"publishConfig": {
|
||||
"tag": "next"
|
||||
},
|
||||
"release": {
|
||||
"branch": "caribou"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/semantic-release/semantic-release.git"
|
||||
|
||||
+1
-13
@@ -163,18 +163,6 @@ test.serial('Do not set properties in option for which arg is not in command lin
|
||||
t.false('e' in run.args[0][0]);
|
||||
});
|
||||
|
||||
test.serial('Set "noCi" options to "true" with "--no-ci"', async t => {
|
||||
const run = stub().resolves(true);
|
||||
const argv = ['', '', '--no-ci'];
|
||||
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
|
||||
|
||||
const exitCode = await cli();
|
||||
|
||||
t.is(run.args[0][0].noCi, true);
|
||||
|
||||
t.is(exitCode, 0);
|
||||
});
|
||||
|
||||
test.serial('Display help', async t => {
|
||||
const run = stub().resolves(true);
|
||||
const argv = ['', '', '--help'];
|
||||
@@ -186,7 +174,7 @@ test.serial('Display help', async t => {
|
||||
t.is(exitCode, 0);
|
||||
});
|
||||
|
||||
test.serial('Returns error code and prints help if called with a command', async t => {
|
||||
test.serial('Return error code and prints help if called with a command', async t => {
|
||||
const run = stub().resolves(true);
|
||||
const argv = ['', '', 'pre'];
|
||||
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
|
||||
|
||||
@@ -22,7 +22,7 @@ test('The "generateNotes" plugin output, if defined, must be a string', t => {
|
||||
t.true(plugins.generateNotes.outputValidator('string'));
|
||||
});
|
||||
|
||||
test('The "publish" plugin output, if defined, must be an object', t => {
|
||||
test('The "publish" plugin output, if defined, must be an object or "false"', t => {
|
||||
t.false(plugins.publish.outputValidator(1));
|
||||
t.false(plugins.publish.outputValidator('string'));
|
||||
|
||||
@@ -30,6 +30,7 @@ test('The "publish" plugin output, if defined, must be an object', t => {
|
||||
t.true(plugins.publish.outputValidator());
|
||||
t.true(plugins.publish.outputValidator(null));
|
||||
t.true(plugins.publish.outputValidator(''));
|
||||
t.true(plugins.publish.outputValidator(false));
|
||||
});
|
||||
|
||||
test('The "generateNotes" plugins output are concatenated with separator and sensitive data is hidden', t => {
|
||||
|
||||
+15
-1
@@ -67,6 +67,18 @@ test('Default values, reading repositoryUrl (http url) from package.json if not
|
||||
t.is(result.tagFormat, `v\${version}`);
|
||||
});
|
||||
|
||||
test('Convert "ci" option to "noCi"', async t => {
|
||||
const pkg = {repository: 'https://host.null/owner/module.git', release: {ci: false}};
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const {cwd} = await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await outputJson(path.resolve(cwd, 'package.json'), pkg);
|
||||
|
||||
const {options: result} = await t.context.getConfig({cwd});
|
||||
|
||||
t.is(result.noCi, true);
|
||||
});
|
||||
|
||||
test('Read options from package.json', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const {cwd} = await gitRepo();
|
||||
@@ -212,7 +224,7 @@ test('Read configuration from file path in "extends"', async t => {
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'https://host.null/owner/module.git',
|
||||
tagFormat: `v\${version}`,
|
||||
plugins: false,
|
||||
plugins: ['plugin-1', ['plugin-2', {plugin2Opt: 'value'}]],
|
||||
};
|
||||
// Create package.json and shareable.json in repository root
|
||||
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
||||
@@ -227,6 +239,8 @@ test('Read configuration from file path in "extends"', async t => {
|
||||
t.deepEqual(t.context.plugins.args[0][1], {
|
||||
analyzeCommits: './shareable.json',
|
||||
generateNotes: './shareable.json',
|
||||
'plugin-1': './shareable.json',
|
||||
'plugin-2': './shareable.json',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+30
-17
@@ -1,14 +1,14 @@
|
||||
import test from 'ava';
|
||||
import tempy from 'tempy';
|
||||
import {
|
||||
gitTagHead,
|
||||
getTagHead,
|
||||
isRefInHistory,
|
||||
fetch,
|
||||
gitHead,
|
||||
getGitHead,
|
||||
repoUrl,
|
||||
tag,
|
||||
push,
|
||||
gitTags,
|
||||
getTags,
|
||||
isGitRepo,
|
||||
verifyTagName,
|
||||
isBranchUpToDate,
|
||||
@@ -33,7 +33,7 @@ test('Get the last commit sha', async t => {
|
||||
// Add commits to the master branch
|
||||
const commits = await gitCommits(['First'], {cwd});
|
||||
|
||||
const result = await gitHead({cwd});
|
||||
const result = await getGitHead({cwd});
|
||||
|
||||
t.is(result, commits[0].hash);
|
||||
});
|
||||
@@ -42,7 +42,7 @@ test('Throw error if the last commit sha cannot be found', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const {cwd} = await gitRepo();
|
||||
|
||||
await t.throws(gitHead({cwd}), Error);
|
||||
await t.throws(getGitHead({cwd}), Error);
|
||||
});
|
||||
|
||||
test('Unshallow and fetch repository', async t => {
|
||||
@@ -84,7 +84,7 @@ test('Fetch all tags on a detached head repository', async t => {
|
||||
|
||||
await fetch(repositoryUrl, {cwd});
|
||||
|
||||
t.deepEqual((await gitTags({cwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0'].sort());
|
||||
t.deepEqual((await getTags({cwd})).sort(), ['v1.0.0', 'v1.0.1', 'v1.1.0'].sort());
|
||||
});
|
||||
|
||||
test('Verify if the commit `sha` is in the direct history of the current branch', async t => {
|
||||
@@ -111,8 +111,8 @@ test('Get the commit sha for a given tag or falsy if the tag does not exists', a
|
||||
// Create the tag corresponding to version 1.0.0
|
||||
await gitTagVersion('v1.0.0', undefined, {cwd});
|
||||
|
||||
t.is(await gitTagHead('v1.0.0', {cwd}), commits[0].hash);
|
||||
t.falsy(await gitTagHead('missing_tag', {cwd}));
|
||||
t.is(await getTagHead('v1.0.0', {cwd}), commits[0].hash);
|
||||
t.falsy(await getTagHead('missing_tag', {cwd}));
|
||||
});
|
||||
|
||||
test('Return git remote repository url from config', async t => {
|
||||
@@ -151,13 +151,27 @@ test('Add tag on head commit', async t => {
|
||||
await t.is(await gitCommitTag(commits[0].hash, {cwd}), 'tag_name');
|
||||
});
|
||||
|
||||
test('Push tag and commit to remote repository', async t => {
|
||||
test('Push tag to remote repository', async t => {
|
||||
// Create a git repository with a remote, set the current working directory at the root of the repo
|
||||
const {cwd, repositoryUrl} = await gitRepo(true);
|
||||
const commits = await gitCommits(['Test commit'], {cwd});
|
||||
|
||||
await tag('tag_name', {cwd});
|
||||
await push(repositoryUrl, 'master', {cwd});
|
||||
await push(repositoryUrl, {cwd});
|
||||
|
||||
t.is(await gitRemoteTagHead(repositoryUrl, 'tag_name', {cwd}), commits[0].hash);
|
||||
});
|
||||
|
||||
test('Push tag to remote repository with remote branch ahaed', async t => {
|
||||
const {cwd, repositoryUrl} = await gitRepo(true);
|
||||
const commits = await gitCommits(['First'], {cwd});
|
||||
await gitPush(repositoryUrl, 'master', {cwd});
|
||||
const tmpRepo = await gitShallowClone(repositoryUrl);
|
||||
await gitCommits(['Second'], {cwd: tmpRepo});
|
||||
await gitPush('origin', 'master', {cwd: tmpRepo});
|
||||
|
||||
await tag('tag_name', {cwd});
|
||||
await push(repositoryUrl, {cwd});
|
||||
|
||||
t.is(await gitRemoteTagHead(repositoryUrl, 'tag_name', {cwd}), commits[0].hash);
|
||||
});
|
||||
@@ -192,7 +206,7 @@ test('Return falsy for invalid tag names', async t => {
|
||||
test('Throws error if obtaining the tags fails', async t => {
|
||||
const cwd = tempy.directory();
|
||||
|
||||
await t.throws(gitTags({cwd}));
|
||||
await t.throws(getTags({cwd}));
|
||||
});
|
||||
|
||||
test('Return "true" if repository is up to date', async t => {
|
||||
@@ -204,19 +218,18 @@ test('Return "true" if repository is up to date', async t => {
|
||||
});
|
||||
|
||||
test('Return falsy if repository is not up to date', async t => {
|
||||
let {cwd, repositoryUrl} = await gitRepo(true);
|
||||
const repoDir = cwd;
|
||||
const {cwd, repositoryUrl} = await gitRepo(true);
|
||||
await gitCommits(['First'], {cwd});
|
||||
await gitCommits(['Second'], {cwd});
|
||||
await gitPush(repositoryUrl, 'master', {cwd});
|
||||
|
||||
t.true(await isBranchUpToDate('master', {cwd}));
|
||||
|
||||
cwd = await gitShallowClone(repositoryUrl);
|
||||
await gitCommits(['Third'], {cwd});
|
||||
await gitPush('origin', 'master', {cwd});
|
||||
const tmpRepo = await gitShallowClone(repositoryUrl);
|
||||
await gitCommits(['Third'], {cwd: tmpRepo});
|
||||
await gitPush('origin', 'master', {cwd: tmpRepo});
|
||||
|
||||
t.falsy(await isBranchUpToDate('master', {cwd: repoDir}));
|
||||
t.falsy(await isBranchUpToDate('master', {cwd}));
|
||||
});
|
||||
|
||||
test('Return "true" if local repository is ahead', async t => {
|
||||
|
||||
@@ -26,7 +26,7 @@ import getStream from 'get-stream';
|
||||
export async function gitRepo(withRemote, branch = 'master') {
|
||||
let cwd = tempy.directory();
|
||||
|
||||
await execa('git', ['init'].concat(withRemote ? ['--bare'] : []), {cwd});
|
||||
await execa('git', ['init', ...(withRemote ? ['--bare'] : [])], {cwd});
|
||||
|
||||
const repositoryUrl = fileUrl(cwd);
|
||||
if (withRemote) {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import nock from 'nock';
|
||||
|
||||
/**
|
||||
* Retun a `nock` object setup to respond to a github authentication request. Other expectation and responses can be chained.
|
||||
*
|
||||
* @param {String} [githubToken='GH_TOKEN'] The github token to return in the authentication response.
|
||||
* @param {String} [githubUrl='https://api.github.com'] The url on which to intercept http requests.
|
||||
* @return {Object} A `nock` object ready to respond to a github authentication request.
|
||||
*/
|
||||
export default function authenticate({
|
||||
githubToken = 'GH_TOKEN',
|
||||
githubUrl = 'https://api.github.com',
|
||||
githubApiPathPrefix = '',
|
||||
} = {}) {
|
||||
return nock(`${githubUrl}/${githubApiPathPrefix}`, {reqheaders: {Authorization: `token ${githubToken}`}});
|
||||
}
|
||||
+7
-3
@@ -693,7 +693,7 @@ test('Allow local releases with "noCi" option', async t => {
|
||||
t.is(success.callCount, 1);
|
||||
});
|
||||
|
||||
test('Accept "undefined" value returned by the "generateNotes" plugins', async t => {
|
||||
test('Accept "undefined" value returned by "generateNotes" and "false" by "publish"', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const {cwd, repositoryUrl} = await gitRepo(true);
|
||||
// Add commits to the master branch
|
||||
@@ -711,7 +711,8 @@ test('Accept "undefined" value returned by the "generateNotes" plugins', async t
|
||||
const generateNotes1 = stub().resolves();
|
||||
const notes2 = 'Release notes 2';
|
||||
const generateNotes2 = stub().resolves(notes2);
|
||||
const publish = stub().resolves();
|
||||
const publish = stub().resolves(false);
|
||||
const success = stub().resolves();
|
||||
|
||||
const options = {
|
||||
branch: 'master',
|
||||
@@ -722,7 +723,7 @@ test('Accept "undefined" value returned by the "generateNotes" plugins', async t
|
||||
generateNotes: [generateNotes1, generateNotes2],
|
||||
prepare: stub().resolves(),
|
||||
publish,
|
||||
success: stub().resolves(),
|
||||
success,
|
||||
fail: stub().resolves(),
|
||||
};
|
||||
|
||||
@@ -754,6 +755,9 @@ test('Accept "undefined" value returned by the "generateNotes" plugins', async t
|
||||
t.is(publish.callCount, 1);
|
||||
t.deepEqual(publish.args[0][1].lastRelease, lastRelease);
|
||||
t.is(publish.args[0][1].nextRelease.notes, notes2);
|
||||
|
||||
t.is(success.callCount, 1);
|
||||
t.deepEqual(success.args[0][1].releases, [{pluginName: '[Function: proxy]'}]);
|
||||
});
|
||||
|
||||
test('Returns false if triggered by a PR', async t => {
|
||||
|
||||
+36
-36
@@ -6,7 +6,7 @@ import {writeJson, readJson} from 'fs-extra';
|
||||
import execa from 'execa';
|
||||
import {WritableStreamBuffer} from 'stream-buffers';
|
||||
import {SECRET_REPLACEMENT} from '../lib/definitions/constants';
|
||||
import {gitHead as getGitHead, gitTagHead, gitRepo, gitCommits, gitRemoteTagHead, gitPush} from './helpers/git-utils';
|
||||
import {gitHead, gitTagHead, gitRepo, gitCommits, gitRemoteTagHead, gitPush} from './helpers/git-utils';
|
||||
import gitbox from './helpers/gitbox';
|
||||
import mockServer from './helpers/mockserver';
|
||||
import npmRegistry from './helpers/npm-registry';
|
||||
@@ -108,12 +108,12 @@ test('Release patch, minor and major versions', async t => {
|
||||
let [, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
let gitHead = await getGitHead({cwd});
|
||||
let head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
@@ -150,12 +150,12 @@ test('Release patch, minor and major versions', async t => {
|
||||
[, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
gitHead = await getGitHead({cwd});
|
||||
head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
@@ -192,12 +192,12 @@ test('Release patch, minor and major versions', async t => {
|
||||
[, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
gitHead = await getGitHead({cwd});
|
||||
head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
@@ -234,12 +234,12 @@ test('Release patch, minor and major versions', async t => {
|
||||
[, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
gitHead = await getGitHead({cwd});
|
||||
head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
@@ -388,12 +388,12 @@ test('Allow local releases with "noCi" option', async t => {
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
|
||||
const gitHead = await getGitHead({cwd});
|
||||
const head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
@@ -442,12 +442,12 @@ test('Pass options via CLI arguments', async t => {
|
||||
const [, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
const gitHead = await getGitHead({cwd});
|
||||
const head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
});
|
||||
|
||||
test('Run via JS API', async t => {
|
||||
@@ -500,12 +500,12 @@ test('Run via JS API', async t => {
|
||||
const [, releasedVersion, releasedGitHead] = /^version = '(.+)'\s+gitHead = '(.+)'$/.exec(
|
||||
(await execa('npm', ['show', packageName, 'version', 'gitHead'], {env: testEnv, cwd})).stdout
|
||||
);
|
||||
const gitHead = await getGitHead({cwd});
|
||||
const head = await gitHead({cwd});
|
||||
t.is(releasedVersion, version);
|
||||
t.is(releasedGitHead, gitHead);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), gitHead);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), gitHead);
|
||||
t.log(`+ released ${releasedVersion} with gitHead ${releasedGitHead}`);
|
||||
t.is(releasedGitHead, head);
|
||||
t.is(await gitTagHead(`v${version}`, {cwd}), head);
|
||||
t.is(await gitRemoteTagHead(authUrl, `v${version}`, {cwd}), head);
|
||||
t.log(`+ released ${releasedVersion} with head ${releasedGitHead}`);
|
||||
|
||||
await mockServer.verify(verifyMock);
|
||||
await mockServer.verify(createReleaseMock);
|
||||
|
||||
@@ -11,10 +11,16 @@ test('Throw a AggregateError', async t => {
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'ENOREPOURL');
|
||||
t.truthy(errors[0].message);
|
||||
t.truthy(errors[0].details);
|
||||
t.is(errors[1].name, 'SemanticReleaseError');
|
||||
t.is(errors[1].code, 'EINVALIDTAGFORMAT');
|
||||
t.truthy(errors[1].message);
|
||||
t.truthy(errors[1].details);
|
||||
t.is(errors[2].name, 'SemanticReleaseError');
|
||||
t.is(errors[2].code, 'ETAGNOVERSION');
|
||||
t.truthy(errors[2].message);
|
||||
t.truthy(errors[2].details);
|
||||
});
|
||||
|
||||
test('Throw a SemanticReleaseError if does not run on a git repository', async t => {
|
||||
@@ -25,6 +31,8 @@ test('Throw a SemanticReleaseError if does not run on a git repository', async t
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'ENOGITREPO');
|
||||
t.truthy(errors[0].message);
|
||||
t.truthy(errors[0].details);
|
||||
});
|
||||
|
||||
test('Throw a SemanticReleaseError if the "tagFormat" is not valid', async t => {
|
||||
@@ -35,6 +43,8 @@ test('Throw a SemanticReleaseError if the "tagFormat" is not valid', async t =>
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'EINVALIDTAGFORMAT');
|
||||
t.truthy(errors[0].message);
|
||||
t.truthy(errors[0].details);
|
||||
});
|
||||
|
||||
test('Throw a SemanticReleaseError if the "tagFormat" does not contains the "version" variable', async t => {
|
||||
@@ -45,6 +55,8 @@ test('Throw a SemanticReleaseError if the "tagFormat" does not contains the "ver
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'ETAGNOVERSION');
|
||||
t.truthy(errors[0].message);
|
||||
t.truthy(errors[0].details);
|
||||
});
|
||||
|
||||
test('Throw a SemanticReleaseError if the "tagFormat" contains multiple "version" variables', async t => {
|
||||
@@ -55,6 +67,8 @@ test('Throw a SemanticReleaseError if the "tagFormat" contains multiple "version
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'ETAGNOVERSION');
|
||||
t.truthy(errors[0].message);
|
||||
t.truthy(errors[0].details);
|
||||
});
|
||||
|
||||
test('Return "true" if all verification pass', async t => {
|
||||
|
||||
Reference in New Issue
Block a user