Skip to content

Commit a3f41dd

Browse files
Merge pull request #11 from AbsaOSS/feature/10-Remove-support-for-branches
Feature/10 remove support for branches
2 parents c836034 + e00dc51 commit a3f41dd

File tree

7 files changed

+88
-198
lines changed

7 files changed

+88
-198
lines changed

README.md

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ A GH action for validating version tag sequences and ensuring compliance with ve
1919
## Motivation
2020

2121
This action is designed to help maintainers and contributors ensure that version tags are sequenced correctly and comply with versioning standards. It can be used to prevent common issues such as:
22+
- Duplicate version tags on input
2223
- Missing version tags
2324
- Incorrect version sequences
2425
- Non-standard version formats
@@ -41,21 +42,6 @@ This action is designed to help maintainers and contributors ensure that version
4142
- **Description**: The version tag to check for in the repository. Example: `v0.1.0`.
4243
- **Required**: Yes
4344

44-
### `branch`
45-
- **Description**: The branch to check for the version tag. Example: `master`.
46-
- **Required**: Yes
47-
48-
### `fails-on-error`
49-
- **Description**: Whether the action should fail if an error occurs.
50-
- **Required**: No
51-
- **Default**: `true`
52-
53-
## Outputs
54-
55-
### `valid`
56-
- **Description**: Whether the version tag is valid.
57-
- **Value**: `true` or `false`
58-
5945
## Usage
6046

6147
### Adding the Action to Your Workflow
@@ -73,10 +59,8 @@ See the default action step definition:
7359
env:
7460
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7561
with:
76-
github-repository: "{ org }/{ repo }"
62+
github-repository: "{ org }/{ repo }" # e.g. ${{ github.repository }}
7763
version-tag: "v0.1.0"
78-
branch: "master"
79-
fails-on-error: "false"
8064
```
8165
8266
### Supported Version Tags Formats
@@ -215,22 +199,10 @@ fi
215199
# Set necessary environment variables
216200
export INPUT_GITHUB_TOKEN="$GITHUB_TOKEN"
217201
export INPUT_VERSION_TAG="v1.2.3"
218-
export INPUT_BRANCH="main"
219-
export INPUT_FAILS_ON_ERROR="true"
220202
export INPUT_GITHUB_REPOSITORY="AbsaOSS/generate-release-notes"
221-
export GITHUB_OUTPUT="output.txt" # File to capture outputs
222-
223-
# Remove existing output file if it exists
224-
if [ -f "$GITHUB_OUTPUT" ]; then
225-
rm "$GITHUB_OUTPUT"
226-
fi
227203
228204
# Run the main script
229205
python main.py
230-
231-
# Display the outputs
232-
echo "Action Outputs:"
233-
cat "$GITHUB_OUTPUT"
234206
```
235207

236208
## Contribution Guidelines

action.yml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,6 @@ inputs:
2323
version-tag:
2424
description: 'The version tag sequence to validate. Example: "v1.2.3".'
2525
required: true
26-
branch:
27-
description: 'The branch to check for the latest version tag. Example: "master".'
28-
required: true
29-
fails-on-error:
30-
description: 'Set to "true" to fail the action if validation errors are found.'
31-
required: false
32-
default: 'true'
33-
34-
outputs:
35-
valid:
36-
description: 'Indicates whether the version tag sequence is valid ("true" or "false").'
37-
value: ${{ steps.version-tag-check.outputs.valid }}
3826

3927
branding:
4028
icon: 'book'
@@ -72,8 +60,6 @@ runs:
7260
INPUT_GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
7361
INPUT_GITHUB_REPOSITORY: ${{ inputs.github-repository }}
7462
INPUT_VERSION_TAG: ${{ inputs.version-tag }}
75-
INPUT_BRANCH: ${{ inputs.branch }}
76-
INPUT_FAILS_ON_ERROR: ${{ inputs.fails-on-error }}
7763
run: |
7864
source .venv/bin/activate
7965
python ${{ github.action_path }}/main.py

tests/test_version_tag_check_action.py

Lines changed: 41 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import os
2020
import pytest
2121

22+
from version_tag_check.version import Version
2223
from version_tag_check.version_tag_check_action import VersionTagCheckAction
2324

2425

@@ -28,15 +29,13 @@
2829
("INPUT_GITHUB_TOKEN", "Failure: GITHUB_TOKEN is not set correctly."),
2930
("INPUT_GITHUB_REPOSITORY", "Failure: GITHUB_REPOSITORY is not set correctly."),
3031
("INPUT_VERSION_TAG", "Failure: VERSION_TAG is not set correctly."),
31-
("INPUT_BRANCH", "Failure: BRANCH is not set correctly."),
3232
])
3333
def test_validate_inputs_missing_variables(monkeypatch, caplog, missing_var, error_message):
3434
# Set all required environment variables
3535
env_vars = {
3636
"INPUT_GITHUB_TOKEN": "fake_token",
3737
"INPUT_GITHUB_REPOSITORY": "owner/repo",
3838
"INPUT_VERSION_TAG": "v1.0.0",
39-
"INPUT_BRANCH": "main",
4039
}
4140
env_vars.pop(missing_var) # Remove the variable to test
4241
if missing_var in os.environ.keys():
@@ -60,153 +59,83 @@ def test_validate_inputs_missing_variables(monkeypatch, caplog, missing_var, err
6059

6160
# run
6261

63-
def test_run_successful(mocker, tmp_path):
62+
@pytest.mark.parametrize(
63+
"version_tag, existing_tags",
64+
[
65+
("v0.0.1", []), # New version with no existing tags
66+
("v0.1.0", []), # New version with no existing tags
67+
("v1.0.0", []), # New version with no existing tags
68+
("v0.0.2", [Version("v0.0.1")]), # Patch increment
69+
("v1.2.0", [Version("v1.1.0")]), # Minor increment
70+
("v2.0.0", [Version("v1.9.9")]), # Major increment
71+
("v2.1.0", [Version("v2.0.5"), Version("v2.0.0")]), # New Release serie
72+
("v1.5.2", [Version("v2.0.0"), Version("v1.5.1")]), # Backport increment
73+
],
74+
)
75+
def test_run_successful(mocker, version_tag, existing_tags):
6476
# Set environment variables
6577
env_vars = {
6678
"INPUT_GITHUB_TOKEN": "fake_token",
67-
"INPUT_VERSION_TAG": "v1.0.1",
68-
"INPUT_BRANCH": "main",
69-
"INPUT_FAILS_ON_ERROR": "true",
79+
"INPUT_VERSION_TAG": version_tag,
7080
"INPUT_GITHUB_REPOSITORY": "owner/repo",
7181
}
72-
# Update os.environ with the test environment variables
7382
os.environ.update(env_vars)
74-
if os.path.exists("output.txt"):
75-
os.remove("output.txt")
7683

7784
# Mock sys.exit to prevent the test from exiting
7885
mock_exit = mocker.patch("sys.exit")
7986

80-
# Mock the Version class
81-
mock_version_class = mocker.patch("version_tag_check.version_tag_check_action.Version")
82-
mock_version_instance = mock_version_class.return_value
83-
mock_version_instance.is_valid_format.return_value = True
84-
8587
# Mock the GitHubRepository class
8688
mock_repository_class = mocker.patch("version_tag_check.version_tag_check_action.GitHubRepository")
8789
mock_repository_instance = mock_repository_class.return_value
88-
mock_repository_instance.get_all_tags.return_value = []
89-
90-
# Mock the NewVersionValidator class
91-
mock_validator_class = mocker.patch("version_tag_check.version_tag_check_action.NewVersionValidator")
92-
mock_validator_instance = mock_validator_class.return_value
93-
mock_validator_instance.is_valid_increment.return_value = True
94-
95-
# Mock the output writing method
96-
mock_output = mocker.patch("version_tag_check.version_tag_check_action.VersionTagCheckAction.write_output")
90+
mock_repository_instance.get_all_tags.return_value = existing_tags
9791

9892
# Run the action
9993
action = VersionTagCheckAction()
10094
action.run()
10195

102-
mock_output.assert_called_once_with("true")
10396
mock_exit.assert_called_once_with(0)
10497

105-
def test_run_invalid_version_format(mocker, tmp_path, caplog):
98+
99+
@pytest.mark.parametrize(
100+
"version_tag, existing_tags, is_valid_format, is_valid_increment, expected_exit_code, error_message",
101+
[
102+
("invalid_version", [], False, True, 1, "Tag does not match the required format"), # Invalid format
103+
("invalid_version", [Version("v1.0.0")], False, True, 1, "Tag does not match the required format"), # Invalid format
104+
("v1.0.3", [Version("v1.0.1")], True, False, 1, "New tag v1.0.3 is not one patch higher than the latest tag v1.0.1."), # Invalid increment
105+
("v1.0.0", [Version("v1.0.0")], True, False, 1, "The tag already exists in repository"), # Existing tag
106+
("v1.4.1", [Version("v2.0.0"), Version("v1.4.2")], True, False, 1, "New tag v1.4.1 is not one patch higher than the latest tag v1.4.2."), # Invalid backport increment
107+
("1.0.0", [], False, True, 1, "Tag does not match the required format"), # Invalid format and increment
108+
("v3.0.1", [Version("v2.9.9"), Version("v1.0.0")], True, False, 1, "New tag v3.0.1 is not a valid major bump. Latest version: v2.9.9."), # Invalid version gap
109+
],
110+
)
111+
def test_run_unsuccessful(mocker, caplog, version_tag, existing_tags, is_valid_format, is_valid_increment, expected_exit_code, error_message):
106112
# Set environment variables
107113
env_vars = {
108114
"INPUT_GITHUB_TOKEN": "fake_token",
109-
"INPUT_VERSION_TAG": "invalid_version",
110-
"INPUT_BRANCH": "main",
111-
"INPUT_FAILS_ON_ERROR": "true",
115+
"INPUT_VERSION_TAG": version_tag,
112116
"INPUT_GITHUB_REPOSITORY": "owner/repo",
113117
}
114118
os.environ.update(env_vars)
115-
if os.path.exists("output.txt"):
116-
os.remove("output.txt")
117119

118-
# Mock sys.exit
120+
# Mock sys.exit to raise a SystemExit for assertion
119121
def mock_exit(code):
120122
raise SystemExit(code)
121123

122124
mocker.patch("sys.exit", mock_exit)
123125

124-
# Mock the Version class used in VersionTagCheckAction
125-
mock_version_class = mocker.patch("version_tag_check.version_tag_check_action.Version")
126-
mock_version_instance = mock_version_class.return_value
127-
mock_version_instance.is_valid_format.return_value = False # Simulate invalid format
128-
129-
# Mock the output writing method
130-
mock_output = mocker.patch("version_tag_check.version_tag_check_action.VersionTagCheckAction.write_output")
131-
132-
# Run the action
133-
caplog.set_level(logging.ERROR)
134-
action = VersionTagCheckAction()
135-
with pytest.raises(SystemExit) as e:
136-
action.run()
137-
138-
# Assert that sys.exit was called with exit code 1
139-
assert e.value.code == 1
140-
141-
mock_output.assert_called_once_with("false")
142-
assert 'Tag does not match the required format' in caplog.text
143-
144-
def test_run_invalid_version_increment(mocker, tmp_path):
145-
# Set environment variables
146-
env_vars = {
147-
"INPUT_GITHUB_TOKEN": "fake_token",
148-
"INPUT_VERSION_TAG": "v1.0.2",
149-
"INPUT_BRANCH": "main",
150-
"INPUT_FAILS_ON_ERROR": "true",
151-
"INPUT_GITHUB_REPOSITORY": "owner/repo",
152-
}
153-
os.environ.update(env_vars)
154-
if os.path.exists("output.txt"):
155-
os.remove("output.txt")
156-
157-
# Mock sys.exit
158-
mock_exit = mocker.patch("sys.exit")
159-
160-
# Mock the Version class
161-
mock_version_class = mocker.patch("version_tag_check.version_tag_check_action.Version")
162-
mock_version_instance = mock_version_class.return_value
163-
mock_version_instance.is_valid_format.return_value = True
164-
165126
# Mock the GitHubRepository class
166127
mock_repository_class = mocker.patch("version_tag_check.version_tag_check_action.GitHubRepository")
167128
mock_repository_instance = mock_repository_class.return_value
168-
mock_repository_instance.get_all_tags.return_value = [] # Simulate existing versions if needed
169-
170-
# Mock the NewVersionValidator class to return False for is_valid_increment
171-
mock_validator_class = mocker.patch("version_tag_check.version_tag_check_action.NewVersionValidator")
172-
mock_validator_instance = mock_validator_class.return_value
173-
mock_validator_instance.is_valid_increment.return_value = False
174-
175-
# Mock the output writing method
176-
mock_output = mocker.patch("version_tag_check.version_tag_check_action.VersionTagCheckAction.write_output")
129+
mock_repository_instance.get_all_tags.return_value = existing_tags
177130

178131
# Run the action
132+
caplog.set_level(logging.ERROR)
179133
action = VersionTagCheckAction()
180-
action.run()
181-
182-
mock_output.assert_called_once_with("false")
183-
mock_exit.assert_called_once_with(1)
184-
185-
186-
# handle_failure
187-
188-
def test_handle_failure_fails_on_error_false(mocker):
189-
# Set environment variables with 'INPUT_FAILS_ON_ERROR' set to 'false'
190-
env_vars = {
191-
"INPUT_GITHUB_TOKEN": "fake_token",
192-
"INPUT_VERSION_TAG": "v1.0.0",
193-
"INPUT_BRANCH": "main",
194-
"INPUT_FAILS_ON_ERROR": "false", # Set to 'false' to test else branch
195-
"INPUT_GITHUB_REPOSITORY": "owner/repo",
196-
}
197-
mocker.patch.dict(os.environ, env_vars)
198-
199-
# Mock sys.exit to raise SystemExit exception
200-
def mock_exit(code):
201-
raise SystemExit(code)
202-
mocker.patch("sys.exit", mock_exit)
203-
204-
# Instantiate the action
205-
action = VersionTagCheckAction()
206-
207-
# Call handle_failure and expect SystemExit
208134
with pytest.raises(SystemExit) as e:
209-
action.handle_failure()
135+
action.run()
136+
137+
# Assert sys.exit was called with the correct code
138+
assert e.value.code == expected_exit_code
210139

211-
# Assert that sys.exit was called with exit code 0
212-
assert e.value.code == 0
140+
# Assert error message in logs
141+
assert error_message in caplog.text

version_tag_check/github_repository.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __init__(self, owner: str, repo: str, token: str) -> None:
4545
self.owner = owner
4646
self.repo = repo
4747
self.token = token
48+
4849
self.headers = {"Authorization": f"Bearer {self.token}", "Accept": "application/vnd.github.v3+json"}
4950

5051
def get_all_tags(self) -> list[Version]:

version_tag_check/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Version:
3232
Class to represent a version and compare it to other versions.
3333
"""
3434

35-
VERSION_REGEX = r"^v?(\d+)\.(\d+)\.(\d+)$"
35+
VERSION_REGEX = r"^v(\d+)\.(\d+)\.(\d+)$"
3636

3737
def __init__(self, version_str: str, version_regex: str = VERSION_REGEX) -> None:
3838
"""

version_tag_check/version_tag_check_action.py

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ def __init__(self) -> None:
4141
"""
4242
self.github_token: str = os.environ.get("INPUT_GITHUB_TOKEN", default="")
4343
self.version_tag_str: str = os.environ.get("INPUT_VERSION_TAG", default="")
44-
self.branch: str = os.environ.get("INPUT_BRANCH", default="")
45-
self.fails_on_error: bool = os.environ.get("INPUT_FAILS_ON_ERROR", "true").lower() == "true"
4644
self.github_repository: str = os.environ.get("INPUT_GITHUB_REPOSITORY", default="")
4745

4846
self.__validate_inputs()
@@ -58,42 +56,21 @@ def run(self) -> None:
5856
new_version = Version(self.version_tag_str)
5957
if not new_version.is_valid_format():
6058
logger.error('Tag does not match the required format "v[0-9]+.[0-9]+.[0-9]+"')
61-
self.handle_failure()
59+
sys.exit(1)
6260

6361
repository: GitHubRepository = GitHubRepository(self.owner, self.repo, self.github_token)
6462
existing_versions: list[Version] = repository.get_all_tags()
6563

64+
if new_version in existing_versions:
65+
logger.error("The tag already exists in repository.")
66+
sys.exit(1)
67+
6668
validator = NewVersionValidator(new_version, existing_versions)
6769
if validator.is_valid_increment():
68-
self.write_output("true")
6970
logger.info("New tag is valid.")
7071
sys.exit(0)
7172
else:
72-
logger.error("New tag is not valid.")
73-
self.handle_failure()
74-
75-
def write_output(self, valid_value) -> None:
76-
"""
77-
Write the output to the file specified by the GITHUB_OUTPUT environment variable.
78-
79-
@param valid_value: The value to write to the output file.
80-
@return: None
81-
"""
82-
output_file = os.environ.get("GITHUB_OUTPUT", default="output.txt")
83-
with open(output_file, "a", encoding="utf-8") as fh:
84-
print(f"valid={valid_value}", file=fh)
85-
86-
def handle_failure(self) -> None:
87-
"""
88-
Handle the failure of the action.
89-
90-
@return: None
91-
"""
92-
self.write_output("false")
93-
if self.fails_on_error:
9473
sys.exit(1)
95-
else:
96-
sys.exit(0)
9774

9875
def __validate_inputs(self) -> None:
9976
"""
@@ -112,7 +89,3 @@ def __validate_inputs(self) -> None:
11289
if len(self.version_tag_str) == 0:
11390
logger.error("Failure: VERSION_TAG is not set correctly.")
11491
sys.exit(1)
115-
116-
if len(self.branch) == 0:
117-
logger.error("Failure: BRANCH is not set correctly.")
118-
sys.exit(1)

0 commit comments

Comments
 (0)