Files
rust-vmm-ci/integration_tests/test_commit_format.py
Catalin Dumitru 7693628035 Update commit format test to work locally
Set default values for the remote name and
base branch when the test is run locally and
the Buildkite variables are not available and
the variables BASE_BRANCH and REMOTE are not set.

Signed-off-by: Catalin Dumitru <catdum@amazon.com>
2021-07-21 15:59:49 +03:00

93 lines
3.6 KiB
Python

# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Test the commit message format.
This test works properly on the local machine only when the environment
variables BASE_BRANCH and REMOTE are set. Otherwise the default values
are "master" for the name of the base branch and "origin" for the
remote name of the upstream repository, and this test may not work as
expected.
"""
import os
import subprocess
from utils import get_cmd_output
COMMIT_TITLE_MAX_LEN = 50
COMMIT_BODY_LINE_MAX_LEN = 72
BASE_BRANCH = \
os.environ.get('BUILDKITE_PULL_REQUEST_BASE_BRANCH') or \
os.environ.get('BASE_BRANCH') or \
"master"
REMOTE = \
os.environ.get('BUILDKITE_REPO') or \
os.environ.get('REMOTE') or \
"origin"
def test_commit_format():
"""
Checks commit message format for the current PR's commits.
Checks if commit messages follow the 50/72 git commit rule
[https://www.midori-global.com/blog/2018/04/02/git-50-72-rule]
and if commits are signed.
"""
# Fetch the upstream repository.
fetch_base_cmd = "git fetch {} {}".format(REMOTE, BASE_BRANCH)
try:
subprocess.run(fetch_base_cmd, shell=True, check=True)
except subprocess.CalledProcessError:
raise NameError(
"The name of the base branch or remote is invalid. "
"See test documentation for more details."
) from None
# Get hashes of PR's commits in their abbreviated form for
# a prettier printing.
shas_cmd = "git log --no-merges --pretty=%h --no-decorate " \
"FETCH_HEAD..HEAD"
shas = get_cmd_output(shas_cmd)
for sha in shas.split():
# Do not enforce the commit rules when the committer is dependabot.
author_cmd = "git show -s --format='%ae' " + sha
author = get_cmd_output(author_cmd)
if "dependabot" in author:
continue
message_cmd = "git show --pretty=format:%B -s " + sha
message = get_cmd_output(message_cmd)
message_lines = message.split("\n")
assert len(message_lines) >= 3,\
"The commit '{}' should contain at least 3 lines: title, " \
"blank line and a sign-off one. Please check: " \
"https://www.midori-global.com/blog/2018/04/02/git-50-72-rule."\
.format(sha)
title = message_lines[0]
assert message_lines[1] == "",\
"For commit '{}', title is divided into multiple lines. " \
"Please keep it one line long and make sure you add a blank " \
"line between title and description.".format(sha)
assert len(title) <= COMMIT_TITLE_MAX_LEN,\
"For commit '{}', title exceeds {} chars. " \
"Please keep it shorter.".format(sha, COMMIT_TITLE_MAX_LEN)
found_signed_off = False
for line in message_lines[2:]:
if line.startswith("Signed-off-by: "):
found_signed_off = True
# If we found `Signed-off-by` line, then it means
# the commit message ended and we don't want to check
# line lengths anymore for the current commit.
break
assert len(line) <= COMMIT_BODY_LINE_MAX_LEN,\
"For commit '{}', message line '{}' exceeds {} chars. " \
"Please keep it shorter or split it in " \
"multiple lines.".format(sha, line,
COMMIT_BODY_LINE_MAX_LEN)
assert found_signed_off, "Commit '{}' is not signed. " \
"Please run 'git commit -s --amend' " \
"on it.".format(sha)