Giter VIP home page Giter VIP logo

opinionated-commit-message's Introduction

opinionated-commit-message

version build-and-test

Opinionated-commit-message is a GitHub Action which checks commit messages according to an opinionated style.

The style was inspired by https://chris.beams.io/posts/git-commit/:

  • Separate subject from body with a blank line
  • Limit the subject line to 50 characters
  • Capitalize the subject line
  • Do not end the subject line with a period
  • Use the imperative mood in the subject line
  • Wrap the body at 72 characters
  • Use the body to explain what and why (instead of how)

Here is an example commit message:

Set up Open ID HttpClient with default proxy

Previously, the Open ID HttpClient was simply instantiated without 
default proxy credentials. However, if there are company proxies,
HttpClient must use the default proxy with OpenID Connect.

Prior Art

There exist a good action to check commit messages, commit-message-checker (https://github.com/GsActions/commit-message-checker). However, it is limited to regular expressions which makes more complex checks (such as imperative mood) hard or impossible to implement.

I based my implementation heavily on commit-message-checker and would like to thank the author for the great work!

Example Workflow

You can set up a GitHub workflow to automatically check messages. Put the following file in .github/workflows/check-commit-message.yml and GitHub should pick it and set it up.

name: 'Check commit message style'
on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
  push:
    branches:
      - master
      - 'dev/*'

jobs:
  check-commit-message-style:
    name: Check commit message style
    runs-on: ubuntu-latest
    steps:
      - name: Check
        uses: mristin/[email protected]

Checked Events

Opinionated-commit-message verifies commit messages on the GitHub events pull_request and push.

In the case of pull requests only the title and the body of the pull request are checked.

On push, all the commit messages of the push are verified.

List of Verbs

Since the subject needs to start with a verb in the imperative mood, we pre-compiled a whitelist of most frequent English verbs together with verbs frequently used in commit messages from our own projects.

However, given the variety of projects in the wild, this whitelist is not sufficient to cover all the possible verbs. We therefore introduce the action input additional-verbs so that you can add your own verbs.

The additional verbs are given as a comma, semicolon or new line separated string in the workflow file. For example:

    steps:
      - name: Check
        uses: mristin/[email protected]
        with:
          additional-verbs: 'chrusimusi, unit-test'

If you prefer to have your additional verbs in imperative mood in a separate file (e.g., to keep the workflow file succinct), you can supply the path as input:

    steps:
      - name: Check
        uses: mristin/[email protected]
        with:
          path-to-additional-verbs: 'src/additional-verbs.txt'

Long URLs

Splitting URLs on separate lines to satisfy the maximum character lenght breaks the link functionality on most readers (e.g., in a terminal or on GitHub). Therefore we need to tolerate long URLs in the message body.

Nevertheless, in order to make the text readable the URL should be put either on a separate line or defined as a link in markdown.

For example, this is how you can write a message with an URL on a separate line:

Please see this page for more details:
http://some-domain.com/very/long/long/long/long/long/long/long/long/long/path.html
or read the manual.

Here is the same message with a link definition (arguably a bit more readable):

Please see [this page for more details][1] or read the manual.

[1]: http://some-domain.com/very/long/long/long/long/long/long/long/long/long/path.html

One-liners

Usually, you need to write elaborate commit messages with a shorter header and more verbose body for an informative Git history. However, this might be too rigid for certain projects.

You can allow one-liner commit messages by setting the flag allow-one-liners:

    steps:
      - name: Check
        uses: mristin/[email protected]
        with:
          allow-one-liners: 'true'

Custom subject length

For use in terminals and monospaced GUIs it is a good practice to limit length of the subject to 50 characters. For some projects, though, this limit is too restrictive. For example, if you include tags in the subject (such as [FIX]) there is not much space left for the actual subject.

You can change the imposed maximum subject length by setting the flag max-subject-line-length:

    steps:
      - name: Check
        uses: mristin/opinionated-commit-message@v2
        with:
          max-subject-line-length: '100'

Custom line length on the body

Similar to the subject line, for terminals and monospaced GUIs it is a good practice to limit the line length of the body to 72 characters. However, the restriction is unnecessarily harsh for teams that use modern GUIs such as GitHub Web. This is especially so when using a description of the pull request as the body, since there is no such limitation in the GitHub UI itself.

You can change the imposed maximum line length by setting the flag max-body-line-length:

    steps:
      - name: Check
        uses: mristin/opinionated-commit-message@v2
        with:
          max-body-line-length: '100'

Skip Body Check

For some repositories only the subject matters while the body is allowed to be free-form. For example, this is the case when the body of the commit is automatically generated (e.g., by a third-party service that we do not control). In such situations, we want check the subject line, but ignore the body in the checks.

You can disable checking the body by setting the flag skip-body-check:

    steps:
      - name: Check
        uses: mristin/opinionated-commit-message@v2
        with:
          skip-body-check: 'true'

Validating PR commit messages

When triggered by a pull_request event, the action checks the title and the body of the pull request by default. GitHub does not include the content of the commit message in the workflow context, so checking all the commit messages of the PR requires additional API calls. If you want to check the commit messages for pull requests you can either:

  • Trigger the action on push events. This will check the commit messages of each pushed commit, but it will run even for branches that do not have a PR associated with them.
  • Set the validate-pull-request-commits option to true. This will check the messages of every commit in the PR. However, because it requires extra API calls to retrieve the commit messages, setting this on option on private repositories require a GitHub token with at least read permission on the contents scope.
    steps:
      - name: Check
        uses: mristin/[email protected]
        with:
          validate-pull-request-commits: 'true'
          # Required for private repos
          github-token: ${{ secrets.GITHUB_TOKEN }}

Permissions

The default permissions for a GitHub Actions workflow is sufficient for this action to work. You only need to check permissions if you are already customizing the permissions of the workflow See the GitHub documentation.

jobs:
  check-commits:
    # If you have this line,
    permissions:
      # Make sure this you also have this line
      contents: read
    steps:
      - uses: mristin/[email protected]
        with:
          validate-pull-request-commits: 'true'
          github-token: ${{ secrets.GITHUB_TOKEN }}

Enforce Sign-off

Most projects do not require a sign-off on the commits. However, there are projects which need every commit to be signed off to avoid legal, safety and other official repercussions (for more information, see this issue and this StackOverflow question).

We provide an enforce-sign-off flag so that you can enforce the sign-off in the commits by:

    steps:
      - name: Check
        uses: mristin/[email protected]
        with:
          enforce-sign-off: 'true'

The check expects that the body of the commit contains one or more lines like this one:

Signed-off-by: Some Body <[email protected]>

You usually sign off the commits using git commit --signoff.

Contributing

If you would like to report bugs or request a feature, please create a new issue.

Please see CONTRIBUTING.md if you would like to contribute to the code.

License

This project is released under the terms of the MIT License.

opinionated-commit-message's People

Contributors

devjvao avatar faern avatar friederbluemle avatar fryuni avatar irangarcia avatar krahlro-sick avatar marcospassos avatar mristin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

opinionated-commit-message's Issues

One line commit messages should not be rejected

One line commit messages are currently rejected with the message:

Expected at least three lines (subject, empty, body), but got: 1

Chris Beams's guidelines say that one line messages are just fine, however:

not every commit requires both a subject and a body. Sometimes a single line is fine, especially when the change is so simple that no further context is necessary.

Check for weird unicode in the message

Hi. I was looking around for a github actions workflow to sanity check our commit messages. This looks really promising! But it does not solve one of our issues: Weird unicode stuff ending up in commit messages. I guess this is mostly due to some git GUIs and/or locale settings?

Most commonly strange newlines. I currently have a commit in main that I would have liked to catch that has content similar to this (as rendered by the terminal):

Add this new cool feature whatever<U+2028>

Body of commit

U+2028 is a special line separator character. I don't think anyone wants them in their commit message history. But this action does not mark it as an error.

Consider heuristics for imperative detection

Personally, I've found that the rate at which I need to add imperatives to my exceptions file is not slowing down.

One idea: try adding "s" or "es" to the word and see whether that is still a word. If so, you've likely got an imperative.
This dataset would be pretty big (one for every English verb), but maybe still worthwhile?

And I suppose (-"y" +"ies") is another pattern for verbs ending in "y". (e.g. "dry" => "dries")

Merge commits are failing length check

When a pull request is merged it will contain a subject message similar to the following:

Merge pull request #117 from Organisaiton/name-of-the-branch-being-merged

This is longer than the default 50 character limit. When the action runs on the main branch it fails.

Extract allowed verbs to a plain txt-file

The fact that the format of the list of allowed verbs is like:

export const SET = new Set([
  'abandon',
  ...
  'write',
]);

Makes it unnecessarily hard to update, sort and maintain. It would be much easier if all the allowed verbs was in a plain textfile, with each verb separated by a single newline (\n). Just like the format of path-to-additional-verbs.

The code to parse that type of list must already be there thanks to the path-to-additional-verbs functionality.

Allow long URLs in commit messages

I propose that URLs should always be allowed in the body of commit messages, even when longer than 72 characters.

Given that commit messages should be well-documented, relevant URLs should be encouraged, I'd say. Alternatives such as using a URL shortener have downsides (makes the writing of the commit message more cumbersome, and makes the actual destination URL opaque).

There seems to be something of a consensus in the open source world around allowing long URLs (1, 2, 3, 4).

If you agree and decide to add this feature, I'd propose as a potential implementation skipping the line length check for any line that has a URL in it. I think a check that only allows long URLs if they are the only content on a given line would be too restrictive, as a common approach is to have the urls sequentially numbered as reference links at the foot of the commit message.

Trouble downloading this action

Hey there - I'm really interested in using this action. I'm copying and pasting the job as described in the docs and seem to be getting an error while downloading the action. We are big users of github actions, but have never published one ourselves - so I don't know what is required to host the tarball of the action on github.

Here's the action that we are using

name: 'Check commit message style'
on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
  push:
    branches:
      - '*'

jobs:
  check-commit-message-style:
    name: Check commit message style
    runs-on: ubuntu-latest
    steps:
      - name: Check
        uses: mristin/opinionated-commit-message@v2

Here's the error:

Current runner version: '2.273.0'
Operating System
Virtual Environment
Prepare workflow directory
Prepare all required actions
Download action repository 'mristin/opinionated-commit-message@v2'
##[error]An action could not be found at the URI 'https://api.github.com/repos/mristin/opinionated-commit-message/tarball/v2'

The version 3 not found

Error: Unable to resolve action mristin/opinionated-commit-message@v3, unable to find version v3

The README suggests using @v3 but the GHA is unable to find this version.

Accept body lines with 72 characters

This check failed with the error message The line 3 of the message (line 1 of the body) exceeds the limit of 72 characters. But the commit message has exactly 72 characters:

This patch fixes a typo in the readme file where this project was called
dead-csharp instead of doctest-csharp.
123456789012345678901234567890123456789012345678901234567890123456789012

The code looks correct at first glance, but maybe the newline is counted as part of the line? In this case, the subject check might be off by one too.

Looking for (co-)maintainer

Hi @statuscake-machine, @1david5 and @johnboyes,
I fired up WebStorm today, tried to re-compile the project, and fix #110 and #28. The number of dependency warnings and errors was just overwhelming. This is all too much for me, as I reserved only one-two hours for these issues today, and that is now up.

Would you perhaps be interested to help me co-maintain the package or take over the maintenance altogether?

Automate end-to-end tests

@johnboyes I forked the discussion from the issue #73 to here.

@johnboyes wrote:

Doing end-to-end tests every time is a great idea, I wonder if you could automate them? You could have a GitHub Action workflow in your repo triggered on every push, that programatically creates commits on an example repo, running against the corresponding version of the opinionated-commit-message checker? Just sharing ideas :-)

I am pretty time-strapped at the moment (kids, busy at work, multiple parallel open source projects...). Ideally, if I had time, I'd agree with you :) -- the manual end-to-end tests were a poor man's solution. At the moment, I would really welcome a pull request if somebody has time for it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.