UNPKG

15.8 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[![Travis](https://img.shields.io/travis/semantic-release/git.svg)](https://travis-ci.org/semantic-release/git)
6[![Codecov](https://img.shields.io/codecov/c/github/semantic-release/git.svg)](https://codecov.io/gh/semantic-release/git)
7[![Greenkeeper badge](https://badges.greenkeeper.io/semantic-release/git.svg)](https://greenkeeper.io/)
8
9[![npm latest version](https://img.shields.io/npm/v/@semantic-release/git/latest.svg)](https://www.npmjs.com/package/@semantic-release/git)
10[![npm next version](https://img.shields.io/npm/v/@semantic-release/git/next.svg)](https://www.npmjs.com/package/@semantic-release/git)
11
12| Step | Description |
13|--------------------|------------------------------------------------------------------------------------------------------------------------------------|
14| `verifyConditions` | Verify the access to the remote Git repository, the commit [`message`](#message) and the [`assets`](#assets) option configuration. |
15| `prepare` | Create a release commit, including configurable file assets. |
16
17## Install
18
19```bash
20$ npm install @semantic-release/git -D
21```
22
23## Usage
24
25The plugin can be configured in the [**semantic-release** configuration file](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration):
26
27```json
28{
29 "plugins": [
30 "@semantic-release/commit-analyzer",
31 "@semantic-release/release-notes-generator",
32 ["@semantic-release/git", {
33 "assets": ["dist/**/*.{js,css}", "docs", "package.json"],
34 "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
35 }]
36 ]
37}
38```
39
40With this example, for each release a release commit will be pushed to the remote Git repository with:
41- a message formatted like `chore(release): <version> [skip ci]\n\n<release notes>`
42- the `.js` and `.css` files in the `dist` directory, the files in the `docs` directory and the `package.json`
43
44## Configuration
45
46### Git authentication
47
48The 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).
49
50When 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).
51
52### Environment variables
53
54| Variable | Description | Default |
55|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
56| `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. |
57| `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. |
58| `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. |
59| `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. |
60
61### Options
62
63| Options | Description | Default |
64|-----------|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
65| `message` | The message for the release commit. See [message](#message). | `chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}` |
66| `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']` |
67
68#### `message`
69
70The message for the release commit is generated with [Lodash template](https://lodash.com/docs#template). The following variables are available:
71
72| Parameter | Description |
73|---------------|-------------------------------------------------------------------------------------|
74| `branch` | The branch from which the release is done. |
75| `lastRelease` | `Object` with `version`, `gitTag` and `gitHead` of the last release. |
76| `nextRelease` | `Object` with `version`, `gitTag`, `gitHead` and `notes` of the release being done. |
77
78**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.
79
80##### `message` examples
81
82The `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:
83
84> 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>...
85
86#### `assets`
87
88Can be an `Array` or a single entry. Each entry can be either:
89- a [glob](https://github.com/micromatch/micromatch#matching-features)
90- or an `Object` with a `path` property containing a [glob](https://github.com/micromatch/micromatch#matching-features).
91
92Each 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"]`).
93
94If a directory is configured, all the files under this directory and its children will be included.
95
96**Note**: If a file has a match in `assets` it will be included even if it also has a match in `.gitignore`.
97
98##### `assets` examples
99
100`'dist/*.js'`: include all `js` files in the `dist` directory, but not in its sub-directories.
101
102`'dist/**/*.js'`: include all `js` files in the `dist` directory and its sub-directories.
103
104`[['dist', '!**/*.css']]`: include all files in the `dist` directory and its sub-directories excluding the `css` files.
105
106`[['dist', '!**/*.css'], 'package.json']`: include `package.json` and all files in the `dist` directory and its sub-directories excluding the `css` files.
107
108`[['dist/**/*.{js,css}', '!**/*.min.*']]`: include all `js` and `css` files in the `dist` directory and its sub-directories excluding the minified version.
109
110### Examples
111
112When used with the [@semantic-release/changelog](https://github.com/semantic-release/changelog) or [@semantic-release/npm](https://github.com/semantic-release/npm) plugins:
113- 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.
114- 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.
115
116```json
117{
118 "plugins": [
119 "@semantic-release/commit-analyzer",
120 "@semantic-release/release-notes-generator",
121 "@semantic-release/changelog",
122 "@semantic-release/npm",
123 "@semantic-release/git"
124 ],
125}
126```
127
128### GPG signature
129
130Using 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.
131
132#### Generate the GPG keys
133
134If 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.
135
136[Download and install the GPG command line tools](https://www.gnupg.org/download/#binary) for your operating system.
137
138Create a GPG key
139
140```bash
141$ gpg --full-generate-key
142```
143
144At 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.
145
146#### Get the GPG keys ID and the public key content
147
148Use 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.
149
150```bash
151$ gpg --list-secret-keys --keyid-format LONG
152/Users/<user_home>/.gnupg/pubring.gpg
153---------------------------------------
154sec rsa4096/XXXXXXXXXXXXXXXX 2017-12-01 [SC]
155uid <your_name> <your_email>
156ssb rsa4096/YYYYYYYYYYYYYYYY 2017-12-01 [E]
157```
158the GPG key ID if 16 character string, on the on the `sec` line, after `rsa4096`. In this example, the GPG key ID is `XXXXXXXXXXXXXXXX`.
159
160Export the public key (replace XXXXXXXXXXXXXXXX with your key ID):
161
162```bash
163$ gpg --armor --export XXXXXXXXXXXXXXXX
164```
165
166Copy your GPG key, beginning with -----BEGIN PGP PUBLIC KEY BLOCK----- and ending with -----END PGP PUBLIC KEY BLOCK-----
167
168#### Add the GPG key to your Git hosted account
169
170##### Add the GPG key to GitHub
171
172In GitHub **Settings**, click on **SSH and GPG keys** in the sidebar, then on the **New GPG Key** button.
173
174Paste the entire GPG key export previously and click the **Add GPG Key** button.
175
176See [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.
177
178### Use the GPG key to sign commit and tags locally
179
180If 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)
181This step is optional and unrelated to Semantic-release.
182
183#### Add the GPG keys to your CI environment
184
185Make 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.
186
187##### Add the GPG keys to Travis CI
188
189Install the [Travis CLI](https://github.com/travis-ci/travis.rb#installation):
190
191```bash
192$ gem install travis
193```
194
195[Login](https://github.com/travis-ci/travis.rb#login) to Travis with the CLI:
196
197```bash
198$ travis login
199```
200
201Add the following [environment](https://github.com/travis-ci/travis.rb#env) variables to Travis:
202- `GPG_PASSPHRASE` to Travis with the value set during the [GPG keys generation](#generate-the-gpg-keys) step
203- `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)
204- `GIT_EMAIL` with the email address you set during the [GPG keys generation](#generate-the-gpg-keys) step
205- `GIT_USERNAME` with the name you set during the [GPG keys generation](#generate-the-gpg-keys) step
206
207```bash
208$ travis env set GPG_PASSPHRASE <gpg_passphrase>
209$ travis env set GPG_KEY_ID XXXXXXXXXXXXXXXX
210$ travis env set GIT_EMAIL <your_email>
211$ travis env set GIT_USERNAME <your_name>
212```
213
214From your repository root export your public and private GPG keys in the `git_gpg_keys.asc` (replace XXXXXXXXXXXXXXXX with your key ID):
215
216```bash
217$ gpg --export -a XXXXXXXXXXXXXXXX > git_gpg_keys.asc
218$ gpg --export-secret-key -a XXXXXXXXXXXXXXXX >> git_gpg_keys.asc
219```
220
221[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:
222
223```bash
224$ travis encrypt-file git_gpg_keys.asc
225```
226The `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`.
227
228Copy 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`:
229
230```yaml
231before_install:
232 # Decrypt the git_gpg_keys.asc.enc key into /tmp/git_gpg_keys.asc
233 - 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
234 # Make sure only the current user can read the keys
235 - chmod 600 /tmp/git_gpg_keys.asc
236 # Import the gpg key
237 - gpg --batch --yes --import /tmp/git_gpg_keys.asc
238 # Create a script that pass the passphrase to the gpg CLI called by git
239 - echo '/usr/bin/gpg2 --passphrase ${GPG_PASSPHRASE} --batch --no-tty "$@"' > /tmp/gpg-with-passphrase && chmod +x /tmp/gpg-with-passphrase
240 # Configure git to use the script that passes the passphrase
241 - git config gpg.program "/tmp/gpg-with-passphrase"
242 # Configure git to sign the commits and tags
243 - git config commit.gpgsign true
244 # Configure git to use your GPG key
245 - git config --global user.signingkey ${GPG_KEY_ID}
246```
247
248See [Encrypting Files](https://docs.travis-ci.com/user/encrypting-files/) for more details.
249
250Delete the local keys as it won't be used anymore:
251
252```bash
253$ rm git_gpg_keys.asc
254```
255
256Commit the encrypted keys and the `.travis.yml` file to your repository:
257
258```bash
259$ git add git_gpg_keys.asc.enc .travis.yml
260$ git commit -m "ci(travis): Add the encrypted GPG keys"
261$ git push
262```