Skip to content

Commit

Permalink
feat: use customizable message templates for PR comments (#175)
Browse files Browse the repository at this point in the history
* feat: use customizable message templates for PR comments

* use default messages for v0 / v1 config

* update documenation / use more descriptive property path

* make pylint and black accept the formatting

Co-authored-by: Leon König <[email protected]>
  • Loading branch information
koenigle and Leon König committed Apr 7, 2022
1 parent 0d0adc7 commit e859006
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 22 deletions.
5 changes: 5 additions & 0 deletions docs/includes/preview-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ Make sure that your *app repository* contains a `.gitops.config.yaml` file. This
2. templates for host and namespace name
3. replace values in template files
4. find repository and branch where the preview should be created (i.e. your *deployment config repository*)
5. message templates used to comment your pull request

```yaml
apiVersion: v2
applicationName: app-xy
# messages: # optional section
# previewEnvCreated: "Created preview at revision ${GIT-HASH}. You can access it here: https://${PREVIEW_HOST}/some-fancy-path" # optional (default: "New preview environment created for version `${GIT_HASH}`. Access it here: https://${PREVIEW_HOST}")
# previewEnvUpdated: "Updated preview to revision ${GIT-HASH}. You can access it here: https://${PREVIEW_HOST}/some-fancy-path" # optional (default: "Preview environment updated to version `${GIT_HASH}`. Access it here: https://${PREVIEW_HOST}")
# previewEnvAlreadyUpToDate: "Your preview is already up-to-date with revision ${GIT-HASH}." # optional (default: "The version `${GIT_HASH}` has already been deployed. Access it here: https://${PREVIEW_HOST}")
previewConfig:
host: ${PREVIEW_NAMESPACE}.example.tld
# template: # optional section
Expand Down
12 changes: 3 additions & 9 deletions gitopscli/commands/create_pr_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,8 @@ def execute(self) -> None:
),
)
create_preview_command.register_callbacks(
deployment_already_up_to_date_callback=lambda preview_host: add_pr_comment(
f"The version `{git_hash}` has already been deployed. Access it here: https://{preview_host}",
),
deployment_updated_callback=lambda preview_host: add_pr_comment(
f"Preview environment updated to version `{git_hash}`. Access it here: https://{preview_host}"
),
deployment_created_callback=lambda preview_host: add_pr_comment(
f"New preview environment created for version `{git_hash}`. Access it here: https://{preview_host}"
),
deployment_already_up_to_date_callback=add_pr_comment,
deployment_updated_callback=add_pr_comment,
deployment_created_callback=add_pr_comment,
)
create_preview_command.execute()
14 changes: 8 additions & 6 deletions gitopscli/commands/create_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def register_callbacks(
def execute(self,) -> None:
gitops_config = self.__get_gitops_config()
self.__create_preview_info_file(gitops_config)
preview_host = gitops_config.get_preview_host(self.__args.preview_id)

preview_target_git_repo_api = self.__create_preview_target_git_repo_api(gitops_config)
with GitRepo(preview_target_git_repo_api) as preview_target_git_repo:
Expand All @@ -62,9 +61,12 @@ def execute(self,) -> None:
)

any_values_replaced = self.__replace_values(preview_target_git_repo, gitops_config)
context = GitOpsConfig.Replacement.PreviewContext(
gitops_config, self.__args.preview_id, self.__args.git_hash
)

if not created_new_preview and not any_values_replaced:
self.__deployment_already_up_to_date_callback(preview_host)
self.__deployment_already_up_to_date_callback(gitops_config.get_uptodate_message(context))
logging.info("The preview is already up-to-date. I'm done here.")
return

Expand All @@ -74,10 +76,10 @@ def execute(self,) -> None:
f"'{gitops_config.application_name}' and git hash '{self.__args.git_hash}'.",
)

if created_new_preview:
self.__deployment_created_callback(preview_host)
else:
self.__deployment_updated_callback(preview_host)
if created_new_preview:
self.__deployment_created_callback(gitops_config.get_created_message(context))
else:
self.__deployment_updated_callback(gitops_config.get_updated_message(context))

def __commit_and_push(self, git_repo: GitRepo, message: str) -> None:
git_repo.commit(self.__args.git_user, self.__args.git_email, message)
Expand Down
49 changes: 49 additions & 0 deletions gitopscli/gitops_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import hashlib
from dataclasses import dataclass
from typing import List, Any, Optional, Dict, Callable, Set
from string import Template

from gitopscli.gitops_exception import GitOpsException

Expand Down Expand Up @@ -52,6 +53,10 @@ def get_value(self, context: PreviewContext) -> str:

preview_host_template: str

messages_created_template: str
messages_updated_template: str
messages_uptodate_template: str

preview_template_organisation: str
preview_template_repository: str
preview_template_path_template: str
Expand Down Expand Up @@ -140,6 +145,26 @@ def get_preview_namespace(self, preview_id: str) -> str:
raise GitOpsException(f"Invalid character in preview namespace: '{invalid_character[0]}'")
return preview_namespace

def get_created_message(self, context: Replacement.PreviewContext) -> str:
return self.fill_template(self.messages_created_template, context)

def get_updated_message(self, context: Replacement.PreviewContext) -> str:
return self.fill_template(self.messages_updated_template, context)

def get_uptodate_message(self, context: Replacement.PreviewContext) -> str:
return self.fill_template(self.messages_uptodate_template, context)

def fill_template(self, template: str, context: Replacement.PreviewContext) -> str:
return Template(template).substitute(
APPLICATION_NAME=self.application_name,
PREVIEW_ID_HASH=self.create_preview_id_hash(context.preview_id),
PREVIEW_ID_HASH_SHORT=self.create_preview_id_hash_short(context.preview_id),
PREVIEW_ID=self.__sanitize(context.preview_id),
PREVIEW_NAMESPACE=self.get_preview_namespace(context.preview_id),
PREVIEW_HOST=self.get_preview_host(context.preview_id),
GIT_HASH=context.git_hash,
)

@staticmethod
def __assert_variables(template: str, variables: Set[str]) -> None:
for var in _VARIABLE_REGEX.findall(template):
Expand Down Expand Up @@ -278,6 +303,12 @@ def __parse_v0(self) -> GitOpsConfig:
return GitOpsConfig(
api_version=0,
application_name=self.__get_string_value("deploymentConfig.applicationName"),
messages_created_template="New preview environment created for version `${GIT_HASH}`. "
+ "Access it here: https://${PREVIEW_HOST}",
messages_updated_template="Preview environment updated to version `${GIT_HASH}`. "
+ "Access it here: https://${PREVIEW_HOST}",
messages_uptodate_template="The version `${GIT_HASH}` has already been deployed. "
+ "Access it here: https://${PREVIEW_HOST}",
preview_host_template=self.__get_string_value("previewConfig.route.host.template").replace(
"{SHA256_8CHAR_BRANCH_HASH}", "${PREVIEW_ID_HASH}" # backwards compatibility
),
Expand Down Expand Up @@ -305,6 +336,12 @@ def __parse_v1(self) -> GitOpsConfig:
return GitOpsConfig(
api_version=1,
application_name=config.application_name,
messages_created_template="New preview environment created for version `${GIT_HASH}`. "
+ "Access it here: https://${PREVIEW_HOST}",
messages_updated_template="Preview environment updated to version `${GIT_HASH}`. "
+ "Access it here: https://${PREVIEW_HOST}",
messages_uptodate_template="The version `${GIT_HASH}` has already been deployed. "
+ "Access it here: https://${PREVIEW_HOST}",
preview_host_template=add_var_dollar(config.preview_host_template),
preview_template_organisation=config.preview_template_organisation,
preview_template_repository=config.preview_template_repository,
Expand Down Expand Up @@ -358,6 +395,18 @@ def __parse_v2(self) -> GitOpsConfig:
return GitOpsConfig(
api_version=2,
application_name=self.__get_string_value("applicationName"),
messages_created_template=self.__get_string_value_or_default(
"messages.previewEnvCreated",
"New preview environment created for version `${GIT_HASH}`. Access it here: https://${PREVIEW_HOST}",
),
messages_updated_template=self.__get_string_value_or_default(
"messages.previewEnvUpdated",
"Preview environment updated to version `${GIT_HASH}`. Access it here: https://${PREVIEW_HOST}",
),
messages_uptodate_template=self.__get_string_value_or_default(
"messages.previewEnvAlreadyUpToDate",
"The version `${GIT_HASH}` has already been deployed. Access it here: https://${PREVIEW_HOST}",
),
preview_host_template=self.__get_string_value("previewConfig.host"),
preview_template_organisation=self.__get_string_value_or_default(
"previewConfig.template.organisation", preview_target_organisation
Expand Down
12 changes: 9 additions & 3 deletions tests/commands/test_create_pr_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ def test_create_pr_preview(self):
]

self.mock_manager.reset_mock()
deployment_already_up_to_date_callback("my-route.baloise.com")
deployment_already_up_to_date_callback(
"The version `5f65cfa04c66444fcb756d6d7f39304d1c18b199` has already been deployed. Access it here: https://my-route.baloise.com"
)
assert self.mock_manager.method_calls == [
call.GitRepoApi.add_pull_request_comment(
4711,
Expand All @@ -85,7 +87,9 @@ def test_create_pr_preview(self):
]

self.mock_manager.reset_mock()
deployment_updated_callback("my-route.baloise.com")
deployment_updated_callback(
"Preview environment updated to version `5f65cfa04c66444fcb756d6d7f39304d1c18b199`. Access it here: https://my-route.baloise.com"
)
assert self.mock_manager.method_calls == [
call.GitRepoApi.add_pull_request_comment(
4711,
Expand All @@ -96,7 +100,9 @@ def test_create_pr_preview(self):
]

self.mock_manager.reset_mock()
deployment_created_callback("my-route.baloise.com")
deployment_created_callback(
"New preview environment created for version `5f65cfa04c66444fcb756d6d7f39304d1c18b199`. Access it here: https://my-route.baloise.com"
)
assert self.mock_manager.method_calls == [
call.GitRepoApi.add_pull_request_comment(
4711,
Expand Down
14 changes: 10 additions & 4 deletions tests/commands/test_create_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def setUp(self):
self.load_gitops_config_mock.return_value = GitOpsConfig(
api_version=2,
application_name="my-app",
messages_created_template="created template ${PREVIEW_ID_HASH}",
messages_updated_template="updated template ${PREVIEW_ID_HASH}",
messages_uptodate_template="uptodate template ${PREVIEW_ID_HASH}",
preview_host_template="app.xy-${PREVIEW_ID_HASH}.example.tld",
preview_template_organisation="PREVIEW_TEMPLATE_ORG",
preview_template_repository="PREVIEW_TEMPLATE_REPO",
Expand Down Expand Up @@ -130,7 +133,7 @@ def test_create_new_preview(self):
)
command.execute()

deployment_created_callback.assert_called_once_with("app.xy-685912d3.example.tld")
deployment_created_callback.assert_called_once_with("created template 685912d3")

assert self.mock_manager.method_calls == [
call.load_gitops_config(ARGS, "ORGA", "REPO",),
Expand Down Expand Up @@ -200,6 +203,9 @@ def test_create_new_preview_from_same_template_target_repo(self):
self.load_gitops_config_mock.return_value = GitOpsConfig(
api_version=gitops_config.api_version,
application_name=gitops_config.application_name,
messages_created_template=gitops_config.messages_created_template,
messages_updated_template=gitops_config.messages_updated_template,
messages_uptodate_template=gitops_config.messages_uptodate_template,
preview_host_template=gitops_config.preview_host_template,
preview_template_organisation=gitops_config.preview_target_organisation, # template = target
preview_template_repository=gitops_config.preview_target_repository, # template = target
Expand Down Expand Up @@ -228,7 +234,7 @@ def test_create_new_preview_from_same_template_target_repo(self):
)
command.execute()

deployment_created_callback.assert_called_once_with("app.xy-685912d3.example.tld")
deployment_created_callback.assert_called_once_with("created template 685912d3")

assert self.mock_manager.method_calls == [
call.load_gitops_config(ARGS, "ORGA", "REPO",),
Expand Down Expand Up @@ -307,7 +313,7 @@ def test_update_existing_preview(self):
)
command.execute()

deployment_updated_callback.assert_called_once_with("app.xy-685912d3.example.tld")
deployment_updated_callback.assert_called_once_with("updated template 685912d3")

assert self.mock_manager.method_calls == [
call.load_gitops_config(ARGS, "ORGA", "REPO",),
Expand Down Expand Up @@ -375,7 +381,7 @@ def test_preview_already_up_to_date(self):
)
command.execute()

deployment_already_up_to_date_callback.assert_called_once_with("app.xy-685912d3.example.tld")
deployment_already_up_to_date_callback.assert_called_once_with("uptodate template 685912d3")

assert self.mock_manager.method_calls == [
call.load_gitops_config(ARGS, "ORGA", "REPO",),
Expand Down
3 changes: 3 additions & 0 deletions tests/commands/test_delete_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def setUp(self):
self.load_gitops_config_mock.return_value = GitOpsConfig(
api_version=0,
application_name="APP",
messages_created_template="created template ${PREVIEW_ID_HASH}",
messages_updated_template="updated template ${PREVIEW_ID_HASH}",
messages_uptodate_template="uptodate template ${PREVIEW_ID_HASH}",
preview_host_template="www.foo.bar",
preview_template_organisation="PREVIEW_TEMPLATE_ORG",
preview_template_repository="PREVIEW_TEMPLATE_REPO",
Expand Down

0 comments on commit e859006

Please sign in to comment.