Skip to content

Support posting pull request comments #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 22, 2024
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
12 changes: 6 additions & 6 deletions .commit-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ checks:
[optional body]\n
[optional footer(s)]\n\n
More details please refer to https://www.conventionalcommits.org"
suggest: git commit --amend --no-verify
suggest: please check your commit message whether matches above regex

- check: branch
regex: ^(bugfix|feature|release|hotfix|task|dependabot)\/.+|(master)|(main)|(HEAD)|(PR-.+)
error: "Branches must begin with these types: bugfix/ feature/ release/ hotfix/ task/"
suggest: git checkout -b type/branch_name
regex: ^(bugfix|feature|release|hotfix|task|chore)\/.+|(master)|(main)|(HEAD)|(PR-.+)
error: "Branches must begin with these types: bugfix/ feature/ release/ hotfix/ task/ chore/"
suggest: run command `git checkout -b type/branch_name`

- check: author_name
regex: ^[A-Za-z ,.\'-]+$|.*(\[bot])
error: The committer name seems invalid
suggest: git config user.name "Peter Shen"
suggest: run command `git config user.name "Your Name"`

- check: author_email
regex: ^\S+@\S+\.\S+$
error: The committer email seems invalid
suggest: git config user.email petershen@example.com
suggest: run command `git config user.email yourname@example.com`
3 changes: 3 additions & 0 deletions .github/workflows/commit-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: ./ # self test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # used by `pr-comments`
with:
message: true
branch: true
author-name: true
author-email: true
commit-signoff: true
job-summary: true
pr-comments: true
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# https://pre-commit.com/
ci:
autofix_commit_msg: 'ci: auto fixes from pre-commit.com hooks'
autoupdate_commit_msg: 'ci: pre-commit autoupdate'

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: name-tests-test
- id: requirements-txt-fixer
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.10.0
hooks:
- id: black
# FIXME: main.py:109: error: Item "None" of "str | None" has no attribute "split" [union-attr]
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: v1.12.0
# hooks:
# - id: mypy
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }} # Checkout PR HEAD commit
- uses: commit-check/commit-check-action@v1
with:
message: true
Expand All @@ -34,6 +36,7 @@ jobs:
commit-signoff: true
dry-run: true
job-summary: true
pr-comments: true
```

## Optional Inputs
Expand Down Expand Up @@ -72,22 +75,41 @@ jobs:

### `job-summary`

- **Description**: display job summary to a workflow run
- **Description**: display job summary to the workflow run
- Default: 'true'

### `pr-comments`

- **Description**: post results to the pull request comments
- Default: 'true'

> [!IMPORTANT]
> This is a experimental feature
> use it you need to set `GITHUB_TOKEN` in the GitHub Action.

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.

## GitHub Action job summary

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

### Success job summary

![Success job summary](https://github.com/commit-check/.github/blob/main/screenshot/success-summary.png)
![Success job summary](https://github.com/commit-check/.github/blob/main/screenshot/success-job-summary.png)

### Failure job summary

![Failure job summary](https://github.com/commit-check/.github/blob/main/screenshot/failure-summary.png)
![Failure job summary](https://github.com/commit-check/.github/blob/main/screenshot/failure-job-summary.png)

## GitHub Pull Request comments

### Success pull request comment

![Success pull request comment](https://github.com/commit-check/.github/blob/main/screenshot/success-pr-comments.png)

### Failure pull request comment

![Failure pull request comment](https://github.com/commit-check/.github/blob/main/screenshot/failure-pr-comments.png)

## Badging your repository

Expand Down
7 changes: 6 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ inputs:
required: false
default: false
job-summary:
description: add a job summary
description: display job summary to the workflow run
required: false
default: true
pr-comments:
description: post results to the pull request comments
required: false
default: true
runs:
Expand All @@ -55,3 +59,4 @@ runs:
COMMIT_SIGNOFF: ${{ inputs.commit-signoff }}
DRY_RUN: ${{ inputs.dry-run }}
JOB_SUMMARY: ${{ inputs.job-summary }}
PR_COMMENTS: ${{ inputs.pr-comments }}
182 changes: 147 additions & 35 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,171 @@
import sys
import subprocess
import re
from github import Github


# Constants for message titles
SUCCESS_TITLE = "# Commit-Check ✔️"
FAILURE_TITLE = "# Commit-Check ❌"

# Environment variables
MESSAGE = os.getenv("MESSAGE", "false")
BRANCH = os.getenv("BRANCH", "false")
AUTHOR_NAME = os.getenv("AUTHOR_NAME", "false")
AUTHOR_EMAIL = os.getenv("AUTHOR_EMAIL", "false")
COMMIT_SIGNOFF = os.getenv("COMMIT_SIGNOFF", "false")
DRY_RUN = os.getenv("DRY_RUN", "false")
JOB_SUMMARY = os.getenv("JOB_SUMMARY", "false")
PR_COMMENTS = os.getenv("PR_COMMENTS", "false")
GITHUB_STEP_SUMMARY = os.environ["GITHUB_STEP_SUMMARY"]
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY")
GITHUB_REF = os.getenv("GITHUB_REF")


def log_env_vars():
"""Logs the environment variables for debugging purposes."""
print(f"MESSAGE = {MESSAGE}")
print(f"BRANCH = {BRANCH}")
print(f"AUTHOR_NAME = {AUTHOR_NAME}")
print(f"AUTHOR_EMAIL = {AUTHOR_EMAIL}")
print(f"COMMIT_SIGNOFF = {COMMIT_SIGNOFF}")
print(f"DRY_RUN = {DRY_RUN}")
print(f"JOB_SUMMARY = {JOB_SUMMARY}")
print(f"PR_COMMENTS = {PR_COMMENTS}\n")


def run_commit_check() -> int:
args = ["--message", "--branch", "--author-name", "--author-email", "--commit-signoff"]
args = [arg for arg, value in zip(args, [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF]) if value == "true"]
"""Runs the commit-check command and logs the result."""
args = [
"--message",
"--branch",
"--author-name",
"--author-email",
"--commit-signoff",
]
args = [
arg
for arg, value in zip(
args, [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF]
)
if value == "true"
]

command = ["commit-check"] + args
print(" ".join(command))
with open("result.txt", "w") as result_file:
result = subprocess.run(command, stdout=result_file, stderr=subprocess.PIPE, check=False)
result = subprocess.run(
command, stdout=result_file, stderr=subprocess.PIPE, check=False
)
return result.returncode


def read_result_file() -> str | None:
"""Reads the result.txt file and removes ANSI color codes."""
if os.path.getsize("result.txt") > 0:
with open("result.txt", "r") as result_file:
result_text = re.sub(
r"\x1B\[[0-9;]*[a-zA-Z]", "", result_file.read()
) # Remove ANSI colors
return result_text.rstrip()
return None


def add_job_summary() -> int:
"""Adds the commit check result to the GitHub job summary."""
if JOB_SUMMARY == "false":
sys.exit()
return 0

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

with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
summary_file.write("### Commit-Check ❌\n```\n")
summary_file.write(result_text)
summary_file.write("```")
return 1
else:
with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
summary_file.write("### Commit-Check ✔️\n")
summary_content = (
SUCCESS_TITLE
if result_text is None
else f"{FAILURE_TITLE}\n```\n{result_text}\n```"
)

with open(GITHUB_STEP_SUMMARY, "a") as summary_file:
summary_file.write(summary_content)

return 0 if result_text is None else 1


def add_pr_comments() -> int:
"""Posts the commit check result as a comment on the pull request."""
if PR_COMMENTS == "false":
return 0

try:
token = os.getenv("GITHUB_TOKEN")
repo_name = os.getenv("GITHUB_REPOSITORY")
pr_number = os.getenv("GITHUB_REF").split("/")[-2]

MESSAGE = os.getenv("MESSAGE", "false")
BRANCH = os.getenv("BRANCH", "false")
AUTHOR_NAME = os.getenv("AUTHOR_NAME", "false")
AUTHOR_EMAIL = os.getenv("AUTHOR_EMAIL", "false")
COMMIT_SIGNOFF = os.getenv("COMMIT_SIGNOFF", "false")
DRY_RUN = os.getenv("DRY_RUN", "false")
JOB_SUMMARY = os.getenv("JOB_SUMMARY", "false")
GITHUB_STEP_SUMMARY = os.environ["GITHUB_STEP_SUMMARY"]
# Initialize GitHub client
g = Github(token)
repo = g.get_repo(repo_name)
pull_request = repo.get_issue(int(pr_number))

# Prepare comment content
result_text = read_result_file()
pr_comments = (
SUCCESS_TITLE
if result_text is None
else f"{FAILURE_TITLE}\n```\n{result_text}\n```"
)

# Fetch all existing comments on the PR
comments = pull_request.get_comments()

# Track if we found a matching comment
matching_comments = []
last_comment = None

for comment in comments:
if comment.body.startswith(SUCCESS_TITLE) or comment.body.startswith(
FAILURE_TITLE
):
matching_comments.append(comment)
if matching_comments:
last_comment = matching_comments[-1]

if last_comment.body == pr_comments:
print(f"PR comment already up-to-date for PR #{pr_number}.")
return 0
else:
# If the last comment doesn't match, update it
print(f"Updating the last comment on PR #{pr_number}.")
last_comment.edit(pr_comments)

# Delete all older matching comments
for comment in matching_comments[:-1]:
print(f"Deleting an old comment on PR #{pr_number}.")
comment.delete()
else:
# No matching comments, create a new one
print(f"Creating a new comment on PR #{pr_number}.")
pull_request.create_comment(body=pr_comments)

return 0 if result_text is None else 1
except Exception as e:
print(f"Error posting PR comment: {e}", file=sys.stderr)
return 1


def main():
"""Main function to run commit-check, add job summary and post PR comments."""
log_env_vars()

# Combine return codes
ret_code = run_commit_check()
ret_code += add_job_summary()
ret_code += add_pr_comments()

print(f"MESSAGE = {MESSAGE}")
print(f"BRANCH = {BRANCH}")
print(f"AUTHOR_NAME = {AUTHOR_NAME}")
print(f"AUTHOR_EMAIL = {AUTHOR_EMAIL}")
print(f"COMMIT_SIGNOFF = {COMMIT_SIGNOFF}")
print(f"DRY_RUN = {DRY_RUN}")
print(f"JOB_SUMMARY = {JOB_SUMMARY}\n")
if DRY_RUN == "true":
ret_code = 0

ret_code = run_commit_check()
ret_code += add_job_summary() # Combine return codes
sys.exit(ret_code)

if DRY_RUN == "true":
ret_code = 0

sys.exit(ret_code)
if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Install commit-check CLI
# For details please see: https://github.com/commit-check/commit-check
commit-check==0.8.3
# Interact with the GitHub API.
PyGithub==2.4.0