Skip to content

Commit 8222ed9

Browse files
committed
Docs: Update and refactor release workflow recipe
- infer version bump from commits - make release commit message adhere to Conventional Commits - read GitHub personal access token from git-ignored `.env` file - functions instead of `gulp.task` - eliminate usage of gulp plugins - improve readability with `execa` and `pify`
1 parent b7b70b8 commit 8222ed9

File tree

1 file changed

+87
-72
lines changed

1 file changed

+87
-72
lines changed
Lines changed: 87 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,94 @@
11
# Automate release workflow
22

33
If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release.
4-
Below you have a simple recipe that bumps the project version, commits the changes to git and creates a new tag.
5-
6-
``` javascript
7-
8-
var gulp = require('gulp');
9-
var conventionalChangelog = require('gulp-conventional-changelog');
10-
var conventionalGithubReleaser = require('conventional-github-releaser');
11-
var bump = require('gulp-bump');
12-
var log = require('gulplog');
13-
var git = require('gulp-git');
14-
var fs = require('fs');
15-
16-
gulp.task('changelog', function () {
17-
return gulp.src('CHANGELOG.md', {
18-
buffer: false
19-
})
20-
.pipe(conventionalChangelog({
21-
preset: 'angular' // Or to any other commit message convention you use.
22-
}))
23-
.pipe(gulp.dest('./'));
24-
});
25-
26-
gulp.task('github-release', function(done) {
27-
conventionalGithubReleaser({
28-
type: "oauth",
29-
token: 'abcdefghijklmnopqrstuvwxyz1234567890' // change this to your own GitHub token or use an environment variable
30-
}, {
31-
preset: 'angular' // Or to any other commit message convention you use.
32-
}, done);
33-
});
34-
35-
gulp.task('bump-version', function () {
36-
// We hardcode the version change type to 'patch' but it may be a good idea to
37-
// use minimist (https://www.npmjs.com/package/minimist) to determine with a
38-
// command argument whether you are doing a 'major', 'minor' or a 'patch' change.
39-
return gulp.src(['./bower.json', './package.json'])
40-
.pipe(bump({type: "patch"}).on('error', log.error))
41-
.pipe(gulp.dest('./'));
42-
});
43-
44-
gulp.task('commit-changes', function () {
45-
return gulp.src('.')
46-
.pipe(git.add())
47-
.pipe(git.commit('[Prerelease] Bumped version number'));
48-
});
49-
50-
gulp.task('push-changes', function (done) {
51-
git.push('origin', 'master', done);
52-
});
53-
54-
gulp.task('create-new-tag', function (done) {
55-
var version = getPackageJsonVersion();
56-
git.tag(version, 'Created Tag for version: ' + version, function (error) {
57-
if (error) {
58-
return done(error);
59-
}
60-
git.push('origin', 'master', {args: '--tags'}, done);
4+
The recipe below bumps the project version, commits the changes to git and creates a new GitHub release.
5+
6+
For publishing a GitHub release you'll need to [create a personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) and add it to your project. However, we don't want to commit it, so we'll use [`dotenv-safe`](https://www.npmjs.com/package/dotenv-safe) to load it from a git-ignored `.env` file.
7+
8+
Create an `.env.example` file to define required environment variables:
9+
10+
```
11+
GH_TOKEN=
12+
```
13+
14+
We'll commit this, so leave it empty. Next, duplicate this file, rename it to `.env` and add your GitHub token:
15+
16+
```
17+
GH_TOKEN=ff34885...
18+
```
19+
20+
Finally, add `.env` to your `.gitignore`.
21+
22+
Moving on, install all the necessary dependencies for this recipe:
23+
24+
```sh
25+
npm install --save-dev conventional-recommended-bump conventional-changelog-cli conventional-github-releaser dotenv-safe execa pify
26+
```
27+
28+
Finally, `gulpfile.js`:
29+
30+
``` js
31+
const gulp = require('gulp');
32+
const conventionalRecommendedBump = require('conventional-recommended-bump');
33+
const conventionalGithubReleaser = require('conventional-github-releaser');
34+
const execa = require('execa');
35+
const fs = require('fs/promises');
36+
const pify = require('pify');
37+
const dotenv = require('dotenv-safe');
38+
39+
// load environment variables
40+
dotenv.config();
41+
42+
// Conventional Changelog preset
43+
const preset = 'angular';
44+
// print output of commands into the terminal
45+
const stdio = 'inherit';
46+
47+
async function bumpVersion() {
48+
// get recommended version bump based on commits
49+
const { releaseType } = await pify(conventionalRecommendedBump)({ preset });
50+
// bump version without committing and tagging
51+
await execa('npm', ['version', releaseType, '--no-git-tag-version'], {
52+
stdio,
6153
});
54+
}
55+
56+
async function changelog() {
57+
await execa(
58+
'npx',
59+
[
60+
'conventional-changelog',
61+
'--preset',
62+
preset,
63+
'--infile',
64+
'CHANGELOG.md',
65+
'--same-file',
66+
],
67+
{ stdio }
68+
);
69+
}
70+
71+
async function commitTagPush() {
72+
const { version } = JSON.parse(await fs.readFile('package.json'));
73+
const commitMsg = `chore: release ${version}`;
74+
await execa('git', ['add', '.'], { stdio });
75+
await execa('git', ['commit', '--message', commitMsg], { stdio });
76+
await execa('git', ['tag', `v${version}`], { stdio });
77+
await execa('git', ['push', '--follow-tags'], { stdio });
78+
}
6279

63-
function getPackageJsonVersion () {
64-
// We parse the json file instead of using require because require caches
65-
// multiple calls so the version number won't be updated
66-
return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
67-
};
68-
});
69-
70-
gulp.task('release', gulp.series(
71-
'bump-version',
72-
'changelog',
73-
'commit-changes',
74-
'push-changes',
75-
'create-new-tag',
76-
'github-release'
77-
));
80+
function githubRelease(done) {
81+
conventionalGithubReleaser(
82+
{ type: 'oauth', token: process.env.GH_TOKEN },
83+
{ preset },
84+
done
85+
);
86+
}
7887

88+
exports.release = gulp.series(
89+
bumpVersion,
90+
changelog,
91+
commitTagPush,
92+
githubRelease
93+
);
7994
```

0 commit comments

Comments
 (0)