Skip to content

Commit 4132c0d

Browse files
committed
feat: support add pull request comments
* add .pre-commit-config.yaml to format code
1 parent a64fe49 commit 4132c0d

File tree

5 files changed

+165
-38
lines changed

5 files changed

+165
-38
lines changed

.pre-commit-config.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# https://pre-commit.com/
2+
ci:
3+
autofix_commit_msg: 'ci: auto fixes from pre-commit.com hooks'
4+
autoupdate_commit_msg: 'ci: pre-commit autoupdate'
5+
6+
repos:
7+
- repo: https://github.com/pre-commit/pre-commit-hooks
8+
rev: v5.0.0
9+
hooks:
10+
- id: check-yaml
11+
- id: check-toml
12+
- id: end-of-file-fixer
13+
- id: trailing-whitespace
14+
- id: name-tests-test
15+
- id: requirements-txt-fixer
16+
- repo: https://github.com/psf/black-pre-commit-mirror
17+
rev: 24.10.0
18+
hooks:
19+
- id: black
20+
# FIXME: main.py:109: error: Item "None" of "str | None" has no attribute "split" [union-attr]
21+
# - repo: https://github.com/pre-commit/mirrors-mypy
22+
# rev: v1.12.0
23+
# hooks:
24+
# - id: mypy
25+
- repo: https://github.com/codespell-project/codespell
26+
rev: v2.3.0
27+
hooks:
28+
- id: codespell

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
commit-signoff: true
3535
dry-run: true
3636
job-summary: true
37+
pr-comments: true
3738
```
3839
3940
## Optional Inputs
@@ -72,14 +73,19 @@ jobs:
7273

7374
### `job-summary`
7475

75-
- **Description**: display job summary to a workflow run
76+
- **Description**: display job summary to the workflow run
77+
- Default: 'true'
78+
79+
### `pr-comments`
80+
81+
- **Description**: post results to the pull request comments
7682
- Default: 'true'
7783

7884
Note: the default rule of above inputs is following [this configuration](https://github.com/commit-check/commit-check/blob/main/.commit-check.yml), if you want to customize just add your `.commit-check.yml` config file under your repository root directory.
7985

8086
## GitHub Action job summary
8187

82-
By default, commit-check-action results are shown on the job summary page of the workflow.
88+
By default, commit-check-action results are shown on the job summary page of the workflow.
8389

8490
### Success job summary
8591

action.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ inputs:
3030
required: false
3131
default: false
3232
job-summary:
33-
description: add a job summary
33+
description: display job summary to the workflow run
3434
required: false
3535
default: true
36+
pr-comments:
37+
description: post results to the pull request comments
38+
required: false
39+
default: false
3640
runs:
3741
using: "composite"
3842
steps:
@@ -55,3 +59,4 @@ runs:
5559
COMMIT_SIGNOFF: ${{ inputs.commit-signoff }}
5660
DRY_RUN: ${{ inputs.dry-run }}
5761
JOB_SUMMARY: ${{ inputs.job-summary }}
62+
PR_COMMENTS: ${{ inputs.pr-comments }}

main.py

Lines changed: 121 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,145 @@
33
import sys
44
import subprocess
55
import re
6+
from github import Github
7+
8+
9+
# Constants for message titles
10+
SUCCESS_TITLE = "### Commit-Check ✔️\n"
11+
FAILURE_TITLE = "### Commit-Check ❌\n"
12+
13+
# Environment variables
14+
MESSAGE = os.getenv("MESSAGE", "false")
15+
BRANCH = os.getenv("BRANCH", "false")
16+
AUTHOR_NAME = os.getenv("AUTHOR_NAME", "false")
17+
AUTHOR_EMAIL = os.getenv("AUTHOR_EMAIL", "false")
18+
COMMIT_SIGNOFF = os.getenv("COMMIT_SIGNOFF", "false")
19+
DRY_RUN = os.getenv("DRY_RUN", "false")
20+
JOB_SUMMARY = os.getenv("JOB_SUMMARY", "false")
21+
PR_COMMENTS = os.getenv("PR_COMMENTS", "false")
22+
GITHUB_STEP_SUMMARY = os.environ["GITHUB_STEP_SUMMARY"]
23+
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
24+
GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
25+
GITHUB_REF = os.getenv("GITHUB_REF")
26+
27+
28+
def log_env_vars():
29+
"""Logs the environment variables for debugging purposes."""
30+
print(f"MESSAGE = {MESSAGE}")
31+
print(f"BRANCH = {BRANCH}")
32+
print(f"AUTHOR_NAME = {AUTHOR_NAME}")
33+
print(f"AUTHOR_EMAIL = {AUTHOR_EMAIL}")
34+
print(f"COMMIT_SIGNOFF = {COMMIT_SIGNOFF}")
35+
print(f"DRY_RUN = {DRY_RUN}")
36+
print(f"JOB_SUMMARY = {JOB_SUMMARY}")
37+
print(f"PR_COMMENTS = {PR_COMMENTS}\n")
638

739

840
def run_commit_check() -> int:
9-
args = ["--message", "--branch", "--author-name", "--author-email", "--commit-signoff"]
10-
args = [arg for arg, value in zip(args, [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF]) if value == "true"]
41+
"""Runs the commit-check command and logs the result."""
42+
args = [
43+
"--message",
44+
"--branch",
45+
"--author-name",
46+
"--author-email",
47+
"--commit-signoff",
48+
]
49+
args = [
50+
arg
51+
for arg, value in zip(
52+
args, [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF]
53+
)
54+
if value == "true"
55+
]
1156

1257
command = ["commit-check"] + args
1358
print(" ".join(command))
1459
with open("result.txt", "w") as result_file:
15-
result = subprocess.run(command, stdout=result_file, stderr=subprocess.PIPE, check=False)
60+
result = subprocess.run(
61+
command, stdout=result_file, stderr=subprocess.PIPE, check=False
62+
)
1663
return result.returncode
1764

1865

66+
def read_result_file() -> str | None:
67+
"""Reads the result.txt file and removes ANSI color codes."""
68+
if os.path.getsize("result.txt") > 0:
69+
with open("result.txt", "r") as result_file:
70+
result_text = re.sub(
71+
r"\x1B\[[0-9;]*[a-zA-Z]", "", result_file.read()
72+
) # Remove ANSI colors
73+
return result_text
74+
return None
75+
76+
1977
def add_job_summary() -> int:
78+
"""Adds the commit check result to the GitHub job summary."""
2079
if JOB_SUMMARY == "false":
21-
sys.exit()
80+
return 0
2281

23-
if os.path.getsize("result.txt") > 0:
24-
with open("result.txt", "r") as result_file:
25-
result_text = re.sub(r'\x1B\[[0-9;]*[a-zA-Z]', '', result_file.read()) # Remove ANSI colors
82+
result_text = read_result_file()
2683

27-
with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
28-
summary_file.write("### Commit-Check ❌\n```\n")
29-
summary_file.write(result_text)
30-
summary_file.write("```")
31-
return 1
32-
else:
33-
with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
34-
summary_file.write("### Commit-Check ✔️\n")
84+
summary_content = (
85+
SUCCESS_TITLE
86+
if result_text is None
87+
else f"{FAILURE_TITLE}```\n{result_text}\n```"
88+
)
89+
90+
with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
91+
summary_file.write(summary_content)
92+
93+
return 0 if result_text is None else 1
94+
95+
96+
def add_pr_comments() -> int:
97+
"""Posts the commit check result as a comment on the pull request."""
98+
if (
99+
PR_COMMENTS == "false"
100+
or not GITHUB_TOKEN
101+
or not GITHUB_REPOSITORY
102+
or not GITHUB_REF
103+
):
35104
return 0
36105

106+
try:
107+
token = os.getenv("GITHUB_TOKEN")
108+
repo_name = os.getenv("GITHUB_REPOSITORY")
109+
pr_number = os.getenv("GITHUB_REF").split("/")[-2]
37110

38-
MESSAGE = os.getenv("MESSAGE", "false")
39-
BRANCH = os.getenv("BRANCH", "false")
40-
AUTHOR_NAME = os.getenv("AUTHOR_NAME", "false")
41-
AUTHOR_EMAIL = os.getenv("AUTHOR_EMAIL", "false")
42-
COMMIT_SIGNOFF = os.getenv("COMMIT_SIGNOFF", "false")
43-
DRY_RUN = os.getenv("DRY_RUN", "false")
44-
JOB_SUMMARY = os.getenv("JOB_SUMMARY", "false")
45-
GITHUB_STEP_SUMMARY = os.environ["GITHUB_STEP_SUMMARY"]
111+
# Initialize GitHub client
112+
g = Github(token)
113+
repo = g.get_repo(repo_name)
114+
issue = repo.get_issue(int(pr_number))
115+
116+
# Prepare comment content
117+
result_text = read_result_file()
118+
pr_comments = (
119+
SUCCESS_TITLE
120+
if result_text is None
121+
else f"{FAILURE_TITLE}```\n{result_text}\n```"
122+
)
123+
124+
issue.create_comment(body=pr_comments)
125+
return 0 if result_text is None else 1
126+
except Exception as e:
127+
print(f"Error posting PR comment: {e}", file=sys.stderr)
128+
return 1
129+
130+
131+
def main():
132+
"""Main function to run commit-check, add job summary and post PR comments."""
133+
log_env_vars()
134+
135+
# Combine return codes
136+
ret_code = run_commit_check()
137+
ret_code += add_job_summary()
138+
ret_code += add_pr_comments()
46139

47-
print(f"MESSAGE = {MESSAGE}")
48-
print(f"BRANCH = {BRANCH}")
49-
print(f"AUTHOR_NAME = {AUTHOR_NAME}")
50-
print(f"AUTHOR_EMAIL = {AUTHOR_EMAIL}")
51-
print(f"COMMIT_SIGNOFF = {COMMIT_SIGNOFF}")
52-
print(f"DRY_RUN = {DRY_RUN}")
53-
print(f"JOB_SUMMARY = {JOB_SUMMARY}\n")
140+
if DRY_RUN == "true":
141+
ret_code = 0
54142

55-
ret_code = run_commit_check()
56-
ret_code += add_job_summary() # Combine return codes
143+
sys.exit(ret_code)
57144

58-
if DRY_RUN == "true":
59-
ret_code = 0
60145

61-
sys.exit(ret_code)
146+
if __name__ == "__main__":
147+
main()

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Install commit-check CLI
22
# For details please see: https://github.com/commit-check/commit-check
33
commit-check==0.8.3
4+
# Interact with the GitHub API.
5+
PyGithub=v2.4.0

0 commit comments

Comments
 (0)