From e57b24e2a478b930cfab51ef1d8a9961d9e81a6b Mon Sep 17 00:00:00 2001 From: pz2 Date: Sun, 26 May 2024 11:37:28 +0200 Subject: [PATCH] Added release commands --- README.md | 26 +++++-- requirements.txt | 4 +- test/ci_provider/gitlab/get_version_test.py | 2 +- test/version/release_command_test.py | 77 +++++++++++++++++++++ valhalla/ci_provider/gitlab/get_version.py | 52 ++------------ valhalla/main.py | 16 ++++- valhalla/version/release_command.py | 23 ++++++ valhalla/version/version_to_release.py | 53 ++++++++++++++ 8 files changed, 193 insertions(+), 60 deletions(-) create mode 100644 test/version/release_command_test.py create mode 100644 valhalla/version/release_command.py diff --git a/README.md b/README.md index e87aac4..80a200d 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,17 @@ merge_request: ### 🔸 usage +**by branch:** + 1. Create branch `release-X.X.X` where `X.X.X` is a name of the version that is going to be released. You can also use - extensions like `release-2.10.4-RC`. + extensions like `release-2.10.4-RC`. To use different release kind use f.e. `release-hotfix-X.X.X`. +2. Valhalla will do everything for you 🚀 + +**by `VALHALLA_RELEASE_CMD` env variable:** + +1. Set `VALHALLA_RELEASE_CMD` env variable to `release-X.X.X` where `X.X.X` is a name of the version that is going to be + released. You can also use + extensions like `release-2.10.4-RC`. To use different release kind use f.e. `release-hotfix-X.X.X`. 2. Valhalla will do everything for you 🚀 ### 👨🏻‍👦🏻 inheritance @@ -144,11 +153,11 @@ and override values in custom use cases. **Use `{}` to evaluate variable to value f.e. `{VERSION}`** -| name | description | -|:----------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| `VERSION` | value extracted from branch name, for `release-1.2.14` it will be `1.2.14` | -| `VERSION_SLUG` | value extracted from branch name and with everything except 0-9 and a-z replaced with -. No leading / trailing -,
for `release-1.2.14` it will be `1-2-14`. Use in URLs, host names, domain names and file names | -| `VALHALLA_TOKEN` | token passed to CI runner which execute this job | +| name | description | +|:----------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| `VERSION` | value extracted from branch name or `VALHALLA_RELEASE_CMD`, for `release-1.2.14` it will be `1.2.14` | +| `VERSION_SLUG` | value extracted from branch name or `VALHALLA_RELEASE_CMD` and with everything except 0-9 and a-z replaced with -. No leading / trailing -,
for `release-1.2.14` it will be `1-2-14`. Use in URLs, host names, domain names and file names | +| `VALHALLA_TOKEN` | token passed to CI runner which execute this job | ### 🏭 custom variables @@ -189,6 +198,7 @@ in your `valhalla.yml`. workflows: # .... your standard workflows here - if: $CI_COMMIT_BRANCH =~ /^release-*/ && $CI_COMMIT_TITLE !~ /.*VALHALLA SKIP.*/ + - if: $VALHALLA_RELEASE_CMD =~ /^release-*/ && $CI_COMMIT_TITLE !~ /.*VALHALLA SKIP.*/ # add new stage stages: @@ -210,6 +220,10 @@ valhalla_release: # and for commits that DOES NOT include VALHALLA SKIP # valhalla during committing adds [VALHALLA SKIP] at the end of commit msg - if: $CI_COMMIT_BRANCH =~ /^release-*/ && $CI_COMMIT_TITLE !~ /.*VALHALLA SKIP.*/ + # we run the job when VALHALLA_RELEASE_CMD env variable is present and has name release- + # and for commits that DOES NOT include VALHALLA SKIP + # valhalla during committing adds [VALHALLA SKIP] at the end of commit msg + - if: $VALHALLA_RELEASE_CMD =~ /^release-*/ && $CI_COMMIT_TITLE !~ /.*VALHALLA SKIP.*/ ``` ### 🚧 .gitignore diff --git a/requirements.txt b/requirements.txt index 7290c2a..2410c7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ PyYAML~=6.0.1 GitPython~=3.1.40 -python-gitlab~=4.2.0 -requests~=2.31.0 +python-gitlab~=4.5.0 +requests~=2.32.2 diff --git a/test/ci_provider/gitlab/get_version_test.py b/test/ci_provider/gitlab/get_version_test.py index 1416d5f..396cba7 100644 --- a/test/ci_provider/gitlab/get_version_test.py +++ b/test/ci_provider/gitlab/get_version_test.py @@ -65,7 +65,7 @@ def test_release_hotfix_branch(self, mock_env_get): self.assertEqual(result.get_config_file_path(), "./valhalla-hotfix.yml") @patch('os.environ.get') - @patch('valhalla.ci_provider.gitlab.get_version.exit') + @patch('valhalla.version.version_to_release.exit') def test_no_matching_valhalla_branch(self, mock_exit, mock_env_get): # given: mock_env_get.return_value = 'release-1.2.3' diff --git a/test/version/release_command_test.py b/test/version/release_command_test.py new file mode 100644 index 0000000..57627b2 --- /dev/null +++ b/test/version/release_command_test.py @@ -0,0 +1,77 @@ +import unittest +from unittest.mock import patch + +from valhalla.version.release_command import get_version_to_release_from_command +from valhalla.version.version_to_release import ReleaseKind + + +class ReleaseCommandTest(unittest.TestCase): + + @patch('os.environ.get') + def test_release_command(self, mock_env_get): + # given: + mock_env_get.return_value = 'release-1.0.0' + release_kinds = [ReleaseKind("valhalla.yml", "", ".")] + + # when: + result = get_version_to_release_from_command(release_kinds) + + # then: + self.assertEqual(result.version_number_to_release, '1.0.0') + self.assertEqual(result.release_kind.filename, "valhalla.yml") + self.assertEqual(result.get_config_file_path(), "./valhalla.yml") + + @patch('os.environ.get') + @patch('valhalla.version.release_command.exit') + def test_wrong_release_command(self, mock_exit, mock_env_get): + # given: + mock_env_get.return_value = 'some-value' + release_kinds = [ReleaseKind("valhalla.yml", "", ".")] + + # when: + result = get_version_to_release_from_command(release_kinds) + + # then: + self.assertIsNone(result) + mock_exit.assert_called_with(-1) + + @patch('os.environ.get') + def test_no_release_command(self, mock_env_get): + # given: + mock_env_get.return_value = None + release_kinds = [ReleaseKind("valhalla.yml", "", ".")] + + # when: + result = get_version_to_release_from_command(release_kinds) + + # then: + self.assertIsNone(result) + + @patch('os.environ.get') + def test_release_hotfix_command(self, mock_env_get): + # given: + mock_env_get.return_value = 'release-hotfix-1.2.3' + release_kinds = [ReleaseKind("valhalla.yml", "", "."), + ReleaseKind("valhalla-hotfix.yml", "-hotfix", ".")] + + # when: + result = get_version_to_release_from_command(release_kinds) + + # then: + self.assertEqual(result.version_number_to_release, '1.2.3') + self.assertEqual(result.release_kind.filename, "valhalla-hotfix.yml") + self.assertEqual(result.get_config_file_path(), "./valhalla-hotfix.yml") + + @patch('os.environ.get') + @patch('valhalla.version.version_to_release.exit') + def test_no_matching_valhalla_command(self, mock_exit, mock_env_get): + # given: + mock_env_get.return_value = 'release-1.2.3' + release_kinds = [ReleaseKind("valhalla-hotfix.yml", "-hotfix", ".")] + + # when: + result = get_version_to_release_from_command(release_kinds) + + # then: + self.assertIsNone(result) + mock_exit.assert_called_with(-1) diff --git a/valhalla/ci_provider/gitlab/get_version.py b/valhalla/ci_provider/gitlab/get_version.py index 0cac098..33724c7 100644 --- a/valhalla/ci_provider/gitlab/get_version.py +++ b/valhalla/ci_provider/gitlab/get_version.py @@ -2,9 +2,8 @@ from typing import List from valhalla.common.logger import info, error -from valhalla.version.version_to_release import VersionToRelease, ReleaseKind - -BASE_PREFIX = "release-" +from valhalla.version.version_to_release import VersionToRelease, ReleaseKind, BASE_PREFIX, \ + get_version_to_release_from_str def get_version_to_release(release_kinds: List[ReleaseKind]) -> VersionToRelease: @@ -13,24 +12,8 @@ def get_version_to_release(release_kinds: List[ReleaseKind]) -> VersionToRelease if ci_commit_branch: info(f'Name of branch is: {ci_commit_branch}') - if ci_commit_branch.startswith('release-'): - - # first we search for specific release kinds - for release_kind in release_kinds: - if release_kind.suffix != "": - prefix = __get_branch_prefix(release_kind) - if ci_commit_branch.startswith(prefix): - return __matched(ci_commit_branch, prefix, release_kind) - - # now if specific release kind not found we search for main - for release_kind in release_kinds: - if release_kind.suffix == "": - prefix = BASE_PREFIX - if ci_commit_branch.startswith(prefix): - return __matched(ci_commit_branch, prefix, release_kind) - - __no_matching_release_kind(ci_commit_branch, release_kinds) - + if ci_commit_branch.startswith(BASE_PREFIX): + return get_version_to_release_from_str(ci_commit_branch, release_kinds) else: error('This is not a release branch! This script should not be run! The name of the branch must be ' 'release-X.X.X') @@ -40,30 +23,3 @@ def get_version_to_release(release_kinds: List[ReleaseKind]) -> VersionToRelease error('CI_COMMIT_BRANCH environment variable is not set. Are you using GitLab CI? If not change your ' 'valhalla configration!') exit(-1) - - -def __get_branch_prefix(release_kind: ReleaseKind) -> str: - prefix = (BASE_PREFIX + release_kind.suffix).replace("--", "-") - if prefix.endswith("-"): - return prefix - else: - return prefix + "-" - - -def __matched(ci_commit_branch: str, prefix: str, release_kind: ReleaseKind) -> VersionToRelease: - info(f"Branch name {ci_commit_branch} has prefix {prefix} and matches with release kind {release_kind}") - project_version = ci_commit_branch[len(prefix):] - info(f'Project version that is going to be released: {project_version}') - return VersionToRelease(project_version, release_kind) - - -def __no_matching_release_kind(ci_commit_branch: str, release_kinds: List[ReleaseKind]): - error('This is a release branch, but valhalla could not find matching valhalla.yml file!') - error(f'Name of branch is: {ci_commit_branch}') - for kind in release_kinds: - error(f'Available release kind: {kind}') - prefix = __get_branch_prefix(kind) - error(f'To match this release kind you branch must starts with {prefix} f.e {prefix}1.5.3') - - error('Create branch name with correct prefix to the release kind that you want to match with and start!') - exit(-1) diff --git a/valhalla/main.py b/valhalla/main.py index dd1b845..8225957 100644 --- a/valhalla/main.py +++ b/valhalla/main.py @@ -6,18 +6,18 @@ from valhalla.commit.commit import GitRepository from valhalla.common.get_config import get_config, CommitConfig, MergeRequestConfig, Config from valhalla.common.logger import info, init_logger +from valhalla.version.release_command import get_version_to_release_from_command from valhalla.common.resolver import init_str_resolver, init_str_resolver_custom_variables from valhalla.release.assets import Assets from valhalla.release.description import Description -from valhalla.version.version_to_release import get_release_kinds +from valhalla.version.version_to_release import get_release_kinds, VersionToRelease def start(): print(f'Release the Valhalla!') - release_kinds = get_release_kinds(".") + version_to_release = __version_to_release() - version_to_release = get_version_to_release(release_kinds) token = get_valhalla_token() init_logger(token) @@ -35,6 +35,16 @@ def start(): create_merge_request(config.merge_request) +def __version_to_release() -> VersionToRelease: + release_kinds = get_release_kinds(".") + version_to_release = get_version_to_release_from_command(release_kinds) + + if version_to_release is None: + version_to_release = get_version_to_release(release_kinds) + + return version_to_release + + def create_merge_request(merge_request_config: MergeRequestConfig): if merge_request_config is None: info("merge_request not specified in valhalla.yml, skipping") diff --git a/valhalla/version/release_command.py b/valhalla/version/release_command.py new file mode 100644 index 0000000..c28209d --- /dev/null +++ b/valhalla/version/release_command.py @@ -0,0 +1,23 @@ +import os +from typing import List + +from valhalla.common.logger import info, error +from valhalla.version.version_to_release import ReleaseKind, VersionToRelease, BASE_PREFIX, \ + get_version_to_release_from_str + + +def get_version_to_release_from_command(release_kinds: List[ReleaseKind]) -> VersionToRelease | None: + command = os.environ.get('VALHALLA_RELEASE_CMD') + + if command: + info(f'Value of VALHALLA_RELEASE_CMD is: {command}') + + if command.startswith(BASE_PREFIX): + return get_version_to_release_from_str(command, release_kinds) + else: + error( + 'This is not a correct release command! VALHALLA_RELEASE_CMD should start from release- prefix, f.e. release-1.2.3') + exit(-1) + else: + info("Cloud not find VALHALLA_RELEASE_CMD environment variable, skipping and going to check branch name") + return None diff --git a/valhalla/version/version_to_release.py b/valhalla/version/version_to_release.py index 3e07ce9..77fe8d7 100644 --- a/valhalla/version/version_to_release.py +++ b/valhalla/version/version_to_release.py @@ -5,6 +5,8 @@ from valhalla.common.logger import info, error +BASE_PREFIX = "release-" + class ReleaseKind: @@ -50,3 +52,54 @@ def get_release_kinds(path: str) -> List[ReleaseKind]: exit(-1) return release_kinds + + +def get_version_to_release_from_str(value: str, release_kinds: List[ReleaseKind]) -> VersionToRelease: + info(f"Analyzing {value} to match release kind") + # first we search for specific release kinds + for release_kind in release_kinds: + if release_kind.suffix != "": + prefix = __get_branch_prefix(release_kind) + if value.startswith(prefix): + return __matched(value, prefix, release_kind) + + info(f"{value} doesn't match specific release kind, checking main kind") + # now if specific release kind not found we search for main + for release_kind in release_kinds: + if release_kind.suffix == "": + prefix = BASE_PREFIX + if value.startswith(prefix): + return __matched(value, prefix, release_kind) + + __no_matching_release_kind(value, release_kinds) + + +def __get_branch_prefix(release_kind: ReleaseKind) -> str: + prefix = (BASE_PREFIX + release_kind.suffix).replace("--", "-") + if prefix.endswith("-"): + return prefix + else: + return prefix + "-" + + +def __matched(value: str, prefix: str, release_kind: ReleaseKind) -> VersionToRelease: + info( + f"Branch name or VALHALLA_RELEASE_CMD is {value} and has prefix {prefix} and matches with release kind {release_kind}") + project_version = value[len(prefix):] + info(f'Project version that is going to be released: {project_version}') + return VersionToRelease(project_version, release_kind) + + +def __no_matching_release_kind(value: str, release_kinds: List[ReleaseKind]): + error( + 'This is a release branch or VALHALLA_RELEASE_CMD was used, but valhalla could not find matching valhalla.yml file!') + error(f'Name of branch or VALHALLA_RELEASE_CMD is: {value}') + for kind in release_kinds: + error(f'Available release kind: {kind}') + prefix = __get_branch_prefix(kind) + error( + f'To match this release kind your branch or VALHALLA_RELEASE_CMD must starts with {prefix} f.e {prefix}1.5.3') + + error( + 'Create branch or use VALHALLA_RELEASE_CMD with correct prefix to the release kind that you want to match with and start!') + exit(-1)