Sample test module for validating the commits messages on a PR branch
import re | |
import subprocess | |
import pytest | |
@pytest.mark.parametrize( | |
"subject, error_msg", | |
[ | |
("WIP: working on something", "is a WIP commit"), | |
("WIP", "is a WIP commit"), | |
("fixup! some other commit", "is a fix-up commit"), | |
("Do the thing.", "ends with a period"), | |
("do the thing", "isn't capitalised"), | |
( | |
"Do the things and include information that should really be in the commit body", | |
"is too long", | |
), | |
], | |
) | |
def test_commit_subject_validity(subject, error_msg): | |
is_valid, _ = _is_commit_subject_valid(subject) | |
assert is_valid is False, f"'{subject}' {error_msg}" | |
def _is_commit_subject_valid(subject): | |
""" | |
Test if a commit subject is valid. | |
See https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html | |
""" | |
if re.match(r"^wip([ :]|$)", subject.lower()): | |
return False, "WIP commits should be rebased" | |
if re.match(r"^fixup!", subject.lower()): | |
return False, "Fix-up commits should be rebased" | |
if re.search(r"\.$", subject): | |
return False, "Commit subject should not end with a period" | |
if re.search(r"^[a-z]", subject): | |
return False, "Commit subject should be capitalised" | |
max_length = 70 | |
if len(subject) > max_length: | |
return False, f"Commit subject should not be longer than {max_length} characters" | |
return True, "" | |
def _pr_commits(): | |
""" | |
Return a generator of commmit message SHAs and subjects for the commits in | |
this branch. | |
""" | |
# Need to run git fetch to ensure CircleCI's checkout of origin/master is up-to-date. | |
cmd = "git fetch" | |
subprocess.run(cmd.split(), capture_output=True) | |
# Grab the oneline summary of the new commits on this PR branch | |
cmd = "git log origin/master.. --oneline" | |
result = subprocess.run(cmd.split(), capture_output=True) | |
output = result.stdout.decode("utf-8") | |
for line in output.split("\n"): | |
parts = line.split(" ") | |
yield parts[0], " ".join(parts[1:]) | |
@pytest.mark.parametrize("sha,commit_subject", _pr_commits()) | |
def test_branch_commit_subject(sha, commit_subject): | |
is_valid, message = _is_commit_subject_valid(commit_subject) | |
if not is_valid: | |
pytest.fail(f"Commit {sha} '{commit_subject}' is invalid: {message}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment