Skip to content

Commit

Permalink
- Removed fail on error input.
Browse files Browse the repository at this point in the history
- Removed valid output.
  • Loading branch information
miroslavpojer committed Nov 22, 2024
1 parent 6ccc8ec commit b1c0027
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 140 deletions.
23 changes: 0 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,6 @@ This action is designed to help maintainers and contributors ensure that release
- **Required**: No
- **Default**: ``

### `fails-on-error`
- **Description**: Whether the action should fail if an error occurs.
- **Required**: No
- **Default**: `true`

## Outputs

### `valid`
- **Description**: Whether the release notes are present.
- **Value**: `true` or `false`

## Usage

### Adding the Action to Your Workflow
Expand All @@ -90,7 +79,6 @@ See the default action step definition:
location: "body"
title: "[Rr]elease [Nn]otes:"
skip-labels: "skip-release-notes,no-release-notes"
fails-on-error: "false"
```
## Running Static Code Analysis
Expand Down Expand Up @@ -218,20 +206,9 @@ export INPUT_GITHUB_REPOSITORY="AbsaOSS/generate-release-notes"
export INPUT_LOCATION="body"
export INPUT_TITLE="[Rr]elease notes:"
export INPUT_SKIP_LABELS="skip-release-notes,another-skip-label"
export INPUT_FAILS_ON_ERROR="true"
export GITHUB_OUTPUT="output.txt" # File to capture outputs

# Remove existing output file if it exists
if [ -f "$GITHUB_OUTPUT" ]; then
rm "$GITHUB_OUTPUT"
fi

# Run the main script
python main.py

# Display the outputs
echo "Action Outputs:"
cat "$GITHUB_OUTPUT"
```

## Contribution Guidelines
Expand Down
10 changes: 0 additions & 10 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,6 @@ inputs:
description: 'A comma-separated list of labels that will cause the action to skip the check.'
required: false
default: ''
fails-on-error:
description: 'Set to "true" to fail the action if validation errors are found.'
required: false
default: 'true'

outputs:
valid:
description: 'Indicates whether the release notes are present in the PR.'
value: ${{ steps.release-notes-presence-check.outputs.valid }}

branding:
icon: 'book'
Expand Down Expand Up @@ -84,7 +75,6 @@ runs:
INPUT_LOCATION: ${{ inputs.location }}
INPUT_TITLE: ${{ inputs.title }}
INPUT_SKIP_LABELS: ${{ inputs.skip-labels }}
INPUT_FAILS_ON_ERROR: ${{ inputs.fails-on-error }}
run: |
source .venv/bin/activate
python ${{ github.action_path }}/main.py
Expand Down
63 changes: 21 additions & 42 deletions release_notes_presence_check/release_notes_presence_check_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def __init__(self) -> None:
self.location: str = os.environ.get("INPUT_LOCATION", default="body")
self.title: str = os.environ.get("INPUT_TITLE", default="[Rr]elease [Nn]otes:")
self.skip_labels: list[str] = os.environ.get("INPUT_SKIP_LABELS", default="")
self.fails_on_error: bool = os.environ.get("INPUT_FAILS_ON_ERROR", "true").lower() == "true"

self.__validate_inputs()

Expand All @@ -65,19 +64,18 @@ def run(self) -> None:
labels: list[str] = [label.get("name", "") for label in pr_data.get("labels", [])]
if self.skip_labels in labels:
logger.info("Skipping release notes check because '%s' label is present.", self.skip_labels)
self.write_output("true")
sys.exit(0) # Exiting with code 0 indicates success but the action is skipped.

# check release notes presence in defined location
pr_body = pr_data.get("body", "")
if len(pr_body.strip()) == 0:
logger.error("Error: Pull request description is empty.")
self.handle_failure()
sys.exit(0)

# Check if release notes tag is present
if not re.search(self.title, pr_body):
logger.error("Error: Release notes title '%s' not found in pull request body.", self.title)
self.handle_failure()
sys.exit(0)

# Get line index of the release notes tag
lines = pr_body.split("\n")
Expand All @@ -90,81 +88,62 @@ def run(self) -> None:
# Check if there is content after the release notes tag
if release_notes_start_index is None or release_notes_start_index >= len(lines):
logger.error("Error: No content found after the release notes tag.")
self.handle_failure()
sys.exit(1)

# Check if there is a bullet list directly under the release notes tag
text_below_release_notes = lines[release_notes_start_index:]
if not text_below_release_notes or not text_below_release_notes[0].strip().startswith(("-", "+", "*")):
logger.error("Error: No bullet list found directly under release notes tag.")
self.handle_failure()
sys.exit(1)

self.write_output("true")
logger.info("Release Notes detected.")
sys.exit(0)

def write_output(self, valid_value: str) -> None:
"""
Write the output to the file specified by the GITHUB_OUTPUT environment variable.
@param valid_value: The value to write to the output file.
@return: None
"""
output_file = os.environ.get("GITHUB_OUTPUT", default="output.txt")
with open(output_file, "a", encoding="utf-8") as fh:
print(f"valid={valid_value}", file=fh)

def handle_failure(self) -> None:
"""
Handle the failure of the action.
@return: None
"""
self.write_output("false")
if self.fails_on_error:
sys.exit(1)
else:
sys.exit(0)

def __validate_inputs(self) -> None:
"""
Validate the required inputs. When the inputs are not valid, the action will fail.
@return: None
"""
error_detected = False

if len(self.github_token) == 0:
logger.error("Failure: GITHUB_TOKEN is not set correctly.")
self.handle_failure()
error_detected = True

value = os.environ.get("INPUT_PR_NUMBER", default="")
if len(value) == 0:
logger.error("Failure: PR_NUMBER is not set correctly.")
self.handle_failure()
error_detected = True

if not value.isdigit():
logger.error("Failure: PR_NUMBER is not a valid number.")
self.handle_failure()
error_detected = True

value = os.environ.get("INPUT_GITHUB_REPOSITORY", default="")
if len(value) == 0:
logger.error("Failure: GITHUB_REPOSITORY is not set correctly.")
self.handle_failure()
error_detected = True

if value.count("/") != 1:
logger.error("Failure: GITHUB_REPOSITORY is not in the correct format.")
self.handle_failure()

if len(value.split("/")[0]) == 0 or len(value.split("/")[1]) == 0:
logger.error("Failure: GITHUB_REPOSITORY is not in the correct format.")
self.handle_failure()
error_detected = True
else:
if len(value.split("/")[0]) == 0 or len(value.split("/")[1]) == 0:
logger.error("Failure: GITHUB_REPOSITORY is not in the correct format.")
error_detected = True

if len(self.location) == 0:
logger.error("Failure: LOCATION is not set correctly.")
self.handle_failure()
error_detected = True

if self.location not in ["body"]:
logger.error("Failure: LOCATION is not one of the supported values.")
self.handle_failure()
error_detected = True

if len(self.title) == 0:
logger.error("Failure: TITLE is not set correctly.")
self.handle_failure()
error_detected = True

if error_detected:
sys.exit(1)
65 changes: 0 additions & 65 deletions tests/test_release_notes_presence_check_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def test_validate_inputs_invalid(monkeypatch, caplog, env_name, env_value, error
"INPUT_LOCATION": "body",
"INPUT_TITLE": "[Rr]elease [Nn]otes:",
"INPUT_SKIP_LABELS": "",
"INPUT_FAILS_ON_ERROR": "true",
}

# Update or remove the environment variable for the tested scenario
Expand Down Expand Up @@ -136,14 +135,10 @@ def test_run_successful(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
action = ReleaseNotesPresenceCheckAction()
action.run()

mock_output.assert_called_once_with("true")
mock_exit.assert_called_once_with(0)


Expand Down Expand Up @@ -174,9 +169,6 @@ def test_run_skip_by_label(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}, {"name": "skip-release-notes-check"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
Expand All @@ -185,8 +177,6 @@ def test_run_skip_by_label(mocker):
assert SystemExit == exit_info.type
assert 0 == exit_info.value.code

mock_output.assert_called_once_with("true")


def test_run_fail_no_body(mocker):
# Set environment variables
Expand Down Expand Up @@ -214,9 +204,6 @@ def test_run_fail_no_body(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
Expand All @@ -225,8 +212,6 @@ def test_run_fail_no_body(mocker):
assert SystemExit == exit_info.type
assert 1 == exit_info.value.code

mock_output.assert_called_once_with("false")

def test_run_fail_empty_body(mocker):
# Set environment variables
env_vars = {
Expand Down Expand Up @@ -254,9 +239,6 @@ def test_run_fail_empty_body(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
Expand All @@ -265,8 +247,6 @@ def test_run_fail_empty_body(mocker):
assert SystemExit == exit_info.type
assert 1 == exit_info.value.code

mock_output.assert_called_once_with("false")

def test_run_fail_title_not_found(mocker):
# Set environment variables
env_vars = {
Expand Down Expand Up @@ -294,9 +274,6 @@ def test_run_fail_title_not_found(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
Expand All @@ -305,8 +282,6 @@ def test_run_fail_title_not_found(mocker):
assert SystemExit == exit_info.type
assert 1 == exit_info.value.code

mock_output.assert_called_once_with("false")

def test_run_fail_release_notes_lines_not_found(mocker):
# Set environment variables
env_vars = {
Expand Down Expand Up @@ -334,9 +309,6 @@ def test_run_fail_release_notes_lines_not_found(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
Expand All @@ -345,8 +317,6 @@ def test_run_fail_release_notes_lines_not_found(mocker):
assert SystemExit == exit_info.type
assert 1 == exit_info.value.code

mock_output.assert_called_once_with("false")

def test_run_fail_no_lines_after_title(mocker):
# Set environment variables
env_vars = {
Expand Down Expand Up @@ -374,45 +344,10 @@ def test_run_fail_no_lines_after_title(mocker):
"labels": [{"name": "bug"}, {"name": "enhancement"}]
}

# Mock the output writing method
mock_output = mocker.patch("release_notes_presence_check.release_notes_presence_check_action.ReleaseNotesPresenceCheckAction.write_output")

# Run the action
with pytest.raises(SystemExit) as exit_info:
action = ReleaseNotesPresenceCheckAction()
action.run()

assert SystemExit == exit_info.type
assert 1 == exit_info.value.code

mock_output.assert_called_once_with("false")

# handle_failure

def test_handle_failure_fails_on_error_false(mocker):
# Set environment variables with 'INPUT_FAILS_ON_ERROR' set to 'false'
env_vars = {
"INPUT_GITHUB_TOKEN": "fake_token",
"INPUT_PR_NUMBER": "109",
"INPUT_GITHUB_REPOSITORY": "owner/repo",
"INPUT_LOCATION": "body",
"INPUT_TITLE": "[Rr]elease [Nn]otes:",
"INPUT_SKIP_LABELS": "",
"INPUT_FAILS_ON_ERROR": "false", # Set to 'false' to test else branch
}
mocker.patch.dict(os.environ, env_vars)

# Mock sys.exit to raise SystemExit exception
def mock_exit(code):
raise SystemExit(code)
mocker.patch("sys.exit", mock_exit)

# Instantiate the action
action = ReleaseNotesPresenceCheckAction()

# Call handle_failure and expect SystemExit
with pytest.raises(SystemExit) as e:
action.handle_failure()

# Assert that sys.exit was called with exit code 0
assert e.value.code == 0

0 comments on commit b1c0027

Please sign in to comment.