diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 000000000..34e382aad --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,40 @@ +{ + "extends": [ + "@commitlint/config-conventional" + ], + "rules": { + "type-enum": [ + 2, + "always", + [ + "build", + "chore", + "ci", + "docs", + "feat", + "fix", + "perf", + "refactor", + "revert", + "security", + "style", + "test" + ] + ], + "subject-case": [ + 2, + "always", + [ + "sentence-case", + "start-case", + "pascal-case", + "upper-case" + ] + ], + "header-max-length": [ + 2, + "always", + 120 + ] + } +} diff --git a/.github/workflows/compliance.yaml b/.github/workflows/compliance.yaml new file mode 100644 index 000000000..e7a6d003a --- /dev/null +++ b/.github/workflows/compliance.yaml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2026 Institute for Automation of Complex Power Systems, RWTH Aachen University +# SPDX-License-Identifier: Apache-2.0 + +name: Compliance checks + +on: + pull_request: + branches: [master, main] + +permissions: + contents: read + +jobs: + conventional-commits: + name: Conventional commit messages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v5 + with: + node-version: "20" + + - name: Install commitlint + run: npm install --no-save @commitlint/cli @commitlint/config-conventional + + # The merge commit takes the PR title, so that is what Release Please reads. + - name: Fail if the pull request title is not a conventional commit + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + if ! printf '%s\n' "$PR_TITLE" | npx commitlint --verbose; then + echo "" + echo "The pull request title becomes the merge commit subject on master." + echo "Use a conventional commit subject, for example:" + echo "" + echo " fix: Coding style" + echo "" + exit 1 + fi + + - name: Fail if a commit in this branch is not a conventional commit + run: | + BASE=${{ github.event.pull_request.base.sha }} + HEAD=${{ github.event.pull_request.head.sha }} + if ! npx commitlint --from "$BASE" --to "$HEAD" --verbose; then + echo "" + echo "Rewrite the offending commit messages, then force-push:" + echo "" + echo " git rebase -i $BASE" + echo " git push --force-with-lease" + echo "" + echo "Or install the pre-commit hooks (see CONTRIBUTING.md) to catch this locally." + exit 1 + fi diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 185b72f13..6d8939d29 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,10 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks + +# commitlint runs at commit-msg, so plain `pre-commit install` must wire that stage too. +default_install_hook_types: [pre-commit, commit-msg] + repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -73,6 +77,13 @@ repos: hooks: - id: reuse-lint-file + - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook + rev: "v9.26.0" + hooks: + - id: commitlint + stages: [commit-msg] + additional_dependencies: ["@commitlint/config-conventional@19.8.1"] + - repo: local hooks: - id: dco-hook