diff --git a/.commit-check.yml b/.commit-check.yml index 7d5e579..f1f725f 100644 --- a/.commit-check.yml +++ b/.commit-check.yml @@ -15,7 +15,7 @@ checks: suggest: run command `git checkout -b type/branch_name` - check: author_name - regex: ^[A-Za-z ,.\'-]+$|.*(\[bot]) + regex: ^[A-Za-zÀ-ÖØ-öø-ÿ\u0100-\u017F\u0180-\u024F ,.\'-]+$|.*(\[bot]) error: The committer name seems invalid suggest: run command `git config user.name "Your Name"` @@ -23,3 +23,8 @@ checks: regex: ^.+@.+$ error: The committer email seems invalid suggest: run command `git config user.email yourname@example.com` + + - check: merge_base + regex: main # it can be master, develop, devel etc based on your project. + error: Current branch is not rebased onto target branch + suggest: please ensure your branch is rebased with the target branch diff --git a/.github/workflows/commit-check.yml b/.github/workflows/commit-check.yml index 7ee0be4..dc398fd 100644 --- a/.github/workflows/commit-check.yml +++ b/.github/workflows/commit-check.yml @@ -15,6 +15,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} # checkout PR HEAD commit + fetch-depth: 0 # fetch all history for all branches and tags - uses: ./ # self test env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # use GITHUB_TOKEN because of use pr-comments @@ -24,5 +25,6 @@ jobs: author-name: true author-email: true commit-signoff: true + merge-base: true job-summary: true pr-comments: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..7ee1b19 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,10 @@ +name: Run pre-commit + +on: + push: + pull_request: + types: opened + +jobs: + pre-commit: + uses: commit-check/.github/.github/workflows/pre-commit.yml@main diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b45ec09..571d5ee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,11 +17,10 @@ repos: 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/pre-commit/mirrors-mypy + rev: v1.12.0 + hooks: + - id: mypy - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: diff --git a/README.md b/README.md index e58e79c..9e9df7b 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,21 @@ [![Main](https://github.com/commit-check/commit-check-action/actions/workflows/main.yaml/badge.svg)](https://github.com/commit-check/commit-check-action/actions/workflows/main.yaml) [![Commit Check](https://github.com/commit-check/commit-check-action/actions/workflows/commit-check.yml/badge.svg)](https://github.com/commit-check/commit-check-action/actions/workflows/commit-check.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/commit-check/commit-check-action) -[![Used by](https://img.shields.io/static/v1?label=Used%20by&message=38&color=informational&logo=slickpic)](https://github.com/commit-check/commit-check-action/network/dependents) +[![Used by](https://img.shields.io/static/v1?label=Used%20by&message=67&color=informational&logo=slickpic)](https://github.com/commit-check/commit-check-action/network/dependents) [![GitHub marketplace](https://img.shields.io/badge/Marketplace-commit--check--action-blue)](https://github.com/marketplace/actions/commit-check-action) +[![slsa-badge](https://slsa.dev/images/gh-badge-level3.svg)](https://github.com/commit-check/commit-check-action/blob/a2873ca0482dd505c93fb51861c953e82fd0a186/action.yml#L59-L69) A Github Action for checking commit message formatting, branch naming, committer name, email, commit signoff and more. +## Table of Contents + +* [Usage](#usage) +* [Optional Inputs](#optional-inputs) +* [GitHub Action Job Summary](#github-action-job-summary) +* [GitHub Pull Request Comments](#github-pull-request-comments) +* [Badging Your Repository](#badging-your-repository) +* [Versioning](#versioning) + ## Usage Create a new GitHub Actions workflow in your project, e.g. at [.github/workflows/commit-check.yml](.github/workflows/commit-check.yml) @@ -30,6 +40,7 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} # checkout PR HEAD commit + fetch-depth: 0 # required for merge-base check - uses: commit-check/commit-check-action@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # use GITHUB_TOKEN because of use pr-comments @@ -39,84 +50,115 @@ jobs: author-name: true author-email: true commit-signoff: true + merge-base: false job-summary: true pr-comments: ${{ github.event_name == 'pull_request' }} ``` +## Used By + +

+ Apache + Apache   + discovery-unicamp + discovery-unicamp   + Texas Instruments + Texas Instruments   + OpenCADC + OpenCADC   + Extrawest + Extrawest + Chainlift + Chainlift   + Mila + Mila   + and many more. +

+ ## Optional Inputs ### `message` - **Description**: check commit message formatting convention. - By default the rule follows [conventional commits](https://www.conventionalcommits.org/). -- Default: 'true' +- Default: `true` ### `branch` - **Description**: check git branch naming convention. - - By default follow bitbucket [conventional branch](https://conventional-branch.github.io/). -- Default: 'true' + - By default the rule follows [conventional branch](https://conventional-branch.github.io/). +- Default: `true` ### `author-name` -- **Description**: check committer author name -- Default: 'true' +- **Description**: check committer author name. +- Default: `true` ### `author-email` -- **Description**: check committer author email -- Default: 'true' +- **Description**: check committer author email. +- Default: `true` ### `commit-signoff` -- **Description**: check committer commit signature -- Default: 'true' +- **Description**: check committer commit signature. +- Default: `true` + +### `merge-base` + +- **Description**: check current branch is rebased onto target branch. +- Default: `false` + +> [!IMPORTANT] +> `merge-base` is an experimental feature. by default it's disable. +> +> To use this feature, you need fetch all history for all branches by setting `fetch-depth: 0` in `actions/checkout`. ### `dry-run` - **Description**: run checks without failing. exit code is 0 otherwise is 1. -- Default: 'false' +- Default: `false` ### `job-summary` -- **Description**: display job summary to the workflow run -- Default: 'true' +- **Description**: display job summary to the workflow run. +- Default: `true` ### `pr-comments` -- **Description**: post results to the pull request comments -- Default: 'false' +- **Description**: post results to the pull request comments. +- Default: `false` > [!IMPORTANT] -> `pr-comments` is an experimental feature. To use it you need to set `GITHUB_TOKEN` in the GitHub Action. +> `pr-comments` is an experimental feature. by default it's disable. To use it you need to set `GITHUB_TOKEN` in the GitHub Action. > -> This feature currently doesn’t work with forked repositories. For more details, refer to issue [#77](https://github.com/commit-check/commit-check-action/issues/77) +> This feature currently doesn’t work with forked repositories. For more details, refer to issue [#77](https://github.com/commit-check/commit-check-action/issues/77). 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 +## GitHub Action Job Summary By default, commit-check-action results are shown on the job summary page of the workflow. -### Success job summary +### Success Job Summary ![Success job summary](https://github.com/commit-check/.github/blob/main/screenshot/success-job-summary.png) -### Failure job summary +### Failure Job Summary ![Failure job summary](https://github.com/commit-check/.github/blob/main/screenshot/failure-job-summary.png) -## GitHub Pull Request comments +## GitHub Pull Request Comments -### Success pull request comment +### 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 ![Failure pull request comment](https://github.com/commit-check/.github/blob/main/screenshot/failure-pr-comments.png) -## Badging your repository +## Badging Your Repository You can add a badge to your repository to show your contributors/users that you use commit-check! diff --git a/action.yml b/action.yml index 531acb4..cdd75ea 100644 --- a/action.yml +++ b/action.yml @@ -25,6 +25,10 @@ inputs: description: check committer commit signature required: false default: true + merge-base: + description: check current branch is rebased onto target branch + required: false + default: false dry-run: description: run checks without failing required: false @@ -47,9 +51,23 @@ runs: # https://github.com/pypa/setuptools/issues/3269 export DEB_PYTHON_INSTALL_LAYOUT=deb fi + + # Set up virtual environment python3 -m venv venv source venv/bin/activate - python3 -m pip install -r "$GITHUB_ACTION_PATH/requirements.txt" + + # Download artifact + python3 -m pip download -r "$GITHUB_ACTION_PATH/requirements.txt" + + # Verify artifact attestations + if ! gh attestation verify commit_check-*.whl -R commit-check/commit-check; then + echo "Artifact verification failed. Aborting installation." + exit 1 + fi + + # Install artifact + python3 -m pip install commit_check-*.whl PyGithub-*.whl + python3 "$GITHUB_ACTION_PATH/main.py" env: MESSAGE: ${{ inputs.message }} @@ -57,6 +75,7 @@ runs: AUTHOR_NAME: ${{ inputs.author-name }} AUTHOR_EMAIL: ${{ inputs.author-email }} COMMIT_SIGNOFF: ${{ inputs.commit-signoff }} + MERGE_BASE: ${{ inputs.merge-base }} DRY_RUN: ${{ inputs.dry-run }} JOB_SUMMARY: ${{ inputs.job-summary }} PR_COMMENTS: ${{ inputs.pr-comments }} diff --git a/main.py b/main.py index eb0af9c..87434ec 100755 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ import sys import subprocess import re -from github import Github +from github import Github # type: ignore # Constants for message titles @@ -16,6 +16,7 @@ AUTHOR_NAME = os.getenv("AUTHOR_NAME", "false") AUTHOR_EMAIL = os.getenv("AUTHOR_EMAIL", "false") COMMIT_SIGNOFF = os.getenv("COMMIT_SIGNOFF", "false") +MERGE_BASE = os.getenv("MERGE_BASE", "false") DRY_RUN = os.getenv("DRY_RUN", "false") JOB_SUMMARY = os.getenv("JOB_SUMMARY", "false") PR_COMMENTS = os.getenv("PR_COMMENTS", "false") @@ -32,6 +33,7 @@ def log_env_vars(): print(f"AUTHOR_NAME = {AUTHOR_NAME}") print(f"AUTHOR_EMAIL = {AUTHOR_EMAIL}") print(f"COMMIT_SIGNOFF = {COMMIT_SIGNOFF}") + print(f"MERGE_BASE = {MERGE_BASE}") print(f"DRY_RUN = {DRY_RUN}") print(f"JOB_SUMMARY = {JOB_SUMMARY}") print(f"PR_COMMENTS = {PR_COMMENTS}\n") @@ -45,11 +47,13 @@ def run_commit_check() -> int: "--author-name", "--author-email", "--commit-signoff", + "--merge-base", ] args = [ arg for arg, value in zip( - args, [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF] + args, + [MESSAGE, BRANCH, AUTHOR_NAME, AUTHOR_EMAIL, COMMIT_SIGNOFF, MERGE_BASE], ) if value == "true" ] @@ -101,7 +105,12 @@ def add_pr_comments() -> int: try: token = os.getenv("GITHUB_TOKEN") repo_name = os.getenv("GITHUB_REPOSITORY") - pr_number = os.getenv("GITHUB_REF").split("/")[-2] + pr_number = os.getenv("GITHUB_REF") + if pr_number is not None: + pr_number = pr_number.split("/")[-2] + else: + # Handle the case where GITHUB_REF is not set + raise ValueError("GITHUB_REF environment variable is not set") # Initialize GitHub client g = Github(token) @@ -154,6 +163,23 @@ def add_pr_comments() -> int: return 1 +def log_error_and_exit( + failure_title: str, result_text: str | None, ret_code: int +) -> None: + """ + Logs an error message to GitHub Actions and exits with the specified return code. + + Args: + failure_title (str): The title of the failure message. + result_text (str): The detailed result text to include in the error message. + ret_code (int): The return code to exit with. + """ + if result_text: + error_message = f"{failure_title}\n```\n{result_text}\n```" + print(f"::error::{error_message}") + sys.exit(ret_code) + + def main(): """Main function to run commit-check, add job summary and post PR comments.""" log_env_vars() @@ -166,7 +192,8 @@ def main(): if DRY_RUN == "true": ret_code = 0 - sys.exit(ret_code) + result_text = read_result_file() + log_error_and_exit(FAILURE_TITLE, result_text, ret_code) if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index b24952d..e16e5b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Install commit-check CLI # For details please see: https://github.com/commit-check/commit-check -commit-check==0.8.5 +commit-check==0.9.6 # Interact with the GitHub API. -PyGithub==2.5.0 +PyGithub==2.6.1