From 01f01462e081a7d64ecb3e10a4d58ce969a57b65 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 8 Nov 2024 12:53:33 -0700 Subject: [PATCH] ci: Add gitlint and document commit conventions * Add gitlint to pre-commit setup * Update pre-commit setup for installing commit-hooks * Add "Commit Conventions" contributing docs --- .gitlint | 138 ++++++++++++++++++ .pre-commit-config.yaml | 7 +- .../contributing/commit-messages.md | 68 +++++++++ .../development/local-toolchain/pre-commit.md | 4 +- docs/sidebars.js | 1 + 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 .gitlint create mode 100644 docs/docs/development/contributing/commit-messages.md diff --git a/.gitlint b/.gitlint new file mode 100644 index 000000000000..f5ed1479da19 --- /dev/null +++ b/.gitlint @@ -0,0 +1,138 @@ +# Edit this file as you like. +# +# All these sections are optional. Each section with the exception of [general] represents +# one rule and each key in it is an option for that specific rule. +# +# Rules and sections can be referenced by their full name or by id. For example +# section "[body-max-line-length]" could also be written as "[B1]". Full section names are +# used in here for clarity. +# +[general] +# Ignore certain rules, this example uses both full name and id +# ignore=title-trailing-punctuation, T3 + +# verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this +# verbosity = 2 + +# By default gitlint will ignore merge, revert, fixup, fixup=amend, and squash commits. +# ignore-merge-commits=true +# ignore-revert-commits=true +# ignore-fixup-commits=true +# ignore-fixup-amend-commits=true +# ignore-squash-commits=true + +# Ignore any data sent to gitlint via stdin +# ignore-stdin=true + +# Fetch additional meta-data from the local repository when manually passing a +# commit message to gitlint via stdin or --commit-msg. Disabled by default. +# staged=true + +# Hard fail when the target commit range is empty. Note that gitlint will +# already fail by default on invalid commit ranges. This option is specifically +# to tell gitlint to fail on *valid but empty* commit ranges. +# Disabled by default. +# fail-without-commits=true + +# Whether to use Python `search` instead of `match` semantics in rules that use +# regexes. Context: https://github.com/jorisroovers/gitlint/issues/254 +# Disabled by default, but will be enabled by default in the future. +# regex-style-search=true + +# Enable debug mode (prints more output). Disabled by default. +# debug=true + +# Enable community contributed rules +# See http://jorisroovers.github.io/gitlint/contrib_rules for details +contrib=contrib-title-conventional-commits,CT1,contrib-disallow-cleanup-commits,CC2 + +# Set the extra-path where gitlint will search for user defined rules +# See http://jorisroovers.github.io/gitlint/user_defined_rules for details +# extra-path=examples/ + +[title-max-length] +line-length=80 + +# Conversely, you can also enforce minimal length of a title with the +# "title-min-length" rule: +# [title-min-length] +# min-length=5 + +# [title-must-not-contain-word] +# Comma-separated list of words that should not occur in the title. Matching is case +# insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING" +# will not cause a violation, but "WIP: my title" will. +# words=wip + +# [title-match-regex] +# python-style regex that the commit-msg title must match +# Note that the regex can contradict with other rules if not used correctly +# (e.g. title-must-not-contain-word). +# regex=^US[0-9]* + +# [body-max-line-length] +# line-length=72 + +# [body-min-length] +# min-length=5 + +# [body-is-missing] +# Whether to ignore this rule on merge commits (which typically only have a title) +# default = True +# ignore-merge-commits=false + +# [body-changed-file-mention] +# List of files that need to be explicitly mentioned in the body when they are changed +# This is useful for when developers often erroneously edit certain files or git submodules. +# By specifying this rule, developers can only change the file when they explicitly reference +# it in the commit message. +# files=gitlint-core/gitlint/rules.py,README.md + +# [body-match-regex] +# python-style regex that the commit-msg body must match. +# E.g. body must end in My-Commit-Tag: foo +# regex=My-Commit-Tag: foo$ + +# [author-valid-email] +# python-style regex that the commit author email address must match. +# For example, use the following regex if you only want to allow email addresses from foo.com +# regex=[^@]+@foo.com + +# [ignore-by-title] +# Ignore certain rules for commits of which the title matches a regex +# E.g. Match commit titles that start with "Release" +# regex=^Release(.*) + +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# [ignore-by-body] +# Ignore certain rules for commits of which the body has a line that matches a regex +# E.g. Match bodies that have a line that that contain "release" +# regex=(.*)release(.*) +# +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# [ignore-body-lines] +# Ignore certain lines in a commit body that match a regex. +# E.g. Ignore all lines that start with 'Co-Authored-By' +# regex=^Co-Authored-By + +# [ignore-by-author-name] +# Ignore certain rules for commits of which the author name matches a regex +# E.g. Match commits made by dependabot +# regex=(.*)dependabot(.*) +# +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# This is a contrib rule - a community contributed rule. These are disabled by default. +# You need to explicitly enable them one-by-one by adding them to the "contrib" option +# under [general] section above. +# [contrib-title-conventional-commits] +# Specify allowed commit types. For details see: https://www.conventionalcommits.org/ +# types = bugfix,user-story,epic diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 352ad7232773..1c6d560cef3e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: rev: v1.5.1 hooks: - id: remove-tabs - exclude: "vendor-prefixes\\.txt$" + exclude: "vendor-prefixes\\.txt$|.git/COMMIT_EDITMSG" - repo: https://github.com/pre-commit/mirrors-clang-format rev: v18.1.8 hooks: @@ -16,9 +16,14 @@ repos: rev: v2.7.1 hooks: - id: prettier + exclude: ".git/COMMIT_EDITMSG" # Workaround for https://github.com/pre-commit/mirrors-prettier/issues/29 additional_dependencies: - prettier@2.8.7 + - repo: https://github.com/jorisroovers/gitlint + rev: v0.19.1 + hooks: + - id: gitlint - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: diff --git a/docs/docs/development/contributing/commit-messages.md b/docs/docs/development/contributing/commit-messages.md new file mode 100644 index 000000000000..5934e247e384 --- /dev/null +++ b/docs/docs/development/contributing/commit-messages.md @@ -0,0 +1,68 @@ +--- +title: Commit Messages +--- + +The ZMK project uses [conventional commits](https://www.conventionalcommits.org/) for their commit messages. This not only provides consistency for our commits, but also allows for release/versioning automation to determine the next version to release, generating changelogs, etc. + +Commit messages will be checked as part of our CI process by GitHub Actions. + +## Guidelines + +Commits should have the following: + +- A first line prefix that includes a [type](#types), as well as appropriate [scope](#scopes) as needed +- Following the prefix, a concise summary of the change, which documents the new behavior/feature/functionality in the positive (e.g. "wake from sleep now works with charlieplex kscan", not "fixed waked from sleep bug with charlieplex kscan driver") +- A blank line following the first line. +- A body that provides more detail of the changes. This MAY be a bulleted list or paragraph prose. +- An optional set of [git trailers](https://git-scm.com/docs/git-interpret-trailers#_description) for things like [GitHub keywords](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests) following a blank line. + +## Example + +Here is an example good commit message: + +``` +feat(boards): Add numpad layouts + +Added physical layouts for the following variants of numpads: + +- With and without extra top row +- 2U plus key or 1U plus and backspace keys +- 2U 0 key or 1U 0 and 00 keys +- Full 1U grid/macropad layout + +Other layouts exist, such as "southpaw" horizontally mirrored layouts, +and layouts with a fifth column, but those seem to be much less common. +``` + +## Pre-Commit + +To help make sure you don't need to wait for GitHub Actions to check your commits, you can [set up pre-commit](../local-toolchain/pre-commit.md) to check your commits as you create them. + +## Types + +The following commit types are used by ZMK: + +- `docs:` - changes to our documentation found in the `docs/` directory. +- `feat:` - changes that add a new feature +- `fix:` - changes that fix existing functionality +- `refactor:` - changes that refactor existing functionality without adding any new features +- `feat!:`/`refactor!:`/`fix!` - same as above, but indicate a breaking change. +- `ci:` - changes to our continuous integration setup with GitHub Actions, usually only for the files in `.github/workflows/`. +- `chore:` - grab bag type for small changes that don't fall into any of the above categories. + +## Scopes + +The following scopes are frequently used to further clarify the scope of the change: + +- `hid` - changes to our general HID code +- `usb` - changes specific to USB +- `ble` - changes specific to BLE +- `power` - changes to our power management code +- `split` - changes to our split keyboard support +- `studio` - changes to our ZMK Studio code +- `display` - changes to to our display code +- `underglow` - changes to to our RGB underglow support +- `behaviors` - changes to to our core behavior code +- `core` - changes to any other area of our core code +- `boards` - changes to the in-tree boards +- `shields` - changes to the in-tree shields diff --git a/docs/docs/development/local-toolchain/pre-commit.md b/docs/docs/development/local-toolchain/pre-commit.md index b4306fc95217..fdc66513fd86 100644 --- a/docs/docs/development/local-toolchain/pre-commit.md +++ b/docs/docs/development/local-toolchain/pre-commit.md @@ -22,12 +22,14 @@ Now that pre-commit is installed on your PC, you need to install it into the ZMK ```bash pre-commit install +pre-commit install --hook-type commit-msg ``` This should print a message such as ``` -pre-commit installed at .git\hooks\pre-commit +pre-commit installed at .git/hooks/pre-commit +pre-commit installed at .git/hooks/commit-msg ``` Pre-commit will now automatically check your changes whenever you run `git commit`. If it detects a problem, it will describe the problem and cancel the commit. For simple problems such as incorrect formatting, it will also automatically fix the files so you can just `git add` them and try again. diff --git a/docs/sidebars.js b/docs/sidebars.js index 6452130acc3c..3cdd84e63860 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -142,6 +142,7 @@ module.exports = { collapsed: true, items: [ "development/contributing/clean-room", + "development/contributing/commit-messages", "development/contributing/documentation", ], },