# release-script

Release tool for npm and bower packages.

[![Build Status](https://travis-ci.org/AlexKVal/release-script.svg)](https://travis-ci.org/AlexKVal/release-script)

---
#### Description

With this tool there is no need to keep (transpiled) `lib`, `build`
or `distr` files in the git repo.

Because `Bower` keeps its files in the github repo,
this tools helps to deal with that too.

Just create new additional github repo for `Bower` version of your project.
This repo will contain only commits generated by this tool.

Say the name of your project is
`original-project-name`
then name the `bower` github repo as
`original-project-name-bower`.

Add `'release-script'.bowerRepo` into your `package.json`:
```json
"release-script": {
  "bowerRepo": "git@github.com:<author>/original-project-name-bower.git"
}
```

Then add additional step into your building process,
which will create `bower` package files in the `amd` folder,
(basically it is just a process of copying the `lib` files, README and LICENSE)
and that's all.

Now `release-script` will do all those steps (described next),
including `bower` publishing, for you - automatically.


_Initial idea is got from `React-Bootstrap` release tools `./tools/release`,
that have been written by [Matt Smith @mtscout6](https://github.com/mtscout6)_

_Kind of "migration manual"_ https://github.com/AlexKVal/release-script/issues/23

#### Documentation pages publishing

If your project generates static documentation pages (as `React-Boostrap` does)
and needs publishing them to a standalone repo (via `git push`), just create additional github repo for the documentation pages.

E.g. [react-bootstrap.github.io.git](https://github.com/react-bootstrap/react-bootstrap.github.io)

Add it as `'release-script'.docsRepo` into your `package.json`:
```json
"release-script": {
  "docsRepo": "git@github.com:<author>/original-project-name-github.io.git"
}
```
Default folders for documentation pages are:
- `"docsRoot": "docs-built"` folder where the files will be built to. (by your custom building script)
- `"tmpDocsRepo": "tmp-docs-repo"` temporary folder. (for the release-script usage)

It is advised to add them both into `.gitignore`.

You can customize them as you need:
```json
"release-script": {
  "docsRepo": "git@github.com:<author>/original-project-name-github.io.git",
  "docsRoot": "docs-built",
  "tmpDocsRepo": "tmp-docs-repo"
}
```

If you need to publish only documentation pages (say with some minor fixes),
you can do it this way:
```
> release --only-docs
```
In this case the `package.json` version will be bumped with `--preid docs` as `0.10.0` => `0.10.0-docs.0`.

If `npm run docs-build` script is present, then it will be used instead of `npm run build` script.

*Note: Documentation pages are not published when you are releasing "pre-release" version,
(i.e. when you run it with `--preid` option).*

#### Pre-release versions publishing

Say you need to publish pre-release `v0.25.100-pre.0` version
with the `canary` npm tag name (instead of default one `latest`).

You can do it this way:
```
> release 0.25.100 --preid pre --tag canary
or
> npm run release 0.25.100 -- --preid pre --tag canary
```

If your `preid` tag and npm tag are the same, then you can just:
```
> release 0.25.100 --preid beta
```
It will produce `v0.25.100-beta.0` and `npm publish --tag beta`.

`changelog` generated output will go into `CHANGELOG-alpha.md` for pre-releases,
and with the next release this file will be removed.

#### Alternative npm package root folder

Say you want to publish the content of your `lib` folder as an npm package's root folder.
Then you can do it as simple as adding the following to your `package.json`
```json
"release-script": {
  "altPkgRootFolder": "lib"
}
```
and that's all.

#### The special case. `build` step in `tests` step.

If you run building scripts within your `npm run test` step, e.g.
```json
"scripts": {
  "test": "npm run lint && npm run build && npm run tests-set",
}
```
then you can prevent `npm run build` step from running
by setting `'release-script'.skipBuildStep` option:
```json
"release-script": {
  "skipBuildStep": "true"
}
```

#### Options

All options for this package are kept under `'release-script'` node in your project's `package.json`

- `bowerRepo` - the full url to github project for the bower pkg files
- `bowerRoot` - the folder name where your `npm run build` command will put/transpile files for bower pkg
  - `default` value: `'amd'`
- `tmpBowerRepo` - the folder name for temporary files for bower pkg.
  - `default` value: `'tmp-bower-repo'`
- `altPkgRootFolder` - the folder name for alternative npm package's root folder

It is advised to add `bowerRoot` and `tmpBowerRepo` folders to your `.gitignore` file.

Example:
```json
"release-script": {
  "bowerRepo": "git@github.com:<org-author-name>/<name-of-project>-bower.git",
  "bowerRoot": "amd",
  "tmpBowerRepo": "tmp-bower-repo",
  "altPkgRootFolder": "lib"
}
```

#### GitHub releases

If you need this script to publish github releases,
you can generate a github token at https://github.com/settings/tokens
and put it to `env.GITHUB_TOKEN` this way:
```sh
> GITHUB_TOKEN="xxxxxxxxxxxx" && release-script patch
```
or into your shell scripts
```sh
export GITHUB_TOKEN="xxxxxxxxxxxx"
```
You can set a custom message for github release via `--notes` CLI option:
```
> release patch --notes "This is a small fix"
```

#### If you need `dry-run` mode by default

You can setup the `release-script` to run in `dry-run` mode by default.

It can be done by setting `"true"` the `defaultDryRun` option in your `package.json`:
```json
"release-script": {
  "defaultDryRun": "true"
}
```
Then to actually run your commands you will have to add `--run`.


#### This script does the following steps:

- ensures that git repo has no pending changes
- ensures that the latest version is fetched
- checks linting and tests by running `npm run test` command
- does version bumping
- builds all by running `npm run build` command
  - If there is no `build` script, then `release-script` just skips the `build` step.
- if one of `[rf|mt]-changelog` is used in 'devDependencies', then changelog is to be generated
- adds and commits `package.json` with changed version and `CHANGELOG.md` if it's used
- adds git tag with new version and changelog message if it's used
- pushes changes to github repo
- if github token is present the script publishes the release to the GitHub
- if `--preid` tag set then `npm publish --tag` command for npm publishing is used
  - with `--tag` option one can set `npm tag name` for a pre-release version (e.g. `alpha` or `canary`)
  - otherwise `--preid` value will be used
- if `altPkgRootFolder` isn't set it will just `npm publish [--tag]` as usual. Otherwise:
  - the release-script will `npm publish [--tag]` from the inside `altPkgRootFolder` folder
  - `scripts` and `devDependencies` will be removed from `package.json`
- if `bowerRepo` field is present in the `package.json` then bower package will be released.
  - the script will clone the bower repo to the `tmpBowerRepo` folder
  - clean up all files but `.git` in the `tmpBowerRepo` folder
  - copy all files from `bowerRoot` to `tmpBowerRepo` (they has to be generated by `npm run build`)
  - add all files to the temporary git repo with `git add -A .`
  - then it will commit, tag and push. The same as for the `npm` package.
  - and at the end it will remove the `tmpBowerRepo` folder
- if `docsRepo` option is set then documentation pages are being pushed to their repo.
  It is done the same way as `bower` publishing process.

If `--only-docs` command line option is set then `github`, `npm` and `bower` publishing steps will be skipped.

## Installation

```sh
> npm install -D release-script
```

If you need `bower` releases too then add `'release-script'.bowerRepo` into your `package.json`:
```json
"release-script": {
  "bowerRepo": "git@github.com:<org-author-name>/<name-of-project>-bower.git"
}
```

If you have smth like that in your shell:
```sh
# npm
export PATH="./node_modules/.bin:$PATH"
```
or you had installed `release-script` globally via `npm install -g release-script`,
then you can release your new versions this way:
```sh
> release patch
or
> release minor --preid alpha
```

Otherwise you need to type in the commands this way:
```sh
> ./node_modules/.bin/release minor --preid alpha
```

You can as well add some helpful `script` commands to your `package.json`:
```json
"scripts": {
    ...
    "patch": "release patch",
    "minor": "release minor",
    "major": "release major"
```

And you can add it like this:
```json
"scripts": {
    ...
    "release": "release",
```
This way it became possible to run it like that:
```
> npm run release minor -- --preid alpha
> npm run release patch -- --notes "This is small fix"
> npm run release major --dry-run // for dry run
etc
```
_Notice: You have to add additional double slash `--` before any `--option`. This way additional options get through to `release-script`._


## License
`release-script` is licensed under the [MIT License](https://github.com/alexkval/release-script/blob/master/LICENSE).
