From dfea8470837e6d77a3c1098e9d00fd25a44b5bf4 Mon Sep 17 00:00:00 2001
From: Daniel Dehennin <daniel.dehennin@ac-dijon.fr>
Date: Mon, 11 Oct 2021 14:49:45 +0200
Subject: [PATCH] ci(gitlab): add commit lint and its documentation

* .gitlab-ci.yml: define only stage `lint` for now and run
`commitlint` at that stage.

* docs/CONTRIBUTING.md: describe the commit message formatting rules.

* README.md: link to the contributing guide.
---
 .gitlab-ci.yml       |  36 ++++++++++++
 README.md            |  10 +++-
 commitlint.config.js |   8 +++
 docs/CONTRIBUTING.md | 134 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 187 insertions(+), 1 deletion(-)
 create mode 100644 .gitlab-ci.yml
 create mode 100644 commitlint.config.js
 create mode 100644 docs/CONTRIBUTING.md

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..87d3586
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# vim: ft=yaml
+---
+
+###############################################################################
+# Define stages and global variables
+###############################################################################
+default:
+  tags:
+    - one
+    - eole
+    - docker
+
+stages:
+  - lint
+variables:
+  DOCKER_DRIVER: 'overlay2'
+
+commitlint:
+  stage: lint
+  image: 'hub.eole.education/eole/commitlint:latest'
+  before_script:
+    # Add `upstream` remote to get access to `upstream/master`
+    - "git remote show upstream 2> /dev/null || git remote add upstream ${CI_REPOSITORY_URL}"
+    - 'git fetch --all'
+  after_script:
+    # Remove `upstream` to avoid caching `CI_JOB_TOKEN`
+    - "git remote remove upstream"
+  script:
+    # Set default commit hashes for `--from` and `--to`
+    - 'export COMMITLINT_FROM="$(git merge-base upstream/master HEAD)"'
+    - 'export COMMITLINT_TO="${CI_COMMIT_SHA}"'
+    # Run `commitlint`
+    - 'commitlint --from "${COMMITLINT_FROM}"
+                  --to   "${COMMITLINT_TO}"
+                  --verbose'
diff --git a/README.md b/README.md
index 4a4731c..91a3f6d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,11 @@
 # CI tools
 
-Tools for the Gitlab CI
\ No newline at end of file
+Tools for the Gitlab CI
+
+## Contributing to this project
+
+### Commit messages
+
+Commit messages formatting is **significant**!
+
+Please, see [How to contribute](docs/CONTRIBUTING.md) for more details
diff --git a/commitlint.config.js b/commitlint.config.js
new file mode 100644
index 0000000..4eb37f4
--- /dev/null
+++ b/commitlint.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+    extends: ['@commitlint/config-conventional'],
+    rules: {
+        'body-max-line-length': [2, 'always', 120],
+        'footer-max-line-length': [2, 'always', 120],
+        'header-max-length': [2, 'always', 72],
+    },
+};
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
new file mode 100644
index 0000000..04ca1d4
--- /dev/null
+++ b/docs/CONTRIBUTING.md
@@ -0,0 +1,134 @@
+# How to contribute
+
+This document will eventually outline all aspects of guidance to make your
+contributing experience a fruitful and enjoyable one. What it already contains
+is information about commit message formatting and how that directly affects
+the numerous automated processes that are used for this repo. It also covers
+how to contribute to this project documentation.
+
+[[_TOC_]]
+
+## Overview
+
+
+Submitting a merge request is more than just code! To achieve a quality
+product, the tests and documentation need to be updated as well. An excellent
+merge request will include these in the changes, wherever relevant.
+
+
+## Commit message formatting
+
+Since every type of change requires making Git commits, we will start by
+covering the importance of ensuring that all of your commit messages are in the
+correct format.
+
+### Automation of multiple processes
+
+This project uses
+[semantic-release](https://github.com/semantic-release/semantic-release) for
+automating numerous processes such as bumping the version number appropriately,
+creating new tags/releases and updating the changelog. The entire process
+relies on the structure of commit messages to determine the version bump, which
+is then used for the rest of the automation.
+
+Full details are available in the upstream docs regarding
+the [Conventionnal Commit Message Conventions](https://www.conventionalcommits.org/en/v1.0.0/).
+The key factor is that the first line of the commit message must follow this format:
+
+```
+type(scope): subject
+```
+
+For example:
+
+```
+feat(libfoo): new API `foo.quux` deprecates `foo.bar`
+
+We create the new API `foo.quux` to better do things and mark
+`foo.bar` deprecated from version `1.3.4`.
+
+* test/libfoo.t: test the new API `foo.quux`
+
+* lib/foo.pl: new API `foo.quux` and mark `foo.bar` deprecated.
+```
+
+Besides the version bump, the changelog and release notes are formatted
+accordingly. So based on the example above:
+
+> Features
+>
+> - **libfoo**: new API `foo.quux` deprecates `foo.bar`
+
+- The `type` translates into a `Features` sub-heading.
+- The `(scope)`: will be shown in bold text without the brackets.
+- The `subject` follows the `scope` as standard text.
+
+### Linting commit messages in CI
+
+This project uses
+[commitlint](https://github.com/conventional-changelog/commitlint) for checking
+commit messages during CI testing. This ensures that they are in accordance
+with the
+[semantic-release](https://github.com/semantic-release/semantic-release)
+settings.
+
+For more details about the default settings, refer back to
+the [`commitlint` reference rules](https://conventional-changelog.github.io/commitlint/#/reference-rules).
+
+
+### Relationship between commit type and version bump
+
+This project applies some customisation to the defaults, as outlined in the
+table below, based upon the type of the commit:
+
+| Type     | Heading                  | Description                                                                                             | Bump (default) | Bump (custom) |
+|----------|--------------------------|---------------------------------------------------------------------------------------------------------|----------------|---------------|
+| build    | Build System             | Changes related to the build system                                                                     | –              | _             |
+| chore    | –                        | Changes to the build process or auxiliary tools and libraries such as documentation generation          | –              | _             |
+| ci       | Continuous Integration   | Changes to the continuous integration configuration                                                     | –              | _             |
+| docs     | Documentation            | Documentation only changes                                                                              | –              | 0.0.1         |
+| feat     | Features                 | A new feature                                                                                           | 0.1.0          | 0.1.0         |
+| fix      | Bug Fixes                | A bug fix                                                                                               | 0.0.1          | 0.0.1         |
+| perf     | Performance Improvements | A code change that improves performance                                                                 | 0.0.1          | 0.0.1         |
+| refactor | Code Refactoring         | A code change that neither fixes a bug nor adds a feature                                               | –              | 0.0.1         |
+| revert   | Reverts                  | A commit used to revert a previous commit                                                               | –              | 0.0.1         |
+| style    | Styles                   | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.) | –              | 0.0.1         |
+| test     | Tests                    | Adding missing or correcting existing tests                                                             | –              | 0.0.1         |
+
+
+#### Scopes
+
+Even if it is possible to
+[limit the possible scopes](https://github.com/conventional-changelog/commitlint/blob/master/docs/reference-rules.md#scope-enum)
+like [in Angular](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope),
+this project does not enforce them and let the contributors define meaningful
+ones in their commits.
+
+### Use `BREAKING CHANGE` to trigger a `major` version change
+
+Adding `BREAKING CHANGE` to the footer of the extended description of the
+commit message will **always** trigger a `major` version change, no matter
+which type has been used. This will be appended to the changelog and release
+notes as well. To preserve good formatting of these notes, the following format
+is prescribed:
+
+```
+BREAKING CHANGE: <explanation in paragraph format>.
+```
+
+An example of that:
+
+```
+feat(api): remove the API deprecated before 1.4.0
+
+To make the project maintainable, we need to cleanup some deprecated
+API.
+
+The API deprecated after 1.4.0 are not concerned by this cleanup.
+
+BREAKING CHANGE: the old API `foo.bar` was deprecated since version 1.3.4 and is
+removed now.
+
+BREAKING CHANGE: the old API `foo.baz` was deprecated since version 1.2.6 and is
+removed now.
+```
-- 
GitLab