Gitmoji: Add a "semver" field for each emoji

Created on 17 May 2020  ยท  35Comments  ยท  Source: carloscuesta/gitmoji

Summary

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.

Why?

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.)

Why bother if you can just use both conventional-commits and gitmoji?

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.

Could conventional-commit change to support gitmoji?

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?

discussion

Most helpful comment

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": "&#x2728;",
  "code": ":sparkles:",
  "description": "Introduce new features.",
  "name": "sparkles",
  "semver": "minor"
}

https://github.com/nkmr-jp/gitmoji-semver

All 35 comments

I thought I'd add some similar projects, for people looking:

  1. https://www.npmjs.com/package/@stackr23/gitmoji-conventional-commits

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.

  1. https://github.com/momocow/semantic-release-gitmoji

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.

  1. Doesn't exist yet (??)

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": "&#x1f3a8;",
      "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": "&#x1f41b;",
       "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 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 ? ๐Ÿค”

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 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 ?

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:

  • fix
  • feat
  • chore
  • refactor
  • docs

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:

  • The default bump for any commit is patch (there is no none).
  • A prefix of feat: raises the level to minor.
  • The words "BREAKING CHANGE" in any commit, _or_, adding ! 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):

  • Default level is patch.
  • The gitmojis :sparkles: and :ambulance: raise the level to minor.
  • The gitmoji :boom: raises the level to major.
  • The gitmojis :bulb:, :green_heart:, โœ… , and ๐Ÿšจ are considered 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 no none).
  • A prefix of feat: raises the level to minor.
  • The words "BREAKING CHANGE" in any commit, _or_, adding ! suffix to any prefix (like feat!: or fix!:) raises the level to major.

@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 like ci: adjust cache, semantic-release won'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:

  • By default, all emojis are considered "none" (no patch).
  • Fix emojis (:bug: :lock: :apple: :penguin: :checkered_flag: :robot: :green_apple: :pencil2:) all indicate a change in the app, so those are PATCH.
  • Feature emojis (:sparkles: :triangular_flag_on_post:) add (or unblock) features in the app, so those are MINOR.
  • Breaking emojis (:boom:) are MAJOR.

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": "&#x2728;",
  "code": ":sparkles:",
  "description": "Introduce new features.",
  "name": "sparkles",
  "semver": "minor"
}

https://github.com/nkmr-jp/gitmoji-semver

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tydax picture Tydax  ยท  29Comments

DanielHilton picture DanielHilton  ยท  13Comments

mikemarsian picture mikemarsian  ยท  14Comments

kevin-dedaniya-rcrm picture kevin-dedaniya-rcrm  ยท  11Comments

grissius picture grissius  ยท  17Comments