Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 68 additions & 58 deletions .ci/scripts/validate_commit_message.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,66 +1,31 @@
# WARNING: DO NOT EDIT!
#
# This file was generated by plugin_template, and is managed by it. Please use
# './plugin-template --github pulp_npm' to update this file.
#
# For more info visit https://github.com/pulp/plugin_template
# This file is managed by the plugin template.
# Do not edit.

import os
import re
import subprocess
import sys
import tomllib
import yaml
from pathlib import Path

from github import Github

with open("pyproject.toml", "rb") as fp:
PYPROJECT_TOML = tomllib.load(fp)
KEYWORDS = ["fixes", "closes"]
BLOCKING_REGEX = [
r"^DRAFT",
r"^WIP",
r"^NOMERGE",
r"^DO\s*NOT\s*MERGE",
r"^EXPERIMENT",
r"^FIXUP",
r"^fixup!", # This is created by 'git commit --fixup'
r"Apply suggestions from code review", # This usually comes from GitHub
]
try:
CHANGELOG_EXTS = [
f".{item['directory']}" for item in PYPROJECT_TOML["tool"]["towncrier"]["type"]
]
except KeyError:
CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc"]
NOISSUE_MARKER = "[noissue]"

sha = sys.argv[1]
message = subprocess.check_output(["git", "log", "--format=%B", "-n 1", sha]).decode("utf-8")

if NOISSUE_MARKER in message:
sys.exit(f"Do not add '{NOISSUE_MARKER}' in the commit message.")

blocking_matches = [m for m in (re.match(pattern, message) for pattern in BLOCKING_REGEX) if m]
if blocking_matches:
print("Found these phrases in the commit message:")
for m in blocking_matches:
print(" - " + m.group(0))
sys.exit("This PR is not ready for consumption.")

g = Github(os.environ.get("GITHUB_TOKEN"))
repo = g.get_repo("pulp/pulp_npm")


def check_status(issue):
def check_status(issue, repo, cherry_pick):
gi = repo.get_issue(int(issue))
if gi.pull_request:
sys.exit(f"Error: issue #{issue} is a pull request.")
if gi.closed_at:
if gi.closed_at and not cherry_pick:
print("Make sure to use 'git cherry-pick -x' when backporting a change.")
print(
"If a backport of a change requires a significant amount of rewriting, "
"consider creating a new issue."
)
sys.exit(f"Error: issue #{issue} is closed.")


def check_changelog(issue):
def check_changelog(issue, CHANGELOG_EXTS):
matches = list(Path("CHANGES").rglob(f"{issue}.*"))

if len(matches) < 1:
Expand All @@ -70,18 +35,63 @@ def check_changelog(issue):
sys.exit(f"Invalid extension for changelog entry '{match}'.")


print("Checking commit message for {sha}.".format(sha=sha[0:7]))
def main() -> None:
TEMPLATE_CONFIG = yaml.safe_load(Path("template_config.yml").read_text())
GITHUB_ORG = TEMPLATE_CONFIG["github_org"]
PLUGIN_NAME = TEMPLATE_CONFIG["plugin_name"]

with Path("pyproject.toml").open("rb") as _fp:
PYPROJECT_TOML = tomllib.load(_fp)
KEYWORDS = ["fixes", "closes"]
BLOCKING_REGEX = [
r"^DRAFT",
r"^WIP",
r"^NOMERGE",
r"^DO\s*NOT\s*MERGE",
r"^EXPERIMENT",
r"^FIXUP",
r"^fixup!", # This is created by 'git commit --fixup'
r"Apply suggestions from code review", # This usually comes from GitHub
]
try:
CHANGELOG_EXTS = [
f".{item['directory']}" for item in PYPROJECT_TOML["tool"]["towncrier"]["type"]
]
except KeyError:
CHANGELOG_EXTS = [".feature", ".bugfix", ".doc", ".removal", ".misc"]
NOISSUE_MARKER = "[noissue]"

sha = sys.argv[1]
message = subprocess.check_output(["git", "log", "--format=%B", "-n 1", sha]).decode("utf-8")

if NOISSUE_MARKER in message:
sys.exit(f"Do not add '{NOISSUE_MARKER}' in the commit message.")

blocking_matches = [m for m in (re.match(pattern, message) for pattern in BLOCKING_REGEX) if m]
if blocking_matches:
print("Found these phrases in the commit message:")
for m in blocking_matches:
print(" - " + m.group(0))
sys.exit("This PR is not ready for consumption.")

g = Github(os.environ.get("GITHUB_TOKEN"))
repo = g.get_repo(f"{GITHUB_ORG}/{PLUGIN_NAME}")

print("Checking commit message for {sha}.".format(sha=sha[0:7]))

# validate the issue attached to the commit
issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords="|".join(KEYWORDS))
issues = re.findall(issue_regex, message, re.IGNORECASE)
cherry_pick_regex = r"^\s*\(cherry picked from commit [0-9a-f]*\)\s*$"
cherry_pick = re.search(cherry_pick_regex, message, re.MULTILINE)

if issues:
for issue in issues:
check_status(issue, repo, cherry_pick)
check_changelog(issue, CHANGELOG_EXTS)

# validate the issue attached to the commit
issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS))
issues = re.findall(issue_regex, message, re.IGNORECASE)
cherry_pick_regex = r"^\s*\(cherry picked from commit [0-9a-f]*\)\s*$"
cherry_pick = re.search(cherry_pick_regex, message, re.MULTILINE)
print("Commit message for {sha} passed.".format(sha=sha[0:7]))

if issues:
for issue in issues:
if not cherry_pick:
check_status(issue)
check_changelog(issue)

print("Commit message for {sha} passed.".format(sha=sha[0:7]))
if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: "Install python dependencies"
run: |
echo ::group::PYDEPS
pip install requests pygithub
pip install requests pygithub pyyaml
echo ::endgroup::
- name: "Check commit message"
if: github.event_name == 'pull_request'
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/scripts/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ echo "Checking for uncommitted migrations..."
cmd_user_prefix bash -c "django-admin makemigrations npm --check --dry-run"

# Run unit tests.
cmd_user_prefix bash -c "PULP_DATABASES__default__USER=postgres pytest -v -r sx --color=yes --suppress-no-test-exit-code -p no:pulpcore --pyargs pulp_npm.tests.unit"
cmd_user_prefix bash -c "PULP_DATABASES__default__USER=postgres pytest -v -r sx --color=yes --suppress-no-test-exit-code -p no:pulpcore --durations=20 --pyargs pulp_npm.tests.unit"
# Run functional tests
if [[ "$TEST" == "performance" ]]; then
if [[ -z ${PERFORMANCE_TEST+x} ]]; then
Expand All @@ -135,11 +135,11 @@ if [ -f "$FUNC_TEST_SCRIPT" ]; then
else
if [[ "$GITHUB_WORKFLOW" =~ "Nightly" ]]
then
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_npm.tests.functional -m parallel -n 8 --nightly"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_npm.tests.functional -m 'not parallel' --nightly"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --durations=20 --pyargs pulp_npm.tests.functional -m parallel -n 8 --nightly"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --durations=20 --pyargs pulp_npm.tests.functional -m 'not parallel' --nightly"
else
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_npm.tests.functional -m parallel -n 8"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --pyargs pulp_npm.tests.functional -m 'not parallel'"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --durations=20 --pyargs pulp_npm.tests.functional -m parallel -n 8"
cmd_user_prefix bash -c "pytest -v --timeout=300 -r sx --color=yes --suppress-no-test-exit-code --durations=20 --pyargs pulp_npm.tests.functional -m 'not parallel'"
fi
fi

Expand Down