From 00bf73fef7120ceb335dc9ef84a4390a2d1ccb59 Mon Sep 17 00:00:00 2001 From: Subash Chandra Sapkota Date: Mon, 26 Feb 2024 19:04:44 +0545 Subject: [PATCH] feat: Add fail_on_error github action parameter --- .github/workflows/test_action.yaml | 14 +++++ README.md | 14 +++++ action.yml | 17 +++++- github_actions/run.py | 84 +++++++++++++++++++++++++++++- 4 files changed, 126 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test_action.yaml b/.github/workflows/test_action.yaml index f05ec9a..b259b63 100644 --- a/.github/workflows/test_action.yaml +++ b/.github/workflows/test_action.yaml @@ -13,6 +13,20 @@ jobs: - uses: actions/checkout@v4 - name: Run commitlint + id: commitlintrun uses: ./ # Uses an action in the root directory # or use a released GitHub Action # uses: opensource-nepal/commitlint@v0.2.1 + with: + fail_on_error: false + + - name: Check Output + run: | + echo 'Status - ${{ steps.commitlintrun.outputs.status }}' + echo 'Exit Code - ${{ steps.commitlintrun.outputs.exit_code }}' + + # Check commitlintrun status + if [ "${{ steps.commitlintrun.outputs.status }}" = "failure" ]; then + echo "Failing the job manually because Commitlint status is failure." + exit 1 + fi diff --git a/README.md b/README.md index 4b74a4d..3ec5831 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,20 @@ jobs: > **_NOTE:_** commitlint GitHub Actions will only be triggered by "push" or "pull_request" events. +#### GitHub Action Inputs + +| # | Name | Type | Default | Description | +| --- | ----------------- | -----------| -----------| ----------- | +| 1 | **fail_on_error** | Boolean | true | Determines whether the GitHub Action should fail when encountering an error. | + + +#### GitHub Action Outputs + +| # | Name | Type | Description | +| --- | -------------- | --------------| ------------ | +| 1 | **exit_code** | Integer | The exit code indicating the success or failure of the GitHub Actions workflow. | +| 2 | **status** |'failure' \| 'success'| The status of the GitHub Actions workflow, indicating success or failure. | + ## Contribution We appreciate feedback and contribution to this package. To get started please see our [contribution guide](./CONTRIBUTING.md). diff --git a/action.yml b/action.yml index 693c167..ce16dd4 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,17 @@ name: "Conventional Commitlint" description: "A GitHub Action to check conventional commit message" +inputs: + fail_on_error: + description: Whether to fail the workflow if commit messages don't follow conventions. + default: 'true' + required: false +outputs: + status: + description: Status + value: ${{ steps.commitlint.outputs.status }} + exit_code: + description: Exit Code + value: ${{ steps.commitlint.outputs.exit_code }} branding: color: "red" icon: "git-commit" @@ -42,5 +54,8 @@ runs: # checking the commits (for both push and pull_request) - name: Check the commits id: commitlint - run: python ${{ github.action_path }}/github_actions/run.py + run: | + python ${{ github.action_path }}/github_actions/run.py shell: bash + env: + INPUT_FAIL_ON_ERROR: ${{ inputs.fail_on_error }} diff --git a/github_actions/run.py b/github_actions/run.py index 819b43b..af299c5 100644 --- a/github_actions/run.py +++ b/github_actions/run.py @@ -2,14 +2,24 @@ This script contains actions to be taken based on GitHub events, specifically for push and pull_request events. """ +import os import subprocess import sys +from typing import Optional, Union from event import GithubEvent +# Events EVENT_PUSH = "push" EVENT_PULL_REQUEST = "pull_request" +# Inputs +INPUT_FAIL_ON_ERROR = "INPUT_FAIL_ON_ERROR" + +# Status +STATUS_SUCCESS = "success" +STATUS_FAILURE = "failure" + def _handle_pr_event(event: GithubEvent) -> None: """ @@ -55,6 +65,67 @@ def _handle_push_event(event: GithubEvent) -> None: raise EnvironmentError("Unable to retrieve From hash and To hash") from None +def _write_output(name: str, value: Union[str, int]) -> None: + """ + Writes an output to the GitHub Actions environment. + + Args: + name (str): The name of the output variable. + value: The value to be assigned to the output variable. + + Raises: + OSError: If there is an issue opening or writing to the output file. + """ + output_file_path = os.environ.get("GITHUB_OUTPUT", "") + with open(file=output_file_path, mode="a", encoding="utf-8") as output_file: + output_file.write(f"{name}={value}\n") + + +def _get_input(key: str) -> Optional[str]: + """ + Reads the github action input + + Args: + key (str): The environment variable to parse + + Returns: + str or None: The value of the input or None if it is not set + """ + return os.environ.get(key) + + +def _parse_boolean_input(val: Optional[str]) -> bool: + """ + Parses the input environment key of boolean type in the YAML 1.2 + "core schema" specification. + Support boolean input list: + `true | True | TRUE | false | False | FALSE` . + ref: https://yaml.org/spec/1.2/spec.html#id2804923 + + Args: + key (str, optional): The name of the environment variable to parse. + + Returns: + bool: The parsed boolean value. + + Raises: + TypeError: If the environment variable's value does not meet the + YAML 1.2 "core schema" specification for booleans. + """ + + if val in {"true", "True", "TRUE"}: + return True + if val in {"false", "False", "FALSE"}: + return False + raise TypeError( + """ + Input does not meet YAML 1.2 "Core Schema" specification.\n' + Support boolean input list: + `true | True | TRUE | false | False | FALSE + """ + ) + + def _check_commits(from_hash: str, to_hash: str) -> None: """Check commits using commitlint. @@ -75,8 +146,17 @@ def _check_commits(from_hash: str, to_hash: str) -> None: text=True, ).strip() sys.stdout.write(f"{output}\n") - except subprocess.CalledProcessError: - sys.exit(1) + + _write_output("status", STATUS_SUCCESS) + _write_output("exit_code", 0) + + except subprocess.CalledProcessError as error: + _write_output("status", STATUS_FAILURE) + _write_output("exit_code", error.returncode) + val = _get_input(INPUT_FAIL_ON_ERROR) + fail_on_error = _parse_boolean_input(val) + if fail_on_error: + sys.exit(1) def main() -> None: