Skip to content

Commit

Permalink
added ability to extend valhalla.yml configs and keep global configur…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
marwin1991 committed Dec 16, 2023
1 parent 00cb8b0 commit a3b6370
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 6 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ saving time, and promoting compliance with established regulations.

### ⚙️ configuration

- if using GitLab workflows
for `merge requests workflow` [(link)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml)
you have to add `if: '$CI_COMMIT_BRANCH =~ /^release-*/` to global workflow configuration
- create `valhalla.yml` in your project (check out [examples](https://github.com/logchange/valhalla/tree/master/examples))
```yml
# This file is used by valhalla tool to create release 🌌
# Visit https://github.com/logchange/valhalla and leave a star 🌟
# More info about configuration you can find https://github.com/logchange/valhalla#%EF%B8%8F-configuration ⬅️
extends: # You can extend any file from URL! This helps keep configuration in one place!
- https://raw.githubusercontent.com/logchange/valhalla/master/valhalla-extends.yml
git_host: gitlab # your project ci provider, supported [gitlab]
commit_before_release: # define actions which have to happen before release and output should be committed
enabled: True # if this is True commands from before will be performed and committed to branch
Expand Down Expand Up @@ -82,6 +81,20 @@ merge_request:
extensions like `release-2.10.4-RC`.
2. Valhalla will do everything for you 🚀

### inheritance

To simplify managing multimple repositories, you can use `extends:` keyword.

```yml
extends:
- https://raw.githubusercontent.com/logchange/valhalla/master/valhalla.yml
```

You can point to any URL that is `valhalla.yml` and it will be loaded and then override by values from
current file. Currently, you can only inherit once, co it means if you inherit from a file, that also contains
`extends` keyword, it won't be evaluated.


### 🖖 string predefined variables

**Use `{}` to evaluate variable to value f.e. `{VERSION}`**
Expand All @@ -92,14 +105,16 @@ merge_request:

### 🦊 .gitlab-ci.yml

- you have to add `if: '$CI_COMMIT_BRANCH =~ /^release-*/` to global workflow configuration
- if using GitLab workflows
for `merge requests workflow` [(link)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml)
you have to add `if: '$CI_COMMIT_BRANCH =~ /^release-*/` to global workflow configuration
```yml
workflows:
if: '$CI_COMMIT_BRANCH =~ /^release-*/

release:
stage:
stage:

```
Empty file added test/extends/__init__.py
Empty file.
85 changes: 85 additions & 0 deletions test/extends/merge_dicts_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import unittest

from valhalla.extends.merge_dicts import merge


class MergeDictsTest(unittest.TestCase):

def test_merge_dicts(self):
parent = {
"commit_before_release": {
"msg": "ABC Releasing version {VERSION}",
"before": [
"parent element 1",
"parent element 2"
],
},
"merge_request": {
"title": "parent title",
"description": "parent description",
},
}

child = {
"extends": [
"https://raw.githubusercontent.com/logchange/valhalla/master/valhalla-extends.yml"
],
"git_host": "gitlab",
"commit_before_release": {
"enabled": True,
"username": "Test1234",
"email": "test-valhalla@logchange.dev",
"msg": "Releasing version {VERSION}",
"before": [
"child element 1",
"child element 2",
"child element 3"
],
},
"release": {
"description": {
"from_command": "cat changelog / v{VERSION} / version_summary.md"
},
"assets": {
"links": [
{
"name": "Documentation",
"url": "https: // google.com / q?={VERSION}",
"link_type": "other",
},
{
"name": "Docker Image",
"url": "https://dockerhub.com/q?={VERSION}",
"link_type": "image",
},
]
},
},
"commit_after_release": {
"enabled": True,
"username": "Test1234",
"email": "test-valhalla@logchange.dev",
"msg": "Preparation for next development cycle",
"before": ['echo "test" > prepare_next_iteration.md'],
},
"merge_request": {
"enabled": True,
"title": "child title",
"reviewers": ["peter.zmilczak", "some_uknownwnnaa"],
},
}

result = merge(parent, child)

self.assertEqual(result['extends'],
['https://raw.githubusercontent.com/logchange/valhalla/master/valhalla-extends.yml'])
self.assertEqual(result['git_host'], 'gitlab')

self.assertEqual(result['commit_before_release']['before'], [
"child element 1",
"child element 2",
"child element 3"
])

self.assertEqual(result['merge_request']['title'], 'child title')
self.assertEqual(result['merge_request']['description'], 'parent description')
5 changes: 5 additions & 0 deletions valhalla.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# This file is used by valhalla tool to create release 🌌
# Visit https://github.com/logchange/valhalla and leave a star 🌟
# More info about configuration you can find https://github.com/logchange/valhalla#%EF%B8%8F-configuration ⬅️
extends:
- https://raw.githubusercontent.com/logchange/valhalla/master/valhalla-extends.yml
git_host: gitlab
commit_before_release:
enabled: True
Expand Down
8 changes: 7 additions & 1 deletion valhalla/common/get_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from yaml import safe_load

from valhalla.common.logger import info, error, warn
from valhalla.extends.ValhallaExtends import ValhallaExtends


class MergeRequestConfig:
Expand Down Expand Up @@ -90,7 +91,8 @@ def __repr__(self):


class Config:
def __init__(self, git_host: str,
def __init__(self,
git_host: str,
commit_before_release: CommitConfig,
release_config: ReleaseConfig,
commit_after_release: CommitConfig,
Expand All @@ -117,6 +119,10 @@ def get_config(path) -> Config:
info(f"Trying to load config from: {path}")
yml_dict = safe_load(f)

extends_list = get_from_dict(yml_dict, 'extends', False)
extends = ValhallaExtends(extends_list)
yml_dict = extends.merge(yml_dict)

git_host = yml_dict['git_host']

commit_before_release_dict = yml_dict['commit_before_release']
Expand Down
43 changes: 43 additions & 0 deletions valhalla/extends/ValhallaExtends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from typing import List

import urllib.request
from yaml import safe_load

from valhalla.common.logger import info, error
from valhalla.extends.merge_dicts import merge


def get_from_url(url):
result = ""
data = urllib.request.urlopen(url)
for line in data:
str_line = line.decode("UTF-8")
result += str_line
info("Loaded from ULR")
info("===========================================")
print(result)
info("===========================================")
return result


class ValhallaExtends:

def __init__(self, extends: List[str]):
self.extends = extends

def merge(self, valhalla_yml_dict: dict) -> dict:
if self.extends is None or len(self.extends) < 1:
info("There is nothing to extend")
return valhalla_yml_dict
elif len(self.extends) == 1:
info("There is one file to extend")
extended = get_from_url(self.extends[0])
extended_dict = safe_load(extended)
info("yml data as dictionary to extends: " + str(extended_dict))
info("yml data from valhalla.yml: " + str(valhalla_yml_dict))
result = merge(extended_dict, valhalla_yml_dict)
info("final yml data: " + str(result))
return result
else:
error("Currently you can extend only from one url!")
exit(1)
Empty file added valhalla/extends/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions valhalla/extends/merge_dicts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import copy


def merge(parent: dict, child: dict):
parent_copy = copy.deepcopy(parent)
child_copy = copy.deepcopy(child)

return __merge(parent_copy, child_copy)


def __merge(parent_org: dict, child_org: dict):
parent_copy = copy.deepcopy(parent_org)
child_copy = copy.deepcopy(child_org)

if isinstance(child_copy, dict):
for k, v in child_copy.items():
if k in parent_copy:
parent_copy[k] = __merge(parent_copy.get(k), v)
else:
parent_copy[k] = v
return parent_copy
else:
return child_copy

0 comments on commit a3b6370

Please sign in to comment.