I would like to see a doc (ideally part of website, but maybe just something checked into the repo) that lays out how various emojis should map to conventional-commits.
There are many tools today that can parse conventional commits. I often would like to propose to authors of these tools to support conventional commits _or_ gitmoji, but how to do so is pretty wishy-washy (compared to the very formal definition of conventional-commits).
For example, I'd probably suggest ":boom: Drop node v8 support" be parsed equivalently to "feat!: Drop node v8 support", ":sparkles: Add a new button" be parsed equivalently to "feat: Add a new button", ":bug: Fix something" be parsed as "fix: Fix something", and then everything else just also gets "fix:".
(This isn't ideal, because there are a lot of obvious mappings, like ":pencil: Add a new paragraph" is clearly intended to be "doc: Add a new paragraph". If we mapped out that relationship, it would be easier to propose support to tool authors.)
I've seen this, but I don't like it. A good example is the https://github.com/vivaxy/gacp project, which creates commit messages that follow conventional-commits standard _and_ contain gitmoji emojis.
I have two issues with this:
1) It's double-accounting. Commits like feat: :sparkles: add a feature and BREAKING CHANGE: :boom: make a change are just saying the exact same thing twice in different ways, defeating the whole purpose of using the emojis.
2) It looks really bad. If the emoji can't be the very first character, it ruins the effect of an all-gitmoji repo (where the commits are lined up and easily parseable). _If_ combining gitmoji and conventional-commits resulted in :sparkles: feat: add a feature, I guess that would be better, but look at the gacp project link above to see how hard it is to even find the emoji when it is not lined up in the commit message.
Maybe. I find it very doubtful, but could conventional-commit make a change to their rules that says:
You can _prefix_ any
<type>with a phrase surrounded by colons.
This would let :boom: feat!: Big API change be a valid conventional-commit message, and fixes my Complaint (2). But it's still double-accounting.
For this reason, I think that even _if_ conventional-commits would be willing to bend to accomodate prefixed emojis, it's not the best case. The best case would be to craft a formalized way to interpret gitmoji, so that asking a tool author to support gitmoji is just like asking a tool to output YAML as well as JSON, etc.
Any thoughts? Pros/cons?
I thought I'd add some similar projects, for people looking:
This project combines gitmojis into conventional-commits in the form e.g. "perf(:zap:)". This looks OK but, in my opinion, still has problems (1) and (2) above.
This project abandons conventional-commits altogether and proposes a way to accomplish the same goal (semantic versioning & releases) using gitmojis. This is similar to what I'm proposing, except I'd like to make the relationship between the two more clear.
An ideal solution to the above might be a _separate project_ called gitmoji-to-conventional-commit, that is an NPM package that takes any gitmoji commit as input and spits out a conventional commit as output.
This "mapping" project isn't something you'd use on your own, but if it existed, it makes it trivial for all authors of existing tools that parse conventional-commits to add gitmoji support!
// Somewhere in the middle of a tool's commit message parsing
const gitmoji = require('gitmoji-to-conventional-commit')
return gitmoji.isGitmoji(message) ? gitmoji.asConventional(message) : message
I personally don't like conventional commit because it doesn't have the granularity I like when using gitmoji, but having the tools from conventional-commit is a great thing to have, and if we mantain in this repo a, let's say, json file it would be great.
maybe we can add one more key to the main gitmoji file:
{
"emoji": "๐จ",
"entity": "🎨",
"code": ":art:",
+ "conventional-commit": "style",
"description": "Improving structure / format of the code.",
"name": "art"
},
What about simply specifying how the version will be bumped?
{
"emoji": "๐",
"entity": "🐛",
"code": ":bug:",
+ "bump": "patch",
"description": "Fixing a bug.",
"name": "bug"
},
Really interesting! I was originally wrestling with "how do I convert a gitmoji message into a conventional message", as I think that provides a bolt-on you could use with various packages out there designed to turn conventional commits into things - changelogs, releases, etc.
Defining bump level per emoji tackles it at a slightly higher level but it solves the "feat!" problem from conventional - if you just take the highest bump level from all emojis in a string, then it allows you to handle a gitmoji message like ":wrench: :boom:" (a configuration change that requires a major version).
FWIW I still think a "mapping of emojis to conventional" is useful but might not be the responsibility of this repo, whereas defining a bump level per emoji seems like a natural fit.
I think that gitmoji and conventional-commits are different aproaches and you should pick one convention to stick to.
Why we should establish a relationship between the two ? There are a lot of other conventions out there, why specifically with conventional ? ๐ค
thats a good point, nonetheless, I think it would be good to have the bump property
I think that
gitmojiandconventional-commitsare different aproaches and you should pick one convention to stick to.Why we should establish a relationship between the two ? There are a lot of other conventions out there, why specifically with conventional ? ๐ค
My specific use case is that there's a couple libraries out there that currently make use of conventional commits, and I'd like to use them with gitmojis. The maintainers seems totally open to also supporting gitmojis, but when asked for details on exactly what the behavior should be I'm drawing a blank beyond "I guess sparkles is a minor bump and boom is a major bump".
(An example of what I'm talking about is https://github.com/mikeal/merge-release/issues/20 - ready to put up a PR, but haven't decided exactly what to propose.)
@elliot-nelson That'd be solved with my suggestion (add info on how each emoji should bump the version), right? If I understand it right, conventional commits would just be an intermediate step that would add more complexity than needed.
Absolutely - just deciding on a bump level would be good enough and maybe better.
So it seems we arrived at an compromise, right? I think the point of this issue transformed into "lets add a bumb property to the gitmoji.json so outside tools know how to behavior when they see a emoji in front of the commit", right? Should we change the title/description of this issue them? Or, maybe better, open a new one with that in mind and close this? What do you all think about it? @elliot-nelson @gustavopch @carloscuesta @johannchopin
I don't understand really the purpose of the bump property ๐
Why it's named bump ? What kind of tools are going to look for this property ? What kind of values the property bump could contain ?
The values would be [major, minor, patch], i.e. the semantic versioning point to update.
Since this value we are discussing is really specific to semantic versioning of libraries/packages (which is only one subset of possible GitHub repos using gitmoji!), maybe the field we are talking about is more like "relatedSemanticVersion" or something.
(The idea is to relate the type of change being made to the type of semantic versioning bump that needs to happen.)
another name to bumb could be semver :thinking: (better name imo)
There's major, minor, patch and none. Commits that don't affect the product shouldn't trigger a version bump (think of changes to CI or docs).
I don't understand really the purpose of the
bumppropertyWhy it's named
bump? What kind of tools are going to look for this property ? What kind of values the propertybumpcould contain ?
It's basically meant to be used when creating configs for versioning tools like semantic-release.
What's the relation between the major/minor/patch/none values with conventional-commits ?
As far as I know, conventional commits propose something like that:
<type>[optional scope]: <description>
And the types are:
I'm a little bit confused ๐ค
Ah, that might be missing background. One of the reasons conventional-commits exists is to be able to produce semantic versions dynamically.
That is, if you read the conventional commits spec, it says:
patch (there is no none).feat: raises the level to minor.! suffix to any prefix (like feat!: or fix!:) raises the level to major.This specification allows tools to take a list of a dozen commits in a PR and turn it into the desired version bump for the next release, and then automatically release a new version of whatever library/module you're working on.
The real purpose of this issue, I guess, is to try and produce the same "specification" for gitmojis -- turning a pile of gitmoji commit messages into a desired new version bump.
this might be useful too for the repos like frinyvonnick/gitmoji-changelog (on #269), @frinyvonnick, could you give your thoughts on this? (pls :sweat_smile:, would appreciate :D)
An example of what that spec might look like (off the top of my head):
patch.minor.major.none (if the ONLY commit in a list was none, then you wouldn't need a new release of the package).There are also some emojis that are not semantic and thus can't really be used to make a semantic decision (things like :rewind: basically need to be ignored).
That is, if you read the conventional commits spec, it says:
- The default bump for any commit is
patch(there is nonone).- A prefix of
feat:raises the level tominor.- The words "BREAKING CHANGE" in any commit, _or_, adding
!suffix to any prefix (likefeat!:orfix!:) raises the level tomajor.
@elliot-nelson Are you sure "the default bump for any commit is patch"? That's not how it works in semantic-release. If I make a commit like ci: adjust cache, semantic-release won't bump the version at all.
@elliot-nelson I don't think :ambulance: should trigger a minor version bump. It's just fixing stuff. It doesn't introduce new features.
We must keep the following in mind:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.
Source: https://semver.org
Changes that don't affect the final build/bundle that will be shipped/deployed shouldn't trigger a new version as there's no reason to have two different versions when they don't differ in any way for the final user. Some of the emojis that shouldn't trigger a new version: :art:, :pencil:, :rocket:, :white_check_mark:, :construction:, :rotating_light:, :bookmark:, :green_heart:, :construction_worker:, etc.
@elliot-nelson Are you sure "the default bump for any commit is patch"? That's not how it works in
semantic-release. If I make a commit likeci: adjust cache,semantic-releasewon't bump the version at all.
You are right, after re-reading the paragraph I was thinking of, I clearly misunderstood it before. Here's the text I was thinking of:
Others: commit types other than fix: and feat: are allowed, for example @commitlint/config-conventional (based on the the Angular convention) recommends chore:, docs:, style:, refactor:, perf:, test:, and others. We also recommend improvement for commits that improve a current implementation without adding a new feature or fixing a bug. Notice these types are not mandated by the conventional commits specification, and have no implicit effect in semantic versioning (unless they include a BREAKING CHANGE, which is NOT recommended).
TLDR you're right, in conventional, you can use any prefix you want and it's considered "not a bump" (unless it includes a !: bang or BREAKING CHANGE in the text).
On gitmoji-changelog we grouped the commits using emojies into categories like added, breaking changes, ... Here is our configuration file. It could be useful to have this semver property to put commits into some categories. For example emojies of type major should go into breaking changes category. But it won't replace totally our configuration file.
@frinyvonnick Yes, I guess gitmoji shouldn't try to replace any config, but only provide the basics so that each tool out there using gitmoji work in a consistent way.
Taking a look into your configuration file though, it's not always possible to say whether a given emoji specifically "Added" or "Changed" something. For example, :dizzy: means "Adding or updating animations and transitions". So it would be impossible for gitmoji to expose a property that would map each emoji to one of those groups in your config.
If I follow the guidelines Gustavo mentioned, it might be easiest to work the other way:
All other emojis would potentially mean _changes to the app_ (obviously catching errors :goal_net: and making database changes :card_file_box: affect the app), but those commits wouldn't produce user-facing semantic version changes. You'd accompany them with other commits and/or other emojis in the same commit message if that change was also (fixing a bug, adding a feature, or making a breaking change)?
@elliot-nelson Adding to your list:
patch: :ambulance: because it fixes something; :ok_hand: :goal_net: because they are somewhat like fixes; :chart_with_upwards_trend: :loud_sound: :mute: :mag: because they must trigger a deployment but don't really change anything for the user.minor: :lipstick: :globe_with_meridians: :wheelchair: :speech_balloon: :children_crossing: :iphone: :egg: :dizzy: because they change the UI (they're like :sparkles: but more specific).If the logic is "requires a deployment", wouldn't almost all of them be at least patch? E.g. ๐๏ธ (database changes).
(Not arguing with your list, just trying to nail down the logic behind it.)
@elliot-nelson Well noted: :card_file_box: should bump the patch version. But, no, I don't think all emojis should trigger a version bump. For example, there's no reason to release a new version when you simply added a comment to the code. It's simply not necessary and won't help in any way.
Agree. I guess it boils down to, we'll need to evaluate each emoji on a case-by-case basis and add the field to each one, and it'll be patch for some and none for others.
Speaking of which... I noticed that as-is, the gitmoji project isn't actually available as a workable npm-installable package (am I misunderstanding it?). It looks like maybe the gitmoji project is the website, and running npm install gitmoji blows up on some node gyp step.
What I guess I'm expecting is something like:
$ npm install gitmoji
```js
const gitmoji = require('gitmoji');
console.log(gitmoji);
// => [
// {
// emoji: ":sparkles:",
// description: "Introducing new features.",
// semver: "minor"
// },
// ...
// ]
^ This is what I'd like for use in other projects.
Maybe more to the point, what I actually want is the fictitious package "gitmoji-semver":
```js
const gs = require('gitmoji-semver');
const message = ':sparkles: users can reset password';
console.log(gs.levelForMessage(message));
// => 'minor'
const messages = [
':bug: no more 404',
':sparkles: users can reset password'
];
console.log(gs.levelForMessages(messages));
// => 'minor'
Right now I'm trying to chart out the best path to get to the example snippet above.
@elliot-nelson I opened an issue in the past asking for that: https://github.com/carloscuesta/gitmoji/issues/410
Done @gustavopch at #444
Should this issue be closed ?
I think it's still an open question (or, I guess, a proposal?) that we add a semver field.
Carlos published gitmojis as an importable/requirable module so now you can do this:
import { gitmojis } from 'gitmojis';
console.log(gitmojis.filter(item => item.code === ':dizzy'));
But, this issue is about adding .semver property so each gitmoji indicates what an appropriate semver version bump would be for that commit.
Hello ! I wrote a script that adds a semver field to gitmojis.json. Until the semver field is officially added, I think this will be useful. It's easy to edit with a yaml file.
# semver.yml
semver:
major: [ boom ]
minor: [ sparkles ]
patch: [ bug, ambulance ]
genelate gitmojis.json file with semver field
$ cat build/dist/gitmojis.json | jq '.gitmojis[] | select(.name=="sparkles")'
{
"emoji": "โจ",
"entity": "✨",
"code": ":sparkles:",
"description": "Introduce new features.",
"name": "sparkles",
"semver": "minor"
}
Most helpful comment
Hello ! I wrote a script that adds a
semverfield togitmojis.json. Until thesemverfield is officially added, I think this will be useful. It's easy to edit with a yaml file.genelate
gitmojis.jsonfile withsemverfieldhttps://github.com/nkmr-jp/gitmoji-semver