Compare commits

...
Author SHA1 Message Date
Pierre Vanduynslager 3438ec5c79 test: fix typo in test examples 2019-10-18 16:25:40 -04:00
Pierre Vanduynslager 4af8548366 fix: ignore custom port when converting ssh repo URL to https 2019-10-18 16:25:40 -04:00
Alexander GandGregor Martynus dc19dfa2e9 docs: remove unnecessarily apostrophe
- improve punctuation of the how-to revert a release section
2019-10-10 07:32:14 -07:00
knidarknessandPierre Vanduynslager 79d22a2556 fix: clarify message for EGITNOPERMISSION error 2019-10-09 17:57:18 -04:00
Pierre Vanduynslager 9f2ec79d67 docs: limit list of suggested tools for commit linting 2019-10-09 16:42:52 -04:00
greenkeeper[bot]andPierre Vanduynslager 0e24022608 fix(package): update read-pkg-up to version 7.0.0 2019-09-27 10:37:25 -07:00
greenkeeper[bot]andPierre Vanduynslager 5986bf920e chore(package): update xo to version 0.25.0 2019-09-26 10:18:12 -07:00
greenkeeper[bot]andPierre Vanduynslager c86045ca49 chore(package): update dockerode to version 3.0.0 2019-09-24 13:37:46 -07:00
Josh BiddickandGregor Martynus 9b78ab7c0d docs: spelling (#1284) 2019-09-05 15:01:13 -07:00
greenkeeper[bot]andGregor Martynus 8e4fa663fa chore(package): update nock to version 11.1.0 2019-09-04 14:20:39 -07:00
Pierre Vanduynslager 6f33c76fde docs: various clarifications and language improvvements 2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 9fd93ac37a docs: fix node version requirement link is FAQ 2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 7ddc2cfcbc docs: update table of content in README.md and in Gitbook SUMMARY.md 2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 55c3616e3f revert: docs(contributing): added instructions on how to run gitbook locally
This reverts commit a3da21a544.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager c517c7048e revert: docs(contributing): copy/pasted "Use gitbook locally" instruction from original url
This reverts commit cd00c2dc86.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 4b13280713 docs: correct list of default plugins 2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 95a9e89141 revert: fix(definitions): Repository documentation links
This reverts commit 1eb302545e.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 54d8e3fe99 revert: docs: note publishing on distribution channels in beta
This reverts commit 490d86d0d5.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager a6188d3902 revert: docs(recipes): cleaned doc and navigation
This reverts commit a8f8bffa37.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager e00b6c84df revert: docs: repared broken links to "CI configuration recipes"
This reverts commit 3f22978623.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 3c4a0fb773 revert: docs: cleaned "Developer guide" section navigation
This reverts commit b08486327d.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager e770c50f01 revert: docs: synched README.md and SUMMARY.md
This reverts commit 813e5f65ed.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 5e41dc89bd revert: docs: made doc file org clearer and augmented content
This reverts commit 5a5eaec3da.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager ce3d1bc715 revert: docs: corrections and further clarifications
This reverts commit 7cb5446bb5.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager 58aaf057f6 revert: docs: update semantic-release-cli broken link
This reverts commit 3bd63eb6a8.
2019-08-22 14:47:21 -04:00
Pierre Vanduynslager eea5de2863 revert: docs: broken link docs/03-recipes/travis.md
This reverts commit d2230fab7e.
2019-08-22 14:47:21 -04:00
greenkeeper[bot]andPierre Vanduynslager 3c2fe35ded fix(package): update yargs to version 14.0.0 2019-08-19 19:50:25 -04:00
Florian KellerandGregor Martynus 1eb302545e fix(definitions): Repository documentation links 2019-08-16 10:17:24 -07:00
GoisandPierre Vanduynslager d2230fab7e docs: broken link docs/03-recipes/travis.md
Fixed the link for `setup with semantic-release-cli.` in 'Environment Variables' section, refering a old file of this repo,
2019-08-13 14:15:28 -04:00
greenkeeper[bot]andGregor Martynus 391af986be fix(package): update hosted-git-info to version 3.0.0 2019-08-12 11:21:36 -07:00
Crhistian RamirezandGregor Martynus d45d8b6170 docs: fix typo 2019-08-11 09:32:29 -07:00
Pierre Vanduynslager 519df0d5c1 chore: remove commitizen from our dependencies 2019-08-09 14:13:09 -04:00
EmandGregor Martynus e168802379 docs: tried to fix #1250 2019-08-05 21:19:32 -07:00
Alvaro Pinot @alvaropinotandGregor Martynus 3bd63eb6a8 docs: update semantic-release-cli broken link
* Remove extra `01-`
2019-08-05 21:18:30 -07:00
Philipp RudloffandGregor Martynus 9a8a36ce45 fix(package): update dependency lodash to address security warnings (#1253) 2019-08-05 21:17:22 -07:00
Emmanuel SciaraandGregor Martynus 7cb5446bb5 docs: corrections and further clarifications
- (correction) removed comments from code samples.
-(correction) remove recommendation for global
install on CI environemnts.
- Synched README.md and SUMMARY.md
2019-07-31 14:40:10 -07:00
Emmanuel SciaraandGregor Martynus 5a5eaec3da docs: made doc file org clearer and augmented content
This is a first step to improving the doc: - renamed directories; - augmented a fair bit of content.
To be continued
2019-07-31 14:40:10 -07:00
Jed MaoandGregor Martynus 2d2bb38e61 docs(shareable-configurations-list): add @jedmao/semantic-release-npm-github-config (#1222) 2019-07-31 08:57:19 -07:00
Emmanuel SciaraandGregor Martynus cd00c2dc86 docs(contributing): copy/pasted "Use gitbook locally" instruction from original url 2019-07-30 17:44:23 -07:00
Emmanuel SciaraandGregor Martynus a3da21a544 docs(contributing): added instructions on how to run gitbook locally 2019-07-30 17:44:23 -07:00
Emmanuel SciaraandGregor Martynus 813e5f65ed docs: synched README.md and SUMMARY.md 2019-07-30 16:13:59 -07:00
Emmanuel SciaraandGregor Martynus b08486327d docs: cleaned "Developer guide" section navigation 2019-07-30 16:13:59 -07:00
Emmanuel SciaraandGregor Martynus 3f22978623 docs: repared broken links to "CI configuration recipes" 2019-07-30 16:13:59 -07:00
Emmanuel SciaraandGregor Martynus a8f8bffa37 docs(recipes): cleaned doc and navigation
Corrected inconsistancies between the sidebar and the actual pages. Remove non existing pages.
Clarified status of "Package managers and languages" to "to be completed".
2019-07-30 16:13:59 -07:00
scott willekeandGregor Martynus 490d86d0d5 docs: note publishing on distribution channels in beta
Since the readme hints at doing this, note that features to automate this are in beta. Also discussed at https://spectrum.chat/semantic-release/general/im-trying-to-configure-a-next-release~5bb8e692-a0cd-49be-8379-9fb6b25261fe
2019-07-21 19:03:45 -07:00
greenkeeper[bot]andGregor Martynus 665a582930 chore(package): update commitizen to version 4.0.0 2019-07-18 14:20:20 -07:00
David AghassiandGregor Martynus 9e28fd9da9 docs: added plugin developer guide docs 2019-07-18 14:20:11 -07:00
mehrad-rafighandGregor Martynus 6e60c58873 ci(node): set node 8 to node 8.3 and add node 12 2019-07-15 14:50:24 -07:00
greenkeeper[bot]andGregor Martynus 75f08302a9 fix(package): update marked to version 0.7.0 2019-07-06 10:15:52 -07:00
greenkeeper[bot]andGregor Martynus 4b2b2fb780 chore(package): update clear-module to version 4.0.0 2019-07-04 20:04:48 -07:00
Debjeet BiswasandGregor Martynus 3b8cae91fa docs: fix typo
fix misspelled `they`
2019-07-02 15:09:54 -07:00
Pierre Vanduynslager 6b3adf6bbe fix: revert to execa ^1.0.0 2019-06-26 12:33:59 -04:00
Rob CresswellandGregor Martynus 228fed7a0b docs: document that plugins config is an override (#1216)
This patch documents that the `plugin` config option is an override, not
a merge with the default. This is significant, for example, if you
customise the github plugin as it will then prevent npm publishing by
default unless the npm plugin is also defined manually.
2019-06-25 13:01:55 -07:00
Pierre Vanduynslager 01a0b2d08a test: use regexp to check missing module message 2019-06-25 11:30:37 -04:00
greenkeeper[bot]andPierre Vanduynslager 52c48be17b fix(package): update execa to version 2.0.0 2019-06-25 11:30:37 -04:00
Pierre Vanduynslager 4ed6213977 style: fix prettier style 2019-06-07 11:47:28 -04:00
greenkeeper[bot]andPierre Vanduynslager 8051294ffd fix(package): update env-ci to version 4.0.0 2019-06-07 11:21:44 -04:00
greenkeeper[bot]andPierre Vanduynslager 95a0456a85 chore(package): update ava to version 2.0.0 2019-06-05 14:43:18 -04:00
GregorandPierre Vanduynslager 038e640d5e fix: prefix git auth with "x-access-token:" when run in a GitHub Action 2019-06-05 12:17:21 -04:00
GregorandPierre Vanduynslager f3f9d1ef58 test: prefix git auth with "x-access-token:" when run in a GitHub Action 2019-06-05 12:17:21 -04:00
26 changed files with 318 additions and 146 deletions
+2 -1
View File
@@ -4,8 +4,9 @@ services:
- docker
node_js:
- 12
- 10
- 8
- 8.3
# 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)
+6 -5
View File
@@ -52,7 +52,7 @@ This removes the immediate connection between human emotions and version numbers
By default **semantic-release** uses [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). The commit message format can be changed with the [`preset` or `config` options](docs/usage/configuration.md#options) of the [@semantic-release/commit-analyzer](https://github.com/semantic-release/commit-analyzer#options) and [@semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator#options) plugins.
Tools such as [commitizen](https://github.com/commitizen/cz-cli), [commitlint](https://github.com/conventional-changelog/commitlint) or [semantic-git-commit-cli](https://github.com/JPeer264/node-semantic-git-commit-cli) can be used to help contributors and enforce valid commit messages.
Tools such as [commitizen](https://github.com/commitizen/cz-cli) or [commitlint](https://github.com/conventional-changelog/commitlint) can be used to help contributors and enforce valid commit messages.
Here is an example of the release type that will be done based on a commit messages:
@@ -103,12 +103,13 @@ After running the tests, the command `semantic-release` will execute the followi
- [Plugins](docs/extending/plugins-list.md)
- [Shareable configuration](docs/extending/shareable-configurations-list.md)
- Recipes
- [CI configurations](docs/recipes/README.md)
- [Package managers and languages](docs/recipes/README.md)
- [CI configurations](docs/recipes/README.md#ci-configurations)
- [Git hosted services](docs/recipes/README.md#git-hosted-services)
- [Package managers and languages](docs/recipes/README.md#package-managers-and-languages)
- Developer guide
- [JavaScript API](docs/developer-guide/js-api.md)
- [Plugins](docs/developer-guide/plugin.md)
- [Shareable configuration](docs/developer-guide/shareable-configuration.md)
- [Plugins development](docs/developer-guide/plugin.md)
- [Shareable configuration development](docs/developer-guide/shareable-configuration.md)
- Support
- [Resources](docs/support/resources.md)
- [Frequently Asked Questions](docs/support/FAQ.md)
+7 -7
View File
@@ -1,6 +1,7 @@
# Summary
## Usage
- [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)
@@ -12,19 +13,18 @@
- [Shareable configuration](docs/extending/shareable-configurations-list.md)
## Recipes
- [CI configurations](docs/recipes/README.md)
- [CircleCI 2.0 workflows](docs/recipes/circleci-workflows.md)
- [CI configurations](docs/recipes/README.md#ci-configurations)
- [CircleCI 2.0](docs/recipes/circleci-workflows.md)
- [Travis CI](docs/recipes/travis.md)
- [Travis CI with build stages](docs/recipes/travis-build-stages.md)
- [GitLab CI](docs/recipes/gitlab-ci.md)
- [Git hosted services](docs/recipes/README.md)
- [Git hosted services](docs/recipes/README.md#git-hosted-services)
- [Git authentication with SSH keys](docs/recipes/git-auth-ssh-keys.md)
- [Package managers and languages](docs/recipes/README.md)
- [Package managers and languages](docs/recipes/README.md#package-managers-and-languages)
## Developer guide
- [JavaScript API](docs/developer-guide/js-api.md)
- [Plugin](docs/developer-guide/plugin.md)
- [Shareable configuration](docs/developer-guide/shareable-configuration.md)
- [Plugin development](docs/developer-guide/plugin.md)
- [Shareable configuration development](docs/developer-guide/shareable-configuration.md)
## Support
- [Resources](docs/support/resources.md)
+2 -3
View File
@@ -21,9 +21,8 @@ See https://github.com/semantic-release/semantic-release/blob/master/docs/suppor
process.exit(1);
}
execa
.stdout('git', ['--version'])
.then(stdout => {
execa('git', ['--version'])
.then(({stdout}) => {
var gitVersion = findVersions(stdout)[0];
if (semver.lt(gitVersion, MIN_GIT_VERSION)) {
console.error(`[semantic-release]: Git version ${MIN_GIT_VERSION} is required. Found ${gitVersion}.`);
+106 -1
View File
@@ -1 +1,106 @@
# Plugin developer guide
# Plugin Developer Guide
To create a plugin for `semantic-release`, you need to decide which parts of the release lifecycle are important to that plugin. For example, it is best to always have a `verify` step because you may be receiving inputs from a user and want to make sure they exist. A plugin can abide by any of the following lifecycles:
- `verify`
- `prepare`
- `publish`
- `success`
- `fail`
`semantic-release` will require the plugin via `node` and look through the required object for methods named like the lifecyles stated above. For example, if your plugin only had a `verify` and `success` step, the `main` file for your object would need to `export` an object with `verify` and `success` functions.
In addition to the lifecycle methods, each lifecyle is passed two objects:
1. `pluginConfig` - an object containing the options that a user may pass in via their `release.config.js` file (or similar)
2. `context` - provided by `semantic-release` for access to things like `env` variables set on the running process.
For each lifecycle you create, you will want to ensure it can accept `pluginConfig` and `context` as parameters.
## Creating a Plugin Project
It is recommended that you generate a new project with `yarn init`. This will provide you with a basic node project to get started with. From there, create an `index.js` file, and make sure it is specified as the `main` in the `package.json`. We will use this file to orchestrate the lifecycle methods later on.
Next, create a `src` or `lib` folder in the root of the project. This is where we will store our logic and code for how our lifecycle methods work. Finally, create a `test` folder so you can write tests related to your logic.
We recommend you setup a linting system to ensure good javascript practices are enforced. ESLint is usually the system of choice, and the configuration can be whatever you or your team fancies.
## Exposing Lifecycle Methods
In your `index.js` file, you can start by writing the following code
```javascript
const verifyConditions = require('./src/verify');
let verified;
/**
* Called by semantic-release during the verification step
* @param {*} pluginConfig The semantic-release plugin config
* @param {*} context The context provided by semantic-release
*/
async function verify(pluginConfig, context) {
await verifyConditions(pluginConfig, context);
verified = true;
}
module.exports = { verify };
```
Then, in your `src` folder, create a file called `verify.js` and add the following
```javascript
const AggregateError = require('aggregate-error');
/**
* A method to verify that the user has given us a slack webhook url to post to
*/
module.exports = async (pluginConfig, context) => {
const { logger } = context;
const errors = [];
// Throw any errors we accumulated during the validation
if (errors.length > 0) {
throw new AggregateError(errors);
}
};
```
As of right now, this code won't do anything. However, if you were to run this plugin via `semantic-release`, it would run when the `verify` step occurred.
Following this structure, you can create different steps and checks to run through out the release process.
## Supporting Options
Let's say we want to verify that an `option` is passed. An `option` is a configuration object that is specific to your plugin. For example, the user may set an `option` in their release config like:
```js
{
prepare: {
path: "@semantic-release/my-special-plugin"
message: "My cool release message"
}
}
```
This `message` option will be passed to the `pluginConfig` object mentioned earlier. We can use the validation method we created to verify this option exists so we can perform logic based on that knowledge. In our `verify` file, we can add the following:
```js
const { message } = pluginConfig;
if (message.length) {
//...
}
```
## Supporting Environment Variables
Similar to `options`, environment variables exist to allow users to pass tokens and set special URLs. These are set on the `context` object instead of the `pluginConfig` object. Let's say we wanted to check for `GITHUB_TOKEN` in the environment because we want to post to GitHub on the user's behalf. To do this, we can add the following to our `verify` command:
```js
const { env } = context;
if (env.GITHUB_TOKEN) {
//...
}
```
@@ -5,3 +5,9 @@
- [@semantic-release/gitlab-config](https://github.com/semantic-release/gitlab-config) - semantic-release shareable configuration for GitLab
## Community configurations
- [@jedmao/semantic-release-npm-github-config](https://github.com/jedmao/semantic-release-npm-github-config)
- Provides an informative [git](https://github.com/semantic-release/git) commit message for the release commit that does not trigger continuous integration and conforms to the [conventional commits specification](https://www.conventionalcommits.org/) (e.g., "chore(release): 1.2.3 [skip ci]\n\nnotes").
- Creates a tarball that gets uploaded with each [GitHub release](https://github.com/semantic-release/github).
- Publishes the same tarball to [npm](https://github.com/semantic-release/npm).
- Commits the version change in `package.json`.
- Creates or updates a [changelog](https://github.com/semantic-release/changelog) file.
+5 -5
View File
@@ -4,7 +4,7 @@
**semantic-release** takes care of updating the `package.json`s version before publishing to [npm](https://www.npmjs.com).
By default, only the published package will contains the version, which is the only place where it is *really* required, but the updated `package.json` will not be pushed to the Git repository
By default, only the published package will contain the version, which is the only place where it is *really* required, but the updated `package.json` will not be pushed to the Git repository
However, the [`@semantic-release/git`](https://github.com/semantic-release/git) plugin can be used to push the updated `package.json` as well as other files to the Git repository.
@@ -141,11 +141,11 @@ See the [`@semantic-release/npm`](https://github.com/semantic-release/npm#semant
If you have introduced a breaking bug in a release you have 2 options:
- If you have a fix immediately ready, commit and push it (or merge it via a pull request) to the release branch
- Otherwise [revert the commit](https://git-scm.com/docs/git-revert) that introduced the bug and push the revert commit (or merge it via a pull request) to the release branch
- Otherwise, [revert the commit](https://git-scm.com/docs/git-revert) that introduced the bug and push the revert commit (or merge it via a pull request) to the release branch
In both cases **semantic-release** will publish a new release, so your package users' will get the fixed/reverted version.
In both cases **semantic-release** will publish a new release, so your package users will get the fixed/reverted version.
Depending on the package manager you are using, you might be able to un-publish or deprecate a release, in order to prevent users from downloading it by accident. For example npm allows you to [un-publish](https://docs.npmjs.com/cli/unpublish) [within 72 hours](https://www.npmjs.com/policies/unpublish) after releasing. You may also [deprecate](https://docs.npmjs.com/cli/deprecate) a release if you would rather avoid un-publishing.
Depending on the package manager you are using, you might be able to un-publish or deprecate a release, in order to prevent users from downloading it by accident. For example, npm allows you to [un-publish](https://docs.npmjs.com/cli/unpublish) [within 72 hours](https://www.npmjs.com/policies/unpublish) after release. You may also [deprecate](https://docs.npmjs.com/cli/deprecate) a release if you would rather avoid un-publishing.
In any case **do not remove the Git tag associated with the buggy version**, otherwise **semantic-release** will later try to republish that version. Publishing a version after un-publishing is not supported by most package managers.
@@ -236,7 +236,7 @@ In addition the [verify conditions step](../../README.md#release-steps) verifies
**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 8.3 or higher**.
See [Node version requirement](../support/node-version.md#node-version-requirement) for more details and solutions.
See [Node version requirement](./node-version.md#node-version-requirement) for more details and solutions.
## What is npx?
+15 -1
View File
@@ -2,12 +2,22 @@
## 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), [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).
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.
Here is a few example of the CI services that can be used to achieve this:
- [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)
- [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.
## Authentication
### Push access to the remote repository
**semantic-release** requires push access to the project Git repository in order to create [Git tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging). The Git authentication can be set with one of the following environment variables:
| Variable | Description |
@@ -19,6 +29,8 @@ See [CI configuration recipes](../recipes/README.md#ci-configurations) for more
Alternatively the Git authentication can be set up via [SSH keys](../recipes/git-auth-ssh-keys.md).
### Authentication for plugins
Most **semantic-release** [plugins](plugins.md) require setting up authentication in order to publish to a package manager registry. The default [@semantic-release/npm](https://github.com/semantic-release/npm#environment-variables) and [@semantic-release/github](https://github.com/semantic-release/github#environment-variables) plugins require the following environment variables:
| Variable | Description |
@@ -31,3 +43,5 @@ See each plugin's documentation for the environment variables required.
The authentication token/credentials have to be made available in the CI service via environment variables.
See [CI configuration recipes](../recipes/README.md#ci-configurations) for more details on how to configure environment variables in your CI service.
**Note**: The environment variables `GH_TOKEN`, `GITHUB_TOKEN`, `GL_TOKEN` and `GITLAB_TOKEN` can be used for both the Git authentication and the API authentication required by [@semantic-release/github](https://github.com/semantic-release/github) and [@semantic-release/gitlab](https://github.com/semantic-release/gitlab).
+10 -18
View File
@@ -1,17 +1,17 @@
# Configuration
**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))
- Git repository ([URL](#repositoryurl) and options [release branch](#branch) and [tag format](#tagformat))
- Plugins [declaration](#plugins) and options
- Run mode ([debug](#debug), [dry run](#dryrun) and [local (no CI)](#ci))
All of these options can be configured directly or by extending a [shareable configuration](shareable-configurations.md).
All of these options can be configured through config file, CLI arguments 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).
## Configuration file
**semantic-release**s [options](#options), mode and [plugins](plugins.md) can be set via:
**semantic-release**s [options](#options), mode and [plugins](plugins.md) can be set via either:
- A `.releaserc` file, written in YAML or JSON, with optional extensions: .`yaml`/`.yml`/`.json`/`.js`
- A `release.config.js` file that exports an object
- A `release` key in the project's `package.json` file
@@ -20,8 +20,7 @@ Alternatively, some options can be set via CLI arguments.
The following three examples are the same.
Via `release` key in the project's `package.json` file:
- Via `release` key in the project's `package.json` file:
```json
{
"release": {
@@ -29,23 +28,15 @@ Via `release` key in the project's `package.json` file:
}
}
```
```bash
$ semantic-release
```
Via `.releaserc` file:
- Via `.releaserc` file:
```json
{
"branch": "next"
}
```
```bash
$ semantic-release
```
Via CLI argument:
- Via CLI argument:
```bash
$ semantic-release --branch next
```
@@ -146,7 +137,8 @@ Output debugging information. This can also be enabled by setting the `DEBUG` en
## 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 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`).
**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.
+4 -4
View File
@@ -1,10 +1,10 @@
# Getting started
In order to use **semantic-release** you must follow these steps:
- [Install](./installation.md#installation) **semantic-release** in your project
- Configure your Continuous Integration service to [run **semantic-release**](./ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded)
- Configure your Git repository and package manager repository [authentication](ci-configuration.md#authentication) in your Continuous Integration service
- Configure **semantic-release** [options and plugins](./configuration.md#configuration)
1. [Install](./installation.md#installation) **semantic-release** in your project
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):
+2 -2
View File
@@ -24,6 +24,6 @@ For other type of projects we recommend installing **semantic-release** directly
$ npx semantic-release
```
**Note:** For a global installation, it's recommended to specify the major **semantic-release** version to install (for example with with `npx semantic-release@15`, or `npm install -g semantic-release@15`). This way your build will not automatically use the next major **semantic-release** release that could possibly break your build. You will have to upgrade manually when a new major version is released.
**Note**: For a global installation, it's recommended to specify the major **semantic-release** version to install (for example with with `npx semantic-release@15`). This way your build will not automatically use the next major **semantic-release** release that could possibly break your build. You will have to upgrade manually when a new major version is released.
**Note:** `npx` is a tool bundled with `npm@>=5.2.0`. It is used to conveniently install the semantic-release binary and to execute it. See [What is npx](../support/FAQ.md#what-is-npx) for more details.
**Note**: `npx` is a tool bundled with `npm@>=5.2.0`. It is used to conveniently install the semantic-release binary and to execute it. See [What is npx](../support/FAQ.md#what-is-npx) for more details.
+14 -11
View File
@@ -19,22 +19,25 @@ A plugin is a npm module that can implement one or more of the following steps:
## Plugins installation
These five plugins are already part of **semantic-release** and don't have to be installed separately:
### Default plugins
These four plugins are already part of **semantic-release** and don't have to be installed separately:
```
"@semantic-release/commit-analyzer"
"@semantic-release/error"
"@semantic-release/github"
"@semantic-release/npm"
"@semantic-release/commit-analyzer"
"@semantic-release/github"
"@semantic-release/npm"
"@semantic-release/release-notes-generator"
```
### Additional plugins
[Additional plugins](../extending/plugins-list.md) have to be installed via npm:
```bash
$ npm install @semantic-release/git @semantic-release/changelog -D
```
## Plugins configuration
## Plugins declaration and execution order
Each plugin must be configured with the [`plugins` options](./configuration.md#plugins) by specifying the list of plugins by npm module name.
@@ -44,9 +47,9 @@ Each plugin must be configured with the [`plugins` options](./configuration.md#p
}
```
## Plugin ordering
**Note:** If the `plugins` option is defined, it overrides the default plugin list, rather than merging with it.
For each [release step](../../README.md#release-steps) the plugins that implement that step will be executed in the order in which the are defined.
For each [release step](../../README.md#release-steps) the plugins that implement that step will be executed in the order in which they are defined.
```json
{
@@ -66,11 +69,11 @@ With this configuration **semantic-release** will:
- execute the `generateNotes` implementation of `@semantic-release/release-notes-generator`
- execute the `publish` implementation of `@semantic-release/npm`
## Plugin options
## Plugin options configuration
A plugin options can specified by wrapping the name and an options object in an array. Options configured this way will be passed only to that specific plugin.
A plugin configuration can be specified by wrapping the name and an options object in an array. Options configured this way will be passed only to that specific plugin.
Global plugin options can defined at the root of the **semantic-release** configuration object. Options configured this way will be passed to all plugins.
Global plugin configuration can be defined at the root of the **semantic-release** configuration object. Options configured this way will be passed to all plugins.
```json
{
+3 -3
View File
@@ -1,3 +1,5 @@
/* eslint require-atomic-updates: off */
const {template, pick} = require('lodash');
const marked = require('marked');
const TerminalRenderer = require('marked-terminal');
@@ -46,9 +48,7 @@ async function run(context, plugins) {
if (ciBranch !== options.branch) {
logger.log(
`This test run was triggered on the branch ${ciBranch}, while semantic-release is configured to only publish from ${
options.branch
}, therefore a new version wont be published.`
`This test run was triggered on the branch ${ciBranch}, while semantic-release is configured to only publish from ${options.branch}, therefore a new version wont be published.`
);
return false;
}
+8 -7
View File
@@ -27,16 +27,17 @@ Please make sure to add the \`repositoryUrl\` to the [semantic-release configura
)}).`,
}),
EGITNOPERMISSION: ({options}) => ({
message: 'The push permission to the Git repository is required.',
message: 'Cannot push to the Git repository.',
details: `**semantic-release** cannot push the version tag to the branch \`${
options.branch
}\` on remote Git repository with URL \`${options.repositoryUrl}\`.
}\` on the remote Git repository with URL \`${options.repositoryUrl}\`.
Please refer to the [authentication configuration documentation](${linkify(
'docs/usage/ci-configuration.md#authentication'
)}) to configure the Git credentials on your CI environment and make sure the [repositoryUrl](${linkify(
'docs/usage/configuration.md#repositoryurl'
)}) is configured with a [valid Git URL](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols).`,
This can be caused by:
- a misconfiguration of the [repositoryUrl](${linkify('docs/usage/configuration.md#repositoryurl')}) option
- the repository being unavailable
- or missing push permission for the user configured via the [Git credentials on your CI environment](${linkify(
'docs/usage/ci-configuration.md#authentication'
)})`,
}),
EINVALIDTAGFORMAT: ({tagFormat}) => ({
message: 'Invalid `tagFormat` option.',
+2
View File
@@ -1,3 +1,5 @@
/* eslint require-atomic-updates: off */
const {isString, isPlainObject} = require('lodash');
const {getGitHead} = require('../git');
const hideSensitive = require('../hide-sensitive');
+2 -2
View File
@@ -85,6 +85,6 @@ module.exports = async (context, opts) => {
};
async function pkgRepoUrl(opts) {
const {package: pkg} = (await readPkgUp(opts)) || {};
return pkg && (isPlainObject(pkg.repository) ? pkg.repository.url : pkg.repository);
const {packageJson} = (await readPkgUp(opts)) || {};
return packageJson && (isPlainObject(packageJson.repository) ? packageJson.repository.url : packageJson.repository);
}
+19 -12
View File
@@ -3,16 +3,6 @@ const {isNil} = require('lodash');
const hostedGitInfo = require('hosted-git-info');
const {verifyAuth} = require('./git');
const GIT_TOKENS = {
GIT_CREDENTIALS: undefined,
GH_TOKEN: undefined,
GITHUB_TOKEN: undefined,
GL_TOKEN: 'gitlab-ci-token:',
GITLAB_TOKEN: 'gitlab-ci-token:',
BB_TOKEN: 'x-token-auth:',
BITBUCKET_TOKEN: 'x-token-auth:',
};
/**
* Determine the the git repository URL to use to push, either:
* - The `repositoryUrl` as is if allowed to push
@@ -25,6 +15,18 @@ const GIT_TOKENS = {
* @return {String} The formatted Git repository URL.
*/
module.exports = async ({cwd, env, options: {repositoryUrl, branch}}) => {
const GIT_TOKENS = {
GIT_CREDENTIALS: undefined,
GH_TOKEN: undefined,
// GitHub Actions require the "x-access-token:" prefix for git access
// https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#http-based-git-access-by-an-installation
GITHUB_TOKEN: isNil(env.GITHUB_ACTION) ? undefined : 'x-access-token:',
GL_TOKEN: 'gitlab-ci-token:',
GITLAB_TOKEN: 'gitlab-ci-token:',
BB_TOKEN: 'x-token-auth:',
BITBUCKET_TOKEN: 'x-token-auth:',
};
const info = hostedGitInfo.fromUrl(repositoryUrl, {noGitPlus: true});
const {protocol, ...parsed} = parse(repositoryUrl);
@@ -39,16 +41,21 @@ module.exports = async ({cwd, env, options: {repositoryUrl, branch}}) => {
// Test if push is allowed without transforming the URL (e.g. is ssh keys are set up)
try {
await verifyAuth(repositoryUrl, branch, {cwd, env});
} catch (error) {
} catch (_) {
const envVar = Object.keys(GIT_TOKENS).find(envVar => !isNil(env[envVar]));
const gitCredentials = `${GIT_TOKENS[envVar] || ''}${env[envVar] || ''}`;
if (gitCredentials) {
// If credentials are set via environment variables, convert the URL to http/https and add basic auth, otherwise return `repositoryUrl` as is
const [match, auth, host, path] = /^(?!.+:\/\/)(?:(.*)@)?(.*?):(.*)$/.exec(repositoryUrl) || [];
const {port, hostname, ...parsed} = parse(
match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : repositoryUrl
);
return format({
...parse(match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : repositoryUrl),
...parsed,
auth: gitCredentials,
host: `${hostname}${protocol === 'ssh:' ? '' : port ? `:${port}` : ''}`,
protocol: protocol && /http[^s]/.test(protocol) ? 'http' : 'https',
});
}
+7 -7
View File
@@ -11,7 +11,7 @@ const debug = require('debug')('semantic-release:git');
*/
async function getTagHead(tagName, execaOpts) {
try {
return await execa.stdout('git', ['rev-list', '-1', tagName], execaOpts);
return (await execa('git', ['rev-list', '-1', tagName], execaOpts)).stdout;
} catch (error) {
debug(error);
}
@@ -26,7 +26,7 @@ async function getTagHead(tagName, execaOpts) {
* @throws {Error} If the `git` command fails.
*/
async function getTags(execaOpts) {
return (await execa.stdout('git', ['tag'], execaOpts))
return (await execa('git', ['tag'], execaOpts)).stdout
.split('\n')
.map(tag => tag.trim())
.filter(Boolean);
@@ -63,7 +63,7 @@ async function isRefInHistory(ref, execaOpts) {
async function fetch(repositoryUrl, execaOpts) {
try {
await execa('git', ['fetch', '--unshallow', '--tags', repositoryUrl], execaOpts);
} catch (error) {
} catch (_) {
await execa('git', ['fetch', '--tags', repositoryUrl], execaOpts);
}
}
@@ -75,8 +75,8 @@ async function fetch(repositoryUrl, execaOpts) {
*
* @return {String} the sha of the HEAD commit.
*/
function getGitHead(execaOpts) {
return execa.stdout('git', ['rev-parse', 'HEAD'], execaOpts);
async function getGitHead(execaOpts) {
return (await execa('git', ['rev-parse', 'HEAD'], execaOpts)).stdout;
}
/**
@@ -88,7 +88,7 @@ function getGitHead(execaOpts) {
*/
async function repoUrl(execaOpts) {
try {
return await execa.stdout('git', ['config', '--get', 'remote.origin.url'], execaOpts);
return (await execa('git', ['config', '--get', 'remote.origin.url'], execaOpts)).stdout;
} catch (error) {
debug(error);
}
@@ -176,7 +176,7 @@ async function verifyTagName(tagName, execaOpts) {
* @return {Boolean} `true` is the HEAD of the current local branch is the same as the HEAD of the remote branch, falsy otherwise.
*/
async function isBranchUpToDate(branch, execaOpts) {
const remoteHead = await execa.stdout('git', ['ls-remote', '--heads', 'origin', branch], execaOpts);
const {stdout: remoteHead} = await execa('git', ['ls-remote', '--heads', 'origin', branch], execaOpts);
try {
return await isRefInHistory(remoteHead.match(/^(\w+)?/)[1], execaOpts);
} catch (error) {
+19 -19
View File
@@ -3,17 +3,20 @@
"description": "Automated semver compliant package publishing",
"version": "0.0.0-development",
"author": "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)",
"ava": {
"files": [
"test/**/*.test.js"
],
"helpers": [
"test/helpers/**/*"
]
},
"bin": {
"semantic-release": "bin/semantic-release.js"
},
"bugs": {
"url": "https://github.com/semantic-release/semantic-release/issues"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"contributors": [
"Gregor Martynus (https://twitter.com/gr2m)",
"Pierre Vanduynslager (https://twitter.com/@pvdlg_)"
@@ -27,46 +30,44 @@
"aggregate-error": "^3.0.0",
"cosmiconfig": "^5.0.1",
"debug": "^4.0.0",
"env-ci": "^3.0.0",
"env-ci": "^4.0.0",
"execa": "^1.0.0",
"figures": "^3.0.0",
"find-versions": "^3.0.0",
"get-stream": "^5.0.0",
"git-log-parser": "^1.2.0",
"hook-std": "^2.0.0",
"hosted-git-info": "^2.7.1",
"lodash": "^4.17.4",
"marked": "^0.6.0",
"hosted-git-info": "^3.0.0",
"lodash": "^4.17.15",
"marked": "^0.7.0",
"marked-terminal": "^3.2.0",
"p-locate": "^4.0.0",
"p-reduce": "^2.0.0",
"read-pkg-up": "^6.0.0",
"read-pkg-up": "^7.0.0",
"resolve-from": "^5.0.0",
"semver": "^6.0.0",
"signale": "^1.2.1",
"yargs": "^13.1.0"
"yargs": "^14.0.0"
},
"devDependencies": {
"ava": "^1.3.1",
"clear-module": "^3.0.0",
"ava": "^2.0.0",
"clear-module": "^4.0.0",
"codecov": "^3.0.0",
"commitizen": "^3.0.0",
"cz-conventional-changelog": "^2.0.0",
"delay": "^4.0.0",
"dockerode": "^2.5.2",
"dockerode": "^3.0.0",
"file-url": "^3.0.0",
"fs-extra": "^8.0.0",
"got": "^9.0.0",
"js-yaml": "^3.10.0",
"mockserver-client": "^5.1.1",
"nock": "^10.0.0",
"nock": "^11.1.0",
"nyc": "^14.0.0",
"p-retry": "^4.0.0",
"proxyquire": "^2.0.0",
"sinon": "^7.2.7",
"stream-buffers": "^3.0.2",
"tempy": "^0.3.0",
"xo": "^0.24.0"
"xo": "^0.25.0"
},
"engines": {
"node": ">=8.3"
@@ -117,7 +118,6 @@
"url": "git+https://github.com/semantic-release/semantic-release.git"
},
"scripts": {
"cm": "git-cz",
"codecov": "codecov -f coverage/coverage-final.json",
"lint": "xo",
"pretest": "npm run lint",
+18 -18
View File
@@ -66,7 +66,7 @@ test.serial('Pass options to semantic-release API', async t => {
];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.is(run.args[0][0].branch, 'master');
t.is(run.args[0][0].repositoryUrl, 'https://github/com/owner/repo.git');
@@ -84,7 +84,7 @@ test.serial('Pass options to semantic-release API', async t => {
t.is(run.args[0][0].debug, true);
t.is(run.args[0][0].dryRun, true);
t.is(exitCode, 0);
t.is(code, 0);
});
test.serial('Pass options to semantic-release API with alias arguments', async t => {
@@ -108,7 +108,7 @@ test.serial('Pass options to semantic-release API with alias arguments', async t
];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.is(run.args[0][0].branch, 'master');
t.is(run.args[0][0].repositoryUrl, 'https://github/com/owner/repo.git');
@@ -117,7 +117,7 @@ test.serial('Pass options to semantic-release API with alias arguments', async t
t.deepEqual(run.args[0][0].extends, ['config1', 'config2']);
t.is(run.args[0][0].dryRun, true);
t.is(exitCode, 0);
t.is(code, 0);
});
test.serial('Pass unknown options to semantic-release API', async t => {
@@ -125,13 +125,13 @@ test.serial('Pass unknown options to semantic-release API', async t => {
const argv = ['', '', '--bool', '--first-option', 'value1', '--second-option', 'value2', '--second-option', 'value3'];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.is(run.args[0][0].bool, true);
t.is(run.args[0][0].firstOption, 'value1');
t.deepEqual(run.args[0][0].secondOption, ['value2', 'value3']);
t.is(exitCode, 0);
t.is(code, 0);
});
test.serial('Pass empty Array to semantic-release API for list option set to "false"', async t => {
@@ -139,11 +139,11 @@ test.serial('Pass empty Array to semantic-release API for list option set to "fa
const argv = ['', '', '--publish', 'false'];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.deepEqual(run.args[0][0].publish, []);
t.is(exitCode, 0);
t.is(code, 0);
});
test.serial('Do not set properties in option for which arg is not in command line', async t => {
@@ -168,10 +168,10 @@ test.serial('Display help', async t => {
const argv = ['', '', '--help'];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.regex(t.context.logs, /Run automated package publishing/);
t.is(exitCode, 0);
t.is(code, 0);
});
test.serial('Return error code and prints help if called with a command', async t => {
@@ -179,11 +179,11 @@ test.serial('Return error code and prints help if called with a command', async
const argv = ['', '', 'pre'];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.regex(t.context.errors, /Run automated package publishing/);
t.regex(t.context.errors, /Too many non-option arguments/);
t.is(exitCode, 1);
t.is(code, 1);
});
test.serial('Return error code if multiple plugin are set for single plugin', async t => {
@@ -191,11 +191,11 @@ test.serial('Return error code if multiple plugin are set for single plugin', as
const argv = ['', '', '--analyze-commits', 'analyze1', 'analyze2'];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.regex(t.context.errors, /Run automated package publishing/);
t.regex(t.context.errors, /Too many non-option arguments/);
t.is(exitCode, 1);
t.is(code, 1);
});
test.serial('Return error code if semantic-release throw error', async t => {
@@ -203,10 +203,10 @@ test.serial('Return error code if semantic-release throw error', async t => {
const argv = ['', ''];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv}});
const exitCode = await cli();
const code = await cli();
t.regex(t.context.errors, /semantic-release error/);
t.is(exitCode, 1);
t.is(code, 1);
});
test.serial('Hide sensitive environment variable values from the logs', async t => {
@@ -215,8 +215,8 @@ test.serial('Hide sensitive environment variable values from the logs', async t
const argv = ['', ''];
const cli = requireNoCache('../cli', {'.': run, process: {...process, argv, env: {...process.env, ...env}}});
const exitCode = await cli();
const code = await cli();
t.regex(t.context.errors, new RegExp(`Throw error: Exposing token ${escapeRegExp(SECRET_REPLACEMENT)}`));
t.is(exitCode, 1);
t.is(code, 1);
});
+1 -1
View File
@@ -482,6 +482,6 @@ test('Throw an Error if one of the shareable config cannot be found', async t =>
const error = await t.throwsAsync(t.context.getConfig({cwd}), Error);
t.is(error.message, "Cannot find module 'non-existing-path'");
t.regex(error.message, /Cannot find module 'non-existing-path'/);
t.is(error.code, 'MODULE_NOT_FOUND');
});
+43 -4
View File
@@ -70,8 +70,8 @@ test('Convert shorthand URL', async t => {
const {cwd} = await gitRepo();
t.is(
await getAuthUrl({cwd, env, options: {repositoryUrl: 'semanitc-release/semanitc-release'}}),
'https://github.com/semanitc-release/semanitc-release.git'
await getAuthUrl({cwd, env, options: {repositoryUrl: 'semantic-release/semantic-release'}}),
'https://github.com/semantic-release/semantic-release.git'
);
});
@@ -82,9 +82,9 @@ test('Convert GitLab shorthand URL', async t => {
await getAuthUrl({
cwd,
env,
options: {branch: 'master', repositoryUrl: 'gitlab:semanitc-release/semanitc-release'},
options: {branch: 'master', repositoryUrl: 'gitlab:semantic-release/semantic-release'},
}),
'https://gitlab.com/semanitc-release/semanitc-release.git'
'https://gitlab.com/semantic-release/semantic-release.git'
);
});
@@ -140,6 +140,19 @@ test('Return the "http" formatted URL if "gitCredentials" is defined and reposit
);
});
test('Return the "http" formatted URL if "gitCredentials" is defined and repositoryUrl is a "http" URL with custom port', async t => {
const {cwd} = await gitRepo();
t.is(
await getAuthUrl({
cwd,
env: {...env, GIT_CREDENTIALS: 'user:pass'},
options: {branch: 'master', repositoryUrl: 'http://host.null:8080/owner/repo.git'},
}),
'http://user:pass@host.null:8080/owner/repo.git'
);
});
test('Return the "https" formatted URL if "gitCredentials" is defined and repositoryUrl is a "git+https" URL', async t => {
const {cwd} = await gitRepo();
@@ -166,6 +179,19 @@ test('Return the "http" formatted URL if "gitCredentials" is defined and reposit
);
});
test('Return the "http" formatted URL if "gitCredentials" is defined and repositoryUrl is a "ssh" URL', async t => {
const {cwd} = await gitRepo();
t.is(
await getAuthUrl({
cwd,
env: {...env, GIT_CREDENTIALS: 'user:pass'},
options: {branch: 'master', repositoryUrl: 'ssh://git@host.null:2222/owner/repo.git'},
}),
'https://user:pass@host.null/owner/repo.git'
);
});
test('Return the "https" formatted URL if "gitCredentials" is defined with "GH_TOKEN"', async t => {
const {cwd} = await gitRepo();
@@ -244,6 +270,19 @@ test('Return the "https" formatted URL if "gitCredentials" is defined with "BITB
);
});
test('Return the "https" formatted URL if "GITHUB_ACTION" is set', async t => {
const {cwd} = await gitRepo();
t.is(
await getAuthUrl({
cwd,
env: {...env, GITHUB_ACTION: 'foo', GITHUB_TOKEN: 'token'},
options: {branch: 'master', repositoryUrl: 'git@host.null:owner/repo.git'},
}),
'https://x-access-token:token@host.null/owner/repo.git'
);
});
test('Handle "https" URL with group and subgroup, with "GIT_CREDENTIALS"', async t => {
const {cwd} = await gitRepo();
+14 -12
View File
@@ -69,8 +69,10 @@ export async function initBareRepo(repositoryUrl, branch = 'master') {
* @returns {Array<Commit>} The created commits, in reverse order (to match `git log` order).
*/
export async function gitCommits(messages, execaOpts) {
await pReduce(messages, (_, message) =>
execa.stdout('git', ['commit', '-m', message, '--allow-empty', '--no-gpg-sign'], execaOpts)
await pReduce(
messages,
async (_, message) =>
(await execa('git', ['commit', '-m', message, '--allow-empty', '--no-gpg-sign'], execaOpts)).stdout
);
return (await gitGetCommits(undefined, execaOpts)).slice(0, messages.length);
}
@@ -98,10 +100,10 @@ export async function gitGetCommits(from, execaOpts) {
* Checkout a branch on the current git repository.
*
* @param {String} branch Branch name.
* @param {Boolean} create `true` to create the branch, `false` to checkout an existing branch.
* @param {Boolean} create to create the branch, `false` to checkout an existing branch.
* @param {Object} [execaOpts] Options to pass to `execa`.
*/
export async function gitCheckout(branch, create = true, execaOpts) {
export async function gitCheckout(branch, create, execaOpts) {
await execa('git', create ? ['checkout', '-b', branch] : ['checkout', branch], execaOpts);
}
@@ -112,8 +114,8 @@ export async function gitCheckout(branch, create = true, execaOpts) {
*
* @return {String} The sha of the head commit in the current git repository.
*/
export function gitHead(execaOpts) {
return execa.stdout('git', ['rev-parse', 'HEAD'], execaOpts);
export async function gitHead(execaOpts) {
return (await execa('git', ['rev-parse', 'HEAD'], execaOpts)).stdout;
}
/**
@@ -181,8 +183,8 @@ export async function gitAddConfig(name, value, execaOpts) {
*
* @return {String} The sha of the commit associated with `tagName` on the local repository.
*/
export function gitTagHead(tagName, execaOpts) {
return execa.stdout('git', ['rev-list', '-1', tagName], execaOpts);
export async function gitTagHead(tagName, execaOpts) {
return (await execa('git', ['rev-list', '-1', tagName], execaOpts)).stdout;
}
/**
@@ -195,7 +197,7 @@ export function gitTagHead(tagName, execaOpts) {
* @return {String} The sha of the commit associated with `tagName` on the remote repository.
*/
export async function gitRemoteTagHead(repositoryUrl, tagName, execaOpts) {
return (await execa.stdout('git', ['ls-remote', '--tags', repositoryUrl, tagName], execaOpts))
return (await execa('git', ['ls-remote', '--tags', repositoryUrl, tagName], execaOpts)).stdout
.split('\n')
.filter(tag => Boolean(tag))
.map(tag => tag.match(/^(\S+)/)[1])[0];
@@ -209,8 +211,8 @@ export async function gitRemoteTagHead(repositoryUrl, tagName, execaOpts) {
*
* @return {String} The tag associatedwith the sha in parameter or `null`.
*/
export function gitCommitTag(gitHead, execaOpts) {
return execa.stdout('git', ['describe', '--tags', '--exact-match', gitHead], execaOpts);
export async function gitCommitTag(gitHead, execaOpts) {
return (await execa('git', ['describe', '--tags', '--exact-match', gitHead], execaOpts)).stdout;
}
/**
@@ -222,6 +224,6 @@ export function gitCommitTag(gitHead, execaOpts) {
*
* @throws {Error} if the push failed.
*/
export async function gitPush(repositoryUrl = 'origin', branch = 'master', execaOpts) {
export async function gitPush(repositoryUrl, branch, execaOpts) {
await execa('git', ['push', '--tags', repositoryUrl, `HEAD:${branch}`], execaOpts);
}
+1 -1
View File
@@ -30,7 +30,7 @@ async function start() {
minTimeout: 1000,
factor: 2,
});
} catch (error) {
} catch (_) {
throw new Error(`Couldn't start mock-server after 2 min`);
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ async function start() {
minTimeout: 1000,
factor: 2,
});
} catch (error) {
} catch (_) {
throw new Error(`Couldn't start npm-registry-docker after 2 min`);
}
+1 -1
View File
@@ -255,6 +255,6 @@ test('Throws an error if the plugin is not found', t => {
Error
);
t.is(error.message, "Cannot find module 'non-existing-path'");
t.regex(error.message, /Cannot find module 'non-existing-path'/);
t.is(error.code, 'MODULE_NOT_FOUND');
});