diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 672c027..41aebbe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,15 @@ stages: - check - deploy +commitcheck: + image: "python" + stage: check + variables: + GIT_STRATEGY: clone + script: + # only run for merge requests + - if [ -z "$CI_MERGE_REQUEST_TITLTE" ]; then true; else python ./dist/tagging/check_conventional_commit.py "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"; fi + cargo:fmtcheck: image: "rust:slim" stage: check diff --git a/dist/tagging/check_conventional_commit.py b/dist/tagging/check_conventional_commit.py new file mode 100755 index 0000000..5ac2e3d --- /dev/null +++ b/dist/tagging/check_conventional_commit.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +from subprocess import Popen, PIPE +from typing import List +from sys import argv, stderr +import re + + +CONVENTIONAL_COMMIT_RE = re.compile(r"(feat|fix|chore)(\([\w_\-\/ ]+\))?: .+") + + +def eprint(*args, **kwargs): + print(*args, file=stderr, **kwargs) + + +def cmd(args: List[str]) -> List[str]: + proc = Popen(args, stdout=PIPE) + (stdout, _) = proc.communicate() + retcode = proc.returncode + if retcode != 0: + raise ValueError(f"Command {" ".join(args)} failed with code {retcode}") + return stdout.decode().splitlines() + + +if __name__ == "__main__": + target_branch = argv[1] + if target_branch is None: + eprint(f"Usage: {argv[0]} CURRENT_COMMIT TARGET_BRANCH") + exit(1) + cmd(["git", "fetch", "origin", f"{target_branch}:{target_branch}"]) + cmsgs = cmd(["git", "show", "-s", "--format=%s", f"{target_branch}..HEAD"]) + success = True + for cmsg in cmsgs: + if CONVENTIONAL_COMMIT_RE.match(cmsg) is None: + eprint(f"Error: commit message '{cmsg}' does not follow the conventional commit standard") + if not success: + exit(1)