From 65373f236b0ff9b2c2b93f5bba39ee5ab1b78b53 Mon Sep 17 00:00:00 2001 From: Einherjar Date: Tue, 12 Sep 2023 12:42:06 -0300 Subject: [PATCH 1/6] ci: add commits check to CI Closes #1119. Creates `commits.yml` in `.github/workflows/` directory with a new GH Action that has 2 jobs: 1. `signed-commits`: uses [`1Password/check-signed-commits-action`](https://github.com/1Password/check-signed-commits-action) to check if all commits in the PR are signed. 1. `conventional-commits`: uses [`cocogitto/cocogitto-action`](https://github.com/cocogitto/cocogitto-action) based on [`cocogitto`](https://crates.io/crates/cocogitto) to check if all commits in the PR follows the conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.2/), i.e. they are prefixed with `fix`, `refactor`, `feat` etc. --- .github/workflows/commits.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/commits.yml diff --git a/.github/workflows/commits.yml b/.github/workflows/commits.yml new file mode 100644 index 000000000..badeb199a --- /dev/null +++ b/.github/workflows/commits.yml @@ -0,0 +1,26 @@ +name: Check Commits + +on: + pull_request: + branches: master + +jobs: + signed-commits: + name: Check signed commits in PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check signed commits in PR + uses: 1Password/check-signed-commits-action@v1 + conventional-commits: + name: Conventional Commits + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + # needs the full log + fetch-depth: 0 + # pick the pr HEAD instead of the merge commit + ref: ${{ github.event.pull_request.head.sha }} + - name: Check conventional commits in PR + uses: cocogitto/cocogitto-action@v3 From 335a9f46a7463eacb24b57b3f919cd03e2091b73 Mon Sep 17 00:00:00 2001 From: Einherjar Date: Tue, 12 Sep 2023 12:50:59 -0300 Subject: [PATCH 2/6] fix: explain the GPG sign commits in CONTRIBUTING.md --- CONTRIBUTING.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a83ccf57..76225abd8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,8 +48,13 @@ hesitate to split it into multiple small, focused PRs. The Minimal Supported Rust Version is **1.57.0** (enforced by our CI). +Commits should be signed with GPG using a key with a valid email address. Commits should cover both the issue fixed and the solution's rationale. -These [guidelines](https://chris.beams.io/posts/git-commit/) should be kept in mind. Commit messages should follow the ["Conventional Commits 1.0.0"](https://www.conventionalcommits.org/en/v1.0.0/) to make commit histories easier to read by humans and automated tools. +These [guidelines](https://chris.beams.io/posts/git-commit/) should be kept in mind. +Commit messages should follow the ["Conventional Commits 1.0.0"](https://www.conventionalcommits.org/en/v1.0.0/) +to make commit histories easier to read by humans and automated tools. +You can use tools like [`cocogitto`](https://github.com/cocogitto/cocogitto) +to check if your commit messages follow the convention. To facilitate communication with other contributors, the project is making use of GitHub's "assignee" field. First check that no one is assigned and then From 32a5dd78b82766a475166f121eeadab481bda57e Mon Sep 17 00:00:00 2001 From: Einherjar Date: Fri, 15 Sep 2023 19:39:52 -0300 Subject: [PATCH 3/6] ci: cocogitto check-latest-tag-only --- .github/workflows/commits.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/commits.yml b/.github/workflows/commits.yml index badeb199a..a8ffae010 100644 --- a/.github/workflows/commits.yml +++ b/.github/workflows/commits.yml @@ -24,3 +24,5 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Check conventional commits in PR uses: cocogitto/cocogitto-action@v3 + with: + check-latest-tag-only: true From 9ad89202b74236220d0602895d5ccf9b7d639fe4 Mon Sep 17 00:00:00 2001 From: Einherjar Date: Sun, 17 Sep 2023 07:12:35 -0300 Subject: [PATCH 4/6] feat(git-hook): `{signed,conventional}-commits.sh` - `signed-commits.sh` hook (a `pre-push` hook) will not allow the user to push to remote if the last commit is not signed. This is a good sanity test,if the last commit is signed then there is a high chance of any other previous are also signed. - `conventional-commits.sh` hook (a `commit-msg` hook) will not allow the user to commit if the commit message does not satisfy the Conventional Commits template. --- CONTRIBUTING.md | 30 +++++++++++++++++++++++----- ci/git-hooks/conventional-commits.sh | 20 +++++++++++++++++++ ci/git-hooks/signed-commits.sh | 16 +++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100755 ci/git-hooks/conventional-commits.sh create mode 100755 ci/git-hooks/signed-commits.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76225abd8..fad5e4467 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,6 +48,15 @@ hesitate to split it into multiple small, focused PRs. The Minimal Supported Rust Version is **1.57.0** (enforced by our CI). +To facilitate communication with other contributors, the project is making use +of GitHub's "assignee" field. First check that no one is assigned and then +comment suggesting that you're working on it. If someone is already assigned, +don't hesitate to ask if the assigned party or previous commenter are still +working on it if it has been awhile. + +Commit policy +------------- + Commits should be signed with GPG using a key with a valid email address. Commits should cover both the issue fixed and the solution's rationale. These [guidelines](https://chris.beams.io/posts/git-commit/) should be kept in mind. @@ -56,11 +65,22 @@ to make commit histories easier to read by humans and automated tools. You can use tools like [`cocogitto`](https://github.com/cocogitto/cocogitto) to check if your commit messages follow the convention. -To facilitate communication with other contributors, the project is making use -of GitHub's "assignee" field. First check that no one is assigned and then -comment suggesting that you're working on it. If someone is already assigned, -don't hesitate to ask if the assigned party or previous commenter are still -working on it if it has been awhile. +[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) can be used +to automate some of the above checks. +There are hooks provided in the `ci/git-hooks` directory that can be installed: + +```bash +cp ci/git-hooks/signed-commits.sh .git/hooks/pre-push +cp ci/git-hooks/conventional-commits.sh .git/hooks/commit-msg +``` + +`signed-commits.sh` hook (a `pre-push` hook) +will not allow the user to push to remote if the last commit is not signed. +This is a good sanity test, +if the last commit is signed then there is a high chance +of any other previous are also signed. +`conventional-commits.sh` hook (a `commit-msg` hook) will not allow the user to commit +if the commit message does not satisfy the Conventional Commits template. Deprecation policy ------------------ diff --git a/ci/git-hooks/conventional-commits.sh b/ci/git-hooks/conventional-commits.sh new file mode 100755 index 000000000..9bdefda78 --- /dev/null +++ b/ci/git-hooks/conventional-commits.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# Conventional commit regex pattern +# bash regex do not support \w \d \s etc +pattern="^(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert)(\([[:alnum:]\-]+\))?:[[:space:]].*" + +# Read the commit message from the file +commit_file="$1" +commit_head_message=$(head -n1 "$commit_file") + +# Check if the commit message matches the pattern +if ! [[ "$commit_head_message" =~ $pattern ]]; then + echo "Error: Invalid commit message format. Please use a conventional commit message." + echo "Commit message should match the pattern: $pattern." + echo "Please refer to https://www.conventionalcommits.org/en/v1.0.0/ for more details." + exit 1 +fi + +# If the commit message matches the pattern, the hook exits successfully +exit 0 diff --git a/ci/git-hooks/signed-commits.sh b/ci/git-hooks/signed-commits.sh new file mode 100755 index 000000000..ca77afdd2 --- /dev/null +++ b/ci/git-hooks/signed-commits.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Function to verify the signature of the last commit +verify_signature() { + local commit_hash=$(git rev-parse HEAD) + if ! git verify-commit "$commit_hash"; then + echo "Error: Last commit ($commit_hash) is not signed." + exit 1 + fi +} + +# Verify the signature of the last commit +verify_signature + +# Allow the push to proceed if the signature is valid +exit 0 From 6f259b72bca06721b402913caefcd183d082ea84 Mon Sep 17 00:00:00 2001 From: Einherjar Date: Mon, 18 Sep 2023 05:45:19 -0300 Subject: [PATCH 5/6] ci: add `cog.toml` for cocogitto `ignore_merge_commits` set to `true` will ignore `Merge ...` like in 59fc1b3. --- cog.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 cog.toml diff --git a/cog.toml b/cog.toml new file mode 100644 index 000000000..ff35ebd0b --- /dev/null +++ b/cog.toml @@ -0,0 +1 @@ +ignore_merge_commits = true From 9e99fee3f404e587c6a8642769167485fe7ac05c Mon Sep 17 00:00:00 2001 From: Einherjar Date: Thu, 21 Sep 2023 05:25:49 -0300 Subject: [PATCH 6/6] fix: exempt `Merge ...` from conventional commits --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fad5e4467..cf54d8ec1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,6 +62,8 @@ Commits should cover both the issue fixed and the solution's rationale. These [guidelines](https://chris.beams.io/posts/git-commit/) should be kept in mind. Commit messages should follow the ["Conventional Commits 1.0.0"](https://www.conventionalcommits.org/en/v1.0.0/) to make commit histories easier to read by humans and automated tools. +Commits starting with `Merge ...` which GitHub automatically generates +are exempt from this rule. You can use tools like [`cocogitto`](https://github.com/cocogitto/cocogitto) to check if your commit messages follow the convention.