semantic-release-gitmoji
semantic-release-gitmoji copied to clipboard
[feature request] generate changelog
It'd be nice to generate changelog as well along with release notes
kinda like https://github.com/semantic-release/changelog
kinda like https://github.com/semantic-release/changelog
That is actually where changelog should be generated, no matter what commit message conventions you are following.
Have you ever try using @semantic-release/changelog
along with semantic-release-gitmoji
?
i.e.
{
"plugins": [
"semantic-release-gitmoji",
"@semantic-release/changelog"
]
}
FYI,
There are steps that semantic release will perform in the release pipeline. https://github.com/semantic-release/semantic-release#release-steps
Especially Generate notes and Prepare are steps that semantic-release-gitmoji
and @semantic-release/changelog
are applied respectively.
The responsibility of semantic-release-gitmoji
is to generate notes from gitmoji commits for the whole semantic release system in Generate notes step. After the step other plugins can further make use of the generated notes. For example, @semantic-release/github
publishes the release notes to github releases in Publish step.
I tried it with @semantic-release/changelog
.
All I got was the header with the version 1.0.0. nothing after that.
# v1.0.0 (2020-08-14)
NOTE: i created the commits using commitizen and cz-emoji
some of the commits I have are
:rotating_light: (app) Remove import <StatusBar /> component
:fire: (app) Remove <StatusBar /> component from being used
:pencil: (readme) add codecov markdown badge
:see_no_evil: (test-results) ignore test-results/ folder
:heavy_plus_sign: (npm) add enzyme npm package
:heavy_plus_sign: (npm) add enzyme-to-json npm package
:wrench: (jest) temporarily disable setupFiles properties
:heavy_plus_sign: (npm) add ts-jest npm package
:heavy_plus_sign: (npm) add jest-junit npm package
:heavy_plus_sign: (npm) add jest-html-reporters npm package
:wrench: (jest) Add jest config file
:pencil: (readme) Add androidBuild github-action markdown badge
:art: (github-action) Add new lines to make androidBuild more readable
Here's my config.
.releaserc.js
const { promisify } = require('util');
const dateFormat = require('dateformat');
const readFileAsync = promisify(require('fs').readFile);
const path = require('path');
const commitRules = require('./semantic-release/commitRules.js');
const TEMPLATE_DIR = 'node_modules/semantic-release-gitmoji/lib/assets/templates/';
const template = readFileAsync(path.join(TEMPLATE_DIR, 'default-template.hbs'));
const commitTemplate = readFileAsync(path.join(TEMPLATE_DIR, 'commit-template.hbs'));
const MAJOR = 'major';
const MINOR = 'minor';
const PATCH = 'patch';
module.exports = {
branches: ['master'],
plugins: [
[
'semantic-release-gitmoji',
{
releaseRules: {
major: commitRules.filter(({ release }) => release === MAJOR).map(({ emoji }) => emoji),
minor: commitRules.filter(({ release }) => release === MINOR).map(({ emoji }) => emoji),
patch: commitRules.filter(({ release }) => release === PATCH).map(({ emoji }) => emoji),
},
releaseNotes: {
template,
partials: { commitTemplate },
helpers: {
datetime: function (format = 'UTC:yyyy-mm-dd') {
return dateFormat(new Date(), format);
},
},
issueResolution: {
template: '{baseUrl}/{owner}/{repo}/issues/{ref}',
baseUrl: 'https://github.com',
source: 'github.com',
},
},
},
],
'@semantic-release/changelog',
'@semantic-release/github',
[
'@semantic-release/git',
{
assets: ['CHANGELOG.md'],
},
],
],
tagFormat: '${version}',
};
.semantic-release/commitRules.js
const MAJOR = 'major';
const MINOR = 'minor';
const PATCH = 'patch';
module.exports = [
{ breaking: true, release: MAJOR },
{ revert: true, release: PATCH },
{
// type: 'style',
emoji: ':art:',
// description: 'Improving structure / format of the code.',
release: PATCH,
},
{
// type: 'perf',
emoji: ':zap:',
// description: 'Improving performance.',
release: PATCH,
},
{
// type: 'prune',
emoji: ':fire:',
// description: 'Removing code or files.',
release: PATCH,
},
{
// type: 'fix',
emoji: ':bug:',
// description: 'Fixing a bug.',
release: PATCH,
},
{
// type: 'quickfix',
emoji: ':ambulance:',
// description: 'Critical hotfix.',
release: MINOR,
},
{
// type: 'feature',
emoji: ':sparkles:',
// description: 'Introducing new features.',
release: MINOR,
},
{
// type: 'docs',
emoji: ':pencil:',
// description: 'Writing docs.',
release: false,
},
{
// type: 'deploy',
emoji: ':rocket:',
// description: 'Deploying stuff.',
release: PATCH,
},
{
// type: 'ui',
emoji: ':lipstick:',
// description: 'Updating the UI and style files.',
release: PATCH,
},
{
// type: 'init',
emoji: ':tada:',
// description: 'Initial commit.',
release: PATCH,
},
{
// type: 'test',
emoji: ':white_check_mark:',
// description: 'Adding tests.',
release: false,
},
{
// type: 'security',
emoji: ':lock:',
// description: 'Fixing security issues.',
release: MINOR,
},
{
// type: 'osx',
emoji: ':apple:',
// description: 'Fixing something on macOS.',
release: PATCH,
},
{
// type: 'linux',
emoji: ':penguin:',
// description: 'Fixing something on Linux.',
release: PATCH,
},
{
// type: 'windows',
emoji: ':checkered_flag:',
// description: 'Fixing something on Windows.',
release: PATCH,
},
{
// type: 'android',
emoji: ':robot:',
// description: 'Fixing something on Android.',
release: PATCH,
},
{
// type: 'ios',
emoji: ':green_apple:',
// description: 'Fixing something on iOS.',
release: PATCH,
},
{
// type: 'release',
emoji: ':bookmark:',
// description: 'Releasing / Version tags.',
release: PATCH,
},
{
// type: 'lint',
emoji: ':rotating_light:',
// description: 'Removing linter warnings.',
release: PATCH,
},
{
// type: 'wip',
emoji: ':construction:',
// description: 'Work in progress.',
release: false, // don't create a release
},
{
// type: 'fix-ci',
emoji: ':green_heart:',
// description: 'Fixing CI Build.',
release: PATCH,
},
{
// type: 'downgrade',
emoji: ':arrow_down:',
// description: ' Downgrading dependencies.',
release: PATCH,
},
{
// type: 'upgrade',
emoji: ':arrow_up:',
// description: ' Upgrading dependencies.',
release: PATCH,
},
{
// type: 'pushpin',
emoji: ':pushpin:',
// description: 'Pinning dependencies to specific versions.',
release: false,
},
{
// type: 'ci',
emoji: ':construction_worker:',
// description: 'Adding CI build system.',
release: PATCH,
},
{
// type: 'analytics',
emoji: ':chart_with_upwards_trend:',
// description: 'Adding analytics or tracking code.',
release: PATCH,
},
{
// type: 'refactoring',
emoji: ':recycle:',
// description: ' Refactoring code.',
release: MINOR,
},
{
// type: 'docker',
emoji: ':whale:',
// description: 'Work about Docker.',
release: PATCH,
},
{
// type: 'dep-add',
emoji: ':heavy_plus_sign:',
// description: 'Adding a dependency.',
release: PATCH,
},
{
// type: 'dep-rm',
emoji: ':heavy_minus_sign:',
// description: 'Removing a dependency.',
release: PATCH,
},
{
// type: 'config',
emoji: ':wrench:',
// description: 'Changing configuration files.',
release: PATCH,
},
{
// type: 'i18n',
emoji: ':globe_with_meridians:',
// description: 'Internationalization and localization.',
release: PATCH,
},
{
// type: 'typo',
emoji: ':pencil2:',
// description: ' Fixing typos.',
release: PATCH,
},
{
// type: 'poo',
emoji: ':poop:',
// description: 'Writing bad code that needs to be improved.',
release: PATCH,
},
{
// type: 'revert',
emoji: ':rewind:',
// description: 'Reverting changes.',
release: PATCH,
},
{
// type: 'merge',
emoji: ':twisted_rightwards_arrows:',
// description: 'Merging branches.',
release: PATCH,
},
{
// type: 'dep-up',
emoji: ':package:',
// description: 'Updating compiled files or packages.',
release: PATCH,
},
{
// type: 'compat',
emoji: ':alien:',
// description: 'Updating code due to external API changes.',
release: PATCH,
},
{
// type: 'mv',
emoji: ':truck:',
// description: 'Moving or renaming files.',
release: PATCH,
},
{
// type: 'license',
emoji: ':page_facing_up:',
// description: 'Adding or updating license.',
release: false,
},
{
// type: 'breaking',
emoji: ':boom:',
// description: 'Introducing breaking changes.',
release: MAJOR,
},
{
// type: 'assets',
emoji: ':bento:',
// description: 'Adding or updating assets.',
release: PATCH,
},
{
// type: 'review',
emoji: ':ok_hand:',
// description: 'Updating code due to code review changes.',
release: PATCH,
},
{
// type: 'access',
emoji: ':wheelchair:',
// description: 'Improving accessibility.',
release: PATCH,
},
{
// type: 'docs-code',
emoji: ':bulb:',
// description: 'Documenting source code.',
release: PATCH,
},
{
// type: 'beer',
emoji: ':beers:',
// description: 'Writing code drunkenly.',
release: PATCH,
},
{
// type: 'texts',
emoji: ':speech_balloon:',
// description: 'Updating text and literals.',
release: PATCH,
},
{
// type: 'db',
emoji: ':card_file_box:',
// description: ' Performing database related changes.',
release: PATCH,
},
{
// type: 'log-add',
emoji: ':loud_sound:',
// description: 'Adding logs.',
release: false,
},
{
// type: 'log-rm',
emoji: ':mute:',
// description: 'Removing logs.',
release: false,
},
{
// type: 'contrib-add',
emoji: ':busts_in_silhouette:',
// description: 'Adding contributor(s).',
release: false,
},
{
// type: 'ux',
emoji: ':children_crossing:',
// description: 'Improving user experience / usability.',
release: PATCH,
},
{
// type: 'arch',
emoji: ':building_construction:',
// description: ' Making architectural changes.',
release: PATCH,
},
{
// type: 'iphone',
emoji: ':iphone:',
// description: 'Working on responsive design.',
release: PATCH,
},
{
// type: 'clown-face',
emoji: ':clown_face:',
// description: 'Mocking things.',
release: false,
},
{
// type: 'egg',
emoji: ':egg:',
// description: 'Adding an easter egg.',
release: PATCH,
},
{
// type: 'see-no-evil',
emoji: ':see_no_evil:',
// description: 'Adding or updating a .gitignore file',
release: false,
},
{
// type: 'camera-flash',
emoji: ':camera_flash:',
// description: 'Adding or updating snapshots',
release: false,
},
{
// type: 'experiment',
emoji: ':alembic:',
// description: ' Experimenting new things',
release: false,
},
{
// type: 'seo',
emoji: ':mag:',
// description: 'Improving SEO',
release: PATCH,
},
{
// type: 'k8s',
emoji: ':wheel_of_dharma:',
// description: ' Work about Kubernetes',
release: PATCH,
},
{
// type: 'types',
emoji: ':label:',
// description: ' Adding or updating types (Flow, TypeScript)',
release: PATCH,
},
{
// type: 'seed',
emoji: ':seedling:',
// description: 'Adding or updating seed files',
release: PATCH,
},
{
// type: 'flags',
emoji: ':triangular_flag_on_post:',
// description: 'Adding, updating, or removing feature flags',
release: PATCH,
},
{
// type: 'animation',
emoji: ':dizzy:',
// description: 'Adding or updating animations and transitions',
release: PATCH,
},
];
Sorry for late response. I will have a try to reproduce by this weekend.
@Clumsy-Coder Hi, I might get the issue for your configuration.
Please take a look at the default template first.
https://github.com/momocow/semantic-release-gitmoji/blob/b5f20fd1e4a77d44f2af944c1c2a1a6f73228c79/lib/assets/templates/default-template.hbs#L8-L41
The template only renders a set of predefined gitmoji commits, i.e. commits whose emojis are one of :sparkles:
, :bug:
, :ambulance:
, :lock:
and :boom:
.
You can try to provide your own template with all your gitmojis.
In the default template gitmojis are explicitly rendered through #with
due to the limitation of handlebars which cannot iterate over objects and the plugin has no knowledge about the shape of the commits
object. (Keys of the object are emoji names that appears in related commits)
To do dynamic commit rendering with the default template, the commits
object requires refactor for handlebars to iterate it easily.
This may be included in the future improvement but in the current version you need a custom template to make your configuration work.
I see, so for now you have to provide your own template file. Which is basically copy paste for each gitmoji used with their own Titles.
I'd be great to have this done automatically in the future.
I'd be great to have this done automatically in the future.
I'll keep this issue open until the feature comes out.
Hey @momocow,
A PR that introduces semver
attributes to gitmojis has been merged: https://github.com/carloscuesta/gitmoji/pull/692
That will help with setting default releaseRules
.
I'll be glad to open a PR, just want to check with you first.
And what do you think of grouping the commits in the template by their semantic level (major
, minor
, patch
) instead of grouping them by emojis.
The final template can look like this:
{{#if compareUrl}}
# [v{{nextRelease.version}}]({{compareUrl}}) ({{datetime "UTC:yyyy-mm-dd"}})
{{else}}
# v{{nextRelease.version}} ({{datetime "UTC:yyyy-mm-dd"}})
{{/if}}
{{#with commits}}
{{#if major}}
### 💥 Breaking Changes
{{#each major}}
- {{> commitTemplate}}
{{/each}}
{{/if}}
{{#if minor}}
### ✨ New Features
{{#each minor}}
- {{> commitTemplate}}
{{/each}}
{{/if}}
{{#if patch}}
### Others
{{#each patch}}
- {{gitmoji}} {{> commitTemplate}}
{{/each}}
{{/if}}
{{/with}}
@ilyasmez It looks awesome, which really simplifies the complexity of release notes templates!
PRs are welcome ;)
As a gitmoji fan, I'd also love to see this PR-ed and merged 🚀
Happy to help testing 🤗
Hey their,
I managed to find a workaround for this issues. If you prefer to group commit by their rules and use of mention Gitmojis Semver https://github.com/carloscuesta/gitmoji/pull/692, you could do as follow.
You will need to setup rules in an object to be able to use them in an handblerbars helpers which will reorganise commits by type of release instead of gitmoji, as shown below:
// in ".releaserc.js" or "release.config.js"
const {promisify} = require("util");
const dateFormat = require("dateformat");
const readFileAsync = promisify(require("fs").readFile);
const path = require("path");
// Use of Gitmojis to create rules
const gitmojis = require("gitmojis").gitmojis;
const TEMPLATE_DIR = "./.semantic-release/templates/";
const template = readFileAsync(path.join(TEMPLATE_DIR, "default-template.hbs"));
const commitTemplate = readFileAsync(path.join(TEMPLATE_DIR, "commit-template.hbs"));
const MAJOR = "major";
const MINOR = "minor";
const PATCH = "patch";
// Store rules based on Gitmoji semver key in a object for later
const RULES = {
major: gitmojis
.filter(({semver}) => semver === MAJOR)
.map(({emoji}) => emoji),
minor: gitmojis
.filter(({semver}) => semver === MINOR)
.map(({emoji}) => emoji),
patch: gitmojis
.filter(({semver}) => semver === PATCH)
.map(({emoji}) => emoji),
// Not needed, just if you wish to render commit
// with gitmojis without semver.
others: gitmojis
.filter(({semver}) => semver === null)
.map(({emoji}) => emoji),
};
module.exports = {
branches: ["main"],
plugins: [
[
"semantic-release-gitmoji",
{
releaseRules: RULES,
releaseNotes: {
template,
partials: {commitTemplate},
helpers: {
datetime: function (format = "UTC:yyyy-mm-dd") {
return dateFormat(new Date(), format);
},
// Handlebars helper to reorganise commits, not optimal though
commitlist: function (commits, options) {
let commitlist = {};
let currRule = "not_defined";
const rules = RULES;
for (const iGitmoji in commits) {
currRule = "not_defined";
for (const iRule in rules) {
if (rules[iRule].includes(iGitmoji)) {
if (
!Object.prototype.hasOwnProperty.call(commitlist, iRule)
) {
commitlist[iRule] = [];
}
currRule = iRule;
break;
}
}
if (
currRule == "not_defined" &&
!Object.prototype.hasOwnProperty.call(commitlist, currRule)
) {
commitlist[currRule] = [];
}
for (
let idxCommit = 0;
idxCommit < commits[iGitmoji].length;
idxCommit++
) {
commitlist[currRule].push(commits[iGitmoji][idxCommit]);
}
}
options.data.root["commits"] = commitlist;
},
},
issueResolution: {
template: "{baseUrl}/{owner}/{repo}/issues/{ref}",
baseUrl: "https://github.com",
},
},
},
],
// Generate changelog
[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
changelogTitle: "# CHANGELOG",
},
],
// Commit changelog
[
"@semantic-release/git",
{
assets: ["CHANGELOG.md"],
message: "🔖 ${nextRelease.version} [skip-ci]\n\n${nextRelease.notes}",
},
],
],
tagFormat: "${version}",
};
Them, you will just need to provide a custom handlebars template such as the example below:
{{#if compareUrl}}
## [v{{nextRelease.version}}]({{compareUrl}}) ({{datetime "UTC:yyyy-mm-dd"}})
{{else}}
## v{{nextRelease.version}} ({{datetime "UTC:yyyy-mm-dd"}})
{{/if}}
{{commitlist commits}}
{{#with commits}}
{{#if major}}
### Major
{{#each major}}
* {{> commitTemplate}}
{{/each}}
{{/if}}
{{#if minor}}
### Minor
{{#each minor}}
* {{> commitTemplate}}
{{/each}}
{{/if}}
{{#if patch}}
### Patch
{{#each patch}}
* {{> commitTemplate}}
{{/each}}
{{/if}}
{{/with}}