UNPKG

17.9 kBMarkdownView Raw
1# @semantic-release/git
2
3[**semantic-release**](https://github.com/semantic-release/semantic-release) plugin to commit release assets to the project's [git](https://git-scm.com/) repository.
4
5[![Build Status](https://github.com/semantic-release/git/workflows/Test/badge.svg)](https://github.com/semantic-release/git/actions?query=workflow%3ATest+branch%3Amaster) [![npm latest version](https://img.shields.io/npm/v/@semantic-release/git/latest.svg)](https://www.npmjs.com/package/@semantic-release/git)
6[![npm next version](https://img.shields.io/npm/v/@semantic-release/git/next.svg)](https://www.npmjs.com/package/@semantic-release/git)
7[![npm beta version](https://img.shields.io/npm/v/@semantic-release/git/beta.svg)](https://www.npmjs.com/package/@semantic-release/git)
8
9| Step | Description |
10|--------------------|------------------------------------------------------------------------------------------------------------------------------------|
11| `verifyConditions` | Verify the access to the remote Git repository, the commit [`message`](#message) and the [`assets`](#assets) option configuration. |
12| `prepare` | Create a release commit, including configurable file assets. |
13
14## Install
15
16```bash
17$ npm install @semantic-release/git -D
18```
19
20## Usage
21
22The plugin can be configured in the [**semantic-release** configuration file](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration):
23
24```json
25{
26 "plugins": [
27 "@semantic-release/commit-analyzer",
28 "@semantic-release/release-notes-generator",
29 ["@semantic-release/git", {
30 "assets": ["dist/**/*.{js,css}", "docs", "package.json"],
31 "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
32 }]
33 ]
34}
35```
36
37With this example, for each release a release commit will be pushed to the remote Git repository with:
38- a message formatted like `chore(release): <version> [skip ci]\n\n<release notes>`
39- the `.js` and `.css` files in the `dist` directory, the files in the `docs` directory and the `package.json`
40
41### Merging between semantic-release branches
42
43This plugin will, by default, create commit messages with the keyword `[skip ci]`, so they won't trigger a new unnecessary CI build. If you are using **semantic-release** with [multiple branches](https://github.com/semantic-release/semantic-release/blob/beta/docs/usage/workflow-configuration.md), when merging a branch with a head being a release commit, a CI job will be triggered on the target branch. Depending on the CI service that might create an unexpected behavior as the head of the target branch might be ignored by the build due to the `[skip ci]` keyword.
44
45To avoid any unexpected behavior we recommend to use the [`--no-ff` option](https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---no-ff) when merging branches used by **semantic-release**.
46
47**Note**: This concerns only merges done between two branches configured in the [`branches` option](https://github.com/semantic-release/semantic-release/blob/beta/docs/usage/configuration.md#branches).
48
49## Configuration
50
51### Git authentication
52
53The Git user associated with the [Git credentials](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/ci-configuration.md#authentication) has to be able to push commit to the [release branch](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#branch).
54
55When configuring branches permission on a Git hosting service (e.g. [GitHub protected branches](https://help.github.com/articles/about-protected-branches), [GitLab protected branches](https://docs.gitlab.com/ee/user/project/protected_branches.html) or [Bitbucket branch permissions](https://confluence.atlassian.com/bitbucket/branch-permissions-385912271.html)) it might be necessary to create a specific configuration in order to allow the **semantic-release** user to bypass global restrictions. For example on GitHub you can uncheck "Include administrators" and configure **semantic-release** to use an administrator user, so the plugin can push the release commit without requiring [status checks](https://help.github.com/articles/about-required-status-checks) and [pull request reviews](https://help.github.com/articles/about-required-reviews-for-pull-requests).
56
57### Environment variables
58
59| Variable | Description | Default |
60|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
61| `GIT_AUTHOR_NAME` | The author name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
62| `GIT_AUTHOR_EMAIL` | The author email associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
63| `GIT_COMMITTER_NAME` | The committer name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
64| `GIT_COMMITTER_EMAIL` | The committer email associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
65
66### Options
67
68| Options | Description | Default |
69|-----------|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
70| `message` | The message for the release commit. See [message](#message). | `chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}` |
71| `assets` | Files to include in the release commit. Set to `false` to disable adding files to the release commit. See [assets](#assets). | `['CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json']` |
72
73#### `message`
74
75The message for the release commit is generated with [Lodash template](https://lodash.com/docs#template). The following variables are available:
76
77| Parameter | Description |
78|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
79| `branch` | The branch from which the release is done. |
80| `branch.name` | The branch name. |
81| `branch.type` | The [type of branch](https://github.com/semantic-release/semantic-release/blob/beta/docs/usage/workflow-configuration.md#branch-types). |
82| `branch.channel` | The distribution channel on which to publish releases from this branch. |
83| `branch.range` | The range of [semantic versions](https://semver.org) to support on this branch. |
84| `branch.prerelease` | The pre-release detonation to append to [semantic versions](https://semver.org) released from this branch. |
85| `lastRelease` | `Object` with `version`, `gitTag` and `gitHead` of the last release. |
86| `nextRelease` | `Object` with `version`, `gitTag`, `gitHead` and `notes` of the release being done. |
87
88**Note**: It is recommended to include `[skip ci]` in the commit message to not trigger a new build. Some CI service support the `[skip ci]` keyword only in the subject of the message.
89
90##### `message` examples
91
92The `message` `Release <%= nextRelease.version %> - <%= new Date().toLocaleDateString('en-US', {year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }) %> [skip ci]\n\n<%= nextRelease.notes %>` will generate the commit message:
93
94> Release v1.0.0 - Oct. 21, 2015 1:24 AM \[skip ci\]<br><br>## 1.0.0<br><br>### Features<br>* Generate 1.21 gigawatts of electricity<br>...
95
96#### `assets`
97
98Can be an `Array` or a single entry. Each entry can be either:
99- a [glob](https://github.com/micromatch/micromatch#matching-features)
100- or an `Object` with a `path` property containing a [glob](https://github.com/micromatch/micromatch#matching-features).
101
102Each entry in the `assets` `Array` is globbed individually. A [glob](https://github.com/micromatch/micromatch#matching-features) can be a `String` (`"dist/**/*.js"` or `"dist/mylib.js"`) or an `Array` of `String`s that will be globbed together (`["dist/**", "!**/*.css"]`).
103
104If a directory is configured, all the files under this directory and its children will be included.
105
106**Note**: If a file has a match in `assets` it will be included even if it also has a match in `.gitignore`.
107
108##### `assets` examples
109
110`'dist/*.js'`: include all `js` files in the `dist` directory, but not in its sub-directories.
111
112`'dist/**/*.js'`: include all `js` files in the `dist` directory and its sub-directories.
113
114`[['dist', '!**/*.css']]`: include all files in the `dist` directory and its sub-directories excluding the `css` files.
115
116`[['dist', '!**/*.css'], 'package.json']`: include `package.json` and all files in the `dist` directory and its sub-directories excluding the `css` files.
117
118`[['dist/**/*.{js,css}', '!**/*.min.*']]`: include all `js` and `css` files in the `dist` directory and its sub-directories excluding the minified version.
119
120### Examples
121
122When used with the [@semantic-release/changelog](https://github.com/semantic-release/changelog) or [@semantic-release/npm](https://github.com/semantic-release/npm) plugins:
123- The [@semantic-release/changelog](https://github.com/semantic-release/changelog) plugin must be called first in order to update the changelog file so the `@semantic-release/git` and [@semantic-release/npm](https://github.com/semantic-release/npm) plugins can include it in the release.
124- The [@semantic-release/npm](https://github.com/semantic-release/npm) plugin must be called second in order to update the `package.json` file so the `@semantic-release/git` plugin can include it in the release commit.
125
126```json
127{
128 "plugins": [
129 "@semantic-release/commit-analyzer",
130 "@semantic-release/release-notes-generator",
131 "@semantic-release/changelog",
132 "@semantic-release/npm",
133 "@semantic-release/git"
134 ],
135}
136```
137
138### GPG signature
139
140Using GPG, you can [sign and verify tags and commits](https://git-scm.com/book/id/v2/Git-Tools-Signing-Your-Work). With GPG keys, the release tags and commits made by Semantic-release are verified and other people can trust that they were really were made by your account.
141
142#### Generate the GPG keys
143
144If you already have a GPG public and private key you can skip this step and go to the [Get the GPG keys ID and the public key content](#get-the-gpg-keys-id-and-the-public-key-content) step.
145
146[Download and install the GPG command line tools](https://www.gnupg.org/download/#binary) for your operating system.
147
148Create a GPG key
149
150```bash
151$ gpg --full-generate-key
152```
153
154At the prompt select the `RSA and RSA` king of key, enter `4096` for the keysize, specify how long the key should be valid, enter yout name, the email associated with your Git hosted account and finally set a long and hard to guess passphrase.
155
156#### Get the GPG keys ID and the public key content
157
158Use the `gpg --list-secret-keys --keyid-format LONG` command to list your GPG keys. From the list, copy the GPG key ID you just created.
159
160```bash
161$ gpg --list-secret-keys --keyid-format LONG
162/Users/<user_home>/.gnupg/pubring.gpg
163---------------------------------------
164sec rsa4096/XXXXXXXXXXXXXXXX 2017-12-01 [SC]
165uid <your_name> <your_email>
166ssb rsa4096/YYYYYYYYYYYYYYYY 2017-12-01 [E]
167```
168the GPG key ID if 16 character string, on the on the `sec` line, after `rsa4096`. In this example, the GPG key ID is `XXXXXXXXXXXXXXXX`.
169
170Export the public key (replace XXXXXXXXXXXXXXXX with your key ID):
171
172```bash
173$ gpg --armor --export XXXXXXXXXXXXXXXX
174```
175
176Copy your GPG key, beginning with -----BEGIN PGP PUBLIC KEY BLOCK----- and ending with -----END PGP PUBLIC KEY BLOCK-----
177
178#### Add the GPG key to your Git hosted account
179
180##### Add the GPG key to GitHub
181
182In GitHub **Settings**, click on **SSH and GPG keys** in the sidebar, then on the **New GPG Key** button.
183
184Paste the entire GPG key export previously and click the **Add GPG Key** button.
185
186See [Adding a new GPG key to your GitHub account](https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/) for more details.
187
188### Use the GPG key to sign commit and tags locally
189
190If you want to use this GPG to also sign the commits and tags you create on your local machine you can follow the instruction at [Git Tools - Signing Your Work](https://git-scm.com/book/id/v2/Git-Tools-Signing-Your-Work)
191This step is optional and unrelated to Semantic-release.
192
193#### Add the GPG keys to your CI environment
194
195Make the public and private GPG key available on the CI environment. Encrypt the keys, commit it to your repository and configure the CI environment to decrypt it.
196
197##### Add the GPG keys to Travis CI
198
199Install the [Travis CLI](https://github.com/travis-ci/travis.rb#installation):
200
201```bash
202$ gem install travis
203```
204
205[Login](https://github.com/travis-ci/travis.rb#login) to Travis with the CLI:
206
207```bash
208$ travis login
209```
210
211Add the following [environment](https://github.com/travis-ci/travis.rb#env) variables to Travis:
212- `GPG_PASSPHRASE` to Travis with the value set during the [GPG keys generation](#generate-the-gpg-keys) step
213- `GPG_KEY_ID` to Travis with the value of your GPG key ID retrieved during the [GPG keys generation](#generate-the-gpg-keys) (replace XXXXXXXXXXXXXXXX with your key ID)
214- `GIT_EMAIL` with the email address you set during the [GPG keys generation](#generate-the-gpg-keys) step
215- `GIT_USERNAME` with the name you set during the [GPG keys generation](#generate-the-gpg-keys) step
216
217```bash
218$ travis env set GPG_PASSPHRASE <gpg_passphrase>
219$ travis env set GPG_KEY_ID XXXXXXXXXXXXXXXX
220$ travis env set GIT_EMAIL <your_email>
221$ travis env set GIT_USERNAME <your_name>
222```
223
224From your repository root export your public and private GPG keys in the `git_gpg_keys.asc` (replace XXXXXXXXXXXXXXXX with your key ID):
225
226```bash
227$ gpg --export -a XXXXXXXXXXXXXXXX > git_gpg_keys.asc
228$ gpg --export-secret-key -a XXXXXXXXXXXXXXXX >> git_gpg_keys.asc
229```
230
231[Encrypt](https://github.com/travis-ci/travis.rb#encrypt) the `git_gpg_keys.asc` (public and private key) using a symmetric encryption (AES-256), and store the secret in a secure environment variable in the Travis environment:
232
233```bash
234$ travis encrypt-file git_gpg_keys.asc
235```
236The `travis encrypt-file` will encrypt the keys into the `git_gpg_keys.asc.enc` file and output in the console the command to add to your `.travis.yml` file. It should look like `openssl aes-256-cbc -K $encrypted_AAAAAAAAAAAA_key -iv $encrypted_BBBBBBBBBBBB_iv -in git_gpg_keys.asc.enc -out git_gpg_keys.asc -d`.
237
238Copy this command to your `.travis.yml` file in the `before_install` step. Change the output path to write the unencrypted key in `/tmp`: `-out git_gpg_keys.asc` => `/tmp/git_gpg_keys.asc`. This will avoid to commit / modify / delete the unencrypted keys by mistake on the CI. Then add the commands to decrypt the GPG keys and make it available to `git`:
239
240```yaml
241before_install:
242 # Decrypt the git_gpg_keys.asc.enc key into /tmp/git_gpg_keys.asc
243 - openssl aes-256-cbc -K $encrypted_AAAAAAAAAAAA_key -iv $encrypted_BBBBBBBBBBBB_iv -in git_gpg_keys.asc.enc -out /tmp/git_gpg_keys.asc -d
244 # Make sure only the current user can read the keys
245 - chmod 600 /tmp/git_gpg_keys.asc
246 # Import the gpg key
247 - gpg --batch --yes --import /tmp/git_gpg_keys.asc
248 # Create a script that pass the passphrase to the gpg CLI called by git
249 - echo '/usr/bin/gpg2 --passphrase ${GPG_PASSPHRASE} --batch --no-tty "$@"' > /tmp/gpg-with-passphrase && chmod +x /tmp/gpg-with-passphrase
250 # Configure git to use the script that passes the passphrase
251 - git config gpg.program "/tmp/gpg-with-passphrase"
252 # Configure git to sign the commits and tags
253 - git config commit.gpgsign true
254 # Configure git to use your GPG key
255 - git config --global user.signingkey ${GPG_KEY_ID}
256```
257
258See [Encrypting Files](https://docs.travis-ci.com/user/encrypting-files/) for more details.
259
260Delete the local keys as it won't be used anymore:
261
262```bash
263$ rm git_gpg_keys.asc
264```
265
266Commit the encrypted keys and the `.travis.yml` file to your repository:
267
268```bash
269$ git add git_gpg_keys.asc.enc .travis.yml
270$ git commit -m "ci(travis): Add the encrypted GPG keys"
271$ git push
272```