From abd2c90d9f428de611b6ba81219c78d9f6f8d2c5 Mon Sep 17 00:00:00 2001 From: Laura Loghin Date: Mon, 20 Jul 2020 17:33:45 +0300 Subject: [PATCH] Add test for commit message format Added test that checks if commits follow the 50/72 git commit rule and if they are signed (git commit -s). Fixes: #9, #14. Signed-off-by: Laura Loghin --- .buildkite/pipeline.yml | 13 ++++++ integration_tests/test_commit_format.py | 62 +++++++++++++++++++++++++ integration_tests/test_coverage.py | 1 + integration_tests/utils.py | 10 ++++ 4 files changed, 86 insertions(+) create mode 100644 integration_tests/test_commit_format.py diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 00cf5dc..25c15ee 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -190,3 +190,16 @@ steps: privileged: true image: "rustvmm/dev:v6" always-pull: true + + - label: "commit-format" + commands: + - pytest rust-vmm-ci/integration_tests/test_commit_format.py + retry: + automatic: false + agents: + os: linux + plugins: + - docker#v3.0.1: + image: "rustvmm/dev:v6" + always-pull: true + propagate-environment: true diff --git a/integration_tests/test_commit_format.py b/integration_tests/test_commit_format.py new file mode 100644 index 0000000..f7195d8 --- /dev/null +++ b/integration_tests/test_commit_format.py @@ -0,0 +1,62 @@ +# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Test the commit message format.""" + +import os + +from utils import get_cmd_output + +COMMIT_TITLE_MAX_LEN = 50 +COMMIT_BODY_LINE_MAX_LEN = 72 +BASE_BRANCH = os.environ['BUILDKITE_PULL_REQUEST_BASE_BRANCH'] + + +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. + """ + # Get hashes of PR's commits in their abbreviated form for + # a prettier printing. + shas_cmd = "git log --no-merges --pretty=%h --no-decorate " \ + "{}..HEAD".format(BASE_BRANCH) + shas = get_cmd_output(shas_cmd) + + for sha in shas.split(): + 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." + title = message_lines[0] + assert message_lines[1] == "", "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." + 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) diff --git a/integration_tests/test_coverage.py b/integration_tests/test_coverage.py index a932be2..f9ec26b 100644 --- a/integration_tests/test_coverage.py +++ b/integration_tests/test_coverage.py @@ -13,6 +13,7 @@ if platform.machine() == "x86_64": elif platform.machine() == "aarch64": COVERAGE_CONFIG_PATH = os.path.join(REPO_ROOT_PATH, "coverage_config_aarch64.json") + def _read_test_config(): """ Reads the config of the coverage for the repository being tested. diff --git a/integration_tests/utils.py b/integration_tests/utils.py index 1e50257..85043c2 100644 --- a/integration_tests/utils.py +++ b/integration_tests/utils.py @@ -1,6 +1,8 @@ # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 + import os +import subprocess def get_repo_root_path(): @@ -9,3 +11,11 @@ def get_repo_root_path(): rust_vmm_ci_path = os.path.dirname(integration_tests_path) return os.path.dirname(rust_vmm_ci_path) + + +def get_cmd_output(cmd): + """Returns stdout content of `cmd` command.""" + cmd_out = subprocess.run(cmd, shell=True, check=True, + stdout=subprocess.PIPE) + stdout = cmd_out.stdout.decode('utf-8') + return stdout