From ade7a41e7b317f85695e95dba22c350239a5881d Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 8 Dec 2022 16:39:23 -0500 Subject: [PATCH] added git creds for pushing on publish w/ burnettk cullerton --- bin/save_all_bpmn.py | 4 +- src/spiffworkflow_backend/config/__init__.py | 30 ++++--- src/spiffworkflow_backend/config/demo.py | 4 +- src/spiffworkflow_backend/config/dev.py | 6 ++ .../config/terraform_deployed_environment.py | 4 +- .../routes/process_api_blueprint.py | 8 +- .../services/file_system_service.py | 13 +++ .../services/git_service.py | 89 ++++++++++--------- .../integration/test_process_api.py | 20 ++--- 9 files changed, 105 insertions(+), 73 deletions(-) create mode 100644 src/spiffworkflow_backend/config/dev.py diff --git a/bin/save_all_bpmn.py b/bin/save_all_bpmn.py index 54a40841..fd44bb54 100644 --- a/bin/save_all_bpmn.py +++ b/bin/save_all_bpmn.py @@ -1,13 +1,13 @@ """Grabs tickets from csv and makes process instances.""" import os -from spiffworkflow_backend import get_hacked_up_app_for_script +from spiffworkflow_backend import create_app from spiffworkflow_backend.services.data_setup_service import DataSetupService def main() -> None: """Main.""" - app = get_hacked_up_app_for_script() + app = create_app() with app.app_context(): failing_process_models = DataSetupService.save_all_process_models() for bpmn_errors in failing_process_models: diff --git a/src/spiffworkflow_backend/config/__init__.py b/src/spiffworkflow_backend/config/__init__.py index 4bd175a7..106b0735 100644 --- a/src/spiffworkflow_backend/config/__init__.py +++ b/src/spiffworkflow_backend/config/__init__.py @@ -38,6 +38,17 @@ def setup_database_uri(app: Flask) -> None: ) +def load_config_file(app: Flask, env_config_module: str) -> None: + """Load_config_file.""" + try: + app.config.from_object(env_config_module) + except ImportStringError as exception: + if os.environ.get("TERRAFORM_DEPLOYED_ENVIRONMENT") != "true": + raise ModuleNotFoundError( + f"Cannot find config module: {env_config_module}" + ) from exception + + def setup_config(app: Flask) -> None: """Setup_config.""" # ensure the instance folder exists @@ -53,19 +64,14 @@ def setup_config(app: Flask) -> None: app.config.from_object("spiffworkflow_backend.config.default") env_config_prefix = "spiffworkflow_backend.config." + if ( + os.environ.get("TERRAFORM_DEPLOYED_ENVIRONMENT") == "true" + and os.environ.get("SPIFFWORKFLOW_BACKEND_ENV") is not None + ): + load_config_file(app, f"{env_config_prefix}terraform_deployed_environment") + env_config_module = env_config_prefix + app.config["ENV_IDENTIFIER"] - try: - app.config.from_object(env_config_module) - except ImportStringError as exception: - if ( - os.environ.get("TERRAFORM_DEPLOYED_ENVIRONMENT") == "true" - and os.environ.get("SPIFFWORKFLOW_BACKEND_ENV") is not None - ): - app.config.from_object(f"{env_config_prefix}terraform_deployed_environment") - else: - raise ModuleNotFoundError( - f"Cannot find config module: {env_config_module}" - ) from exception + load_config_file(app, env_config_module) # This allows config/testing.py or instance/config.py to override the default config if "ENV_IDENTIFIER" in app.config and app.config["ENV_IDENTIFIER"] == "testing": diff --git a/src/spiffworkflow_backend/config/demo.py b/src/spiffworkflow_backend/config/demo.py index db5abf0e..06e9184d 100644 --- a/src/spiffworkflow_backend/config/demo.py +++ b/src/spiffworkflow_backend/config/demo.py @@ -2,8 +2,8 @@ from os import environ GIT_COMMIT_ON_SAVE = True -GIT_COMMIT_USERNAME = "demo" -GIT_COMMIT_EMAIL = "demo@example.com" +GIT_USERNAME = "demo" +GIT_USER_EMAIL = "demo@example.com" SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get( "SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME", default="terraform_deployed_environment.yml", diff --git a/src/spiffworkflow_backend/config/dev.py b/src/spiffworkflow_backend/config/dev.py new file mode 100644 index 00000000..f20189e9 --- /dev/null +++ b/src/spiffworkflow_backend/config/dev.py @@ -0,0 +1,6 @@ +"""dev.""" +from os import environ + +GIT_MERGE_BRANCH = environ.get("GIT_MERGE_BRANCH", default="staging") +GIT_USERNAME = environ.get("GIT_USERNAME", default="sartography-automated-committer") +GIT_USER_EMAIL = environ.get("GIT_USER_EMAIL", default="sartography-automated-committer@users.noreply.github.com") diff --git a/src/spiffworkflow_backend/config/terraform_deployed_environment.py b/src/spiffworkflow_backend/config/terraform_deployed_environment.py index 458e541c..4310d76a 100644 --- a/src/spiffworkflow_backend/config/terraform_deployed_environment.py +++ b/src/spiffworkflow_backend/config/terraform_deployed_environment.py @@ -5,8 +5,8 @@ from os import environ environment_identifier_for_this_config_file_only = environ["SPIFFWORKFLOW_BACKEND_ENV"] GIT_COMMIT_ON_SAVE = True -GIT_COMMIT_USERNAME = environment_identifier_for_this_config_file_only -GIT_COMMIT_EMAIL = f"{environment_identifier_for_this_config_file_only}@example.com" +GIT_USERNAME = environment_identifier_for_this_config_file_only +GIT_USER_EMAIL = f"{environment_identifier_for_this_config_file_only}@example.com" SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get( "SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME", default="terraform_deployed_environment.yml", diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index b804563f..b4437ef8 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -371,12 +371,14 @@ def process_model_move( def process_model_publish( - modified_process_model_identifier: str, - branch_to_update: Optional[str] = None + modified_process_model_identifier: str, branch_to_update: Optional[str] = None ) -> flask.wrappers.Response: + """Process_model_publish.""" if branch_to_update is None: branch_to_update = current_app.config["GIT_MERGE_BRANCH"] - process_model_identifier = un_modify_modified_process_model_id(modified_process_model_identifier) + process_model_identifier = un_modify_modified_process_model_id( + modified_process_model_identifier + ) pr_url = GitService().publish(process_model_identifier, branch_to_update) data = {"ok": True, "pr_url": pr_url} return Response(json.dumps(data), status=200, mimetype="application/json") diff --git a/src/spiffworkflow_backend/services/file_system_service.py b/src/spiffworkflow_backend/services/file_system_service.py index ccf992e4..0567120d 100644 --- a/src/spiffworkflow_backend/services/file_system_service.py +++ b/src/spiffworkflow_backend/services/file_system_service.py @@ -1,5 +1,6 @@ """File_system_service.""" import os +from contextlib import contextmanager from datetime import datetime from typing import List from typing import Optional @@ -23,6 +24,18 @@ class FileSystemService: PROCESS_GROUP_JSON_FILE = "process_group.json" PROCESS_MODEL_JSON_FILE = "process_model.json" + # https://stackoverflow.com/a/24176022/6090676 + @contextmanager + @staticmethod + def cd(newdir): + """Cd.""" + prevdir = os.getcwd() + os.chdir(os.path.expanduser(newdir)) + try: + yield + finally: + os.chdir(prevdir) + @staticmethod def root_path() -> str: """Root_path.""" diff --git a/src/spiffworkflow_backend/services/git_service.py b/src/spiffworkflow_backend/services/git_service.py index 27d94025..d0d45918 100644 --- a/src/spiffworkflow_backend/services/git_service.py +++ b/src/spiffworkflow_backend/services/git_service.py @@ -1,8 +1,8 @@ """Git_service.""" - import os import shutil import uuid +from typing import Optional from flask import current_app from flask import g @@ -44,64 +44,69 @@ class GitService: return file_contents.encode("utf-8") @staticmethod - def commit(message: str) -> str: + def commit(message: str, repo_path: Optional[str]) -> str: """Commit.""" - bpmn_spec_absolute_dir = current_app.config["BPMN_SPEC_ABSOLUTE_DIR"] + repo_path_to_use = repo_path + if repo_path is None: + repo_path_to_use = current_app.config["BPMN_SPEC_ABSOLUTE_DIR"] + git_username = "" git_email = "" - if ( - current_app.config["GIT_COMMIT_USERNAME"] - and current_app.config["GIT_COMMIT_EMAIL"] - ): - git_username = current_app.config["GIT_COMMIT_USERNAME"] - git_email = current_app.config["GIT_COMMIT_EMAIL"] - shell_command = f"./bin/git_commit_bpmn_models_repo '{bpmn_spec_absolute_dir}' '{message}' '{git_username}' '{git_email}'" + if current_app.config["GIT_USERNAME"] and current_app.config["GIT_USER_EMAIL"]: + git_username = current_app.config["GIT_USERNAME"] + git_email = current_app.config["GIT_USER_EMAIL"] + shell_command_path = os.path.join( + current_app.root_path, "..", "..", "bin", "git_commit_bpmn_models_repo" + ) + shell_command = f"{shell_command_path} '{repo_path_to_use}' '{message}' '{git_username}' '{git_email}'" output = os.popen(shell_command).read() # noqa: S605 return output - @staticmethod - def publish(process_model_id: str, branch_to_update: str) -> str: + @classmethod + def publish(cls, process_model_id: str, branch_to_update: str) -> str: + """Publish.""" source_process_model_root = FileSystemService.root_path() - source_process_model_path = os.path.join(source_process_model_root, process_model_id) + source_process_model_path = os.path.join( + source_process_model_root, process_model_id + ) unique_hex = uuid.uuid4().hex clone_dir = f"sample-process-models.{unique_hex}" # clone new instance of sample-process-models, checkout branch_to_update - os.chdir("/tmp") destination_process_root = f"/tmp/{clone_dir}" - os.system(f"git clone https://github.com/sartography/sample-process-models.git {clone_dir}") - os.chdir(destination_process_root) + os.system( + f"git clone https://{current_app.config['GIT_USERNAME']}:{current_app.config['GIT_USER_PASSWORD']}@github.com/sartography/sample-process-models.git {destination_process_root}" + ) + with FileSystemService.cd(destination_process_root): + # create publish branch from branch_to_update + os.system(f"git checkout {branch_to_update}") # noqa: S605 + publish_branch = f"publish-{process_model_id}" + command = f"git show-ref --verify refs/remotes/origin/{publish_branch}" + output = os.popen(command).read() # noqa: S605 + if output: + os.system(f"git checkout {publish_branch}") + else: + os.system(f"git checkout -b {publish_branch}") # noqa: S605 - # create publish branch from branch_to_update - os.system(f"git checkout {branch_to_update}") # noqa: S605 - publish_branch = f"publish-{process_model_id}" - command = f"git show-ref --verify refs/remotes/origin/{publish_branch}" - output = os.popen(command).read() # noqa: S605 - if output: - os.system(f"git checkout {publish_branch}") - else: - os.system(f"git checkout -b {publish_branch}") # noqa: S605 + # copy files from process model into the new publish branch + destination_process_model_path = os.path.join( + destination_process_root, process_model_id + ) + if os.path.exists(destination_process_model_path): + shutil.rmtree(destination_process_model_path) + shutil.copytree(source_process_model_path, destination_process_model_path) - # copy files from process model into the new publish branch - destination_process_model_path = os.path.join(destination_process_root, process_model_id) - if os.path.exists(destination_process_model_path): - shutil.rmtree(destination_process_model_path) - shutil.copytree(source_process_model_path, destination_process_model_path) + # add and commit files to publish_branch, then push + commit_message = f"Request to publish changes to {process_model_id}, from {g.user.username}" + cls.commit(commit_message, destination_process_root) + os.system("git push") - # add and commit files to publish_branch, then push - os.chdir(destination_process_root) - os.system("git add .") # noqa: S605 - commit_message = f"Request to publish changes to {process_model_id}, from {g.user.username}" - os.system(f"git commit -m '{commit_message}'") # noqa: S605 - os.system("git push") - - # build url for github page to open PR - output = os.popen("git config --get remote.origin.url").read() - remote_url = output.strip().replace(".git", "") - pr_url = f"{remote_url}/compare/{publish_branch}?expand=1" + # build url for github page to open PR + output = os.popen("git config --get remote.origin.url").read() + remote_url = output.strip().replace(".git", "") + pr_url = f"{remote_url}/compare/{publish_branch}?expand=1" # try to clean up - os.chdir("/tmp") if os.path.exists(destination_process_root): shutil.rmtree(destination_process_root) diff --git a/tests/spiffworkflow_backend/integration/test_process_api.py b/tests/spiffworkflow_backend/integration/test_process_api.py index 495dbfc7..d3abd732 100644 --- a/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/tests/spiffworkflow_backend/integration/test_process_api.py @@ -2562,7 +2562,7 @@ class TestProcessApi(BaseTest): with_db_and_bpmn_file_cleanup: None, with_super_admin_user: UserModel, ) -> None: - + """Test_process_model_publish.""" bpmn_root = FileSystemService.root_path() shell_command = f"git init {bpmn_root}" output = os.popen(shell_command).read() # noqa: S605 @@ -2571,14 +2571,13 @@ class TestProcessApi(BaseTest): output = os.popen("git status").read() # noqa: S605 assert "On branch main" in output assert "No commits yet" in output - assert "nothing to commit (create/copy files and use \"git add\" to track)" in output + assert ( + 'nothing to commit (create/copy files and use "git add" to track)' in output + ) process_group_id = "test_group" self.create_process_group( - client, - with_super_admin_user, - process_group_id, - process_group_id + client, with_super_admin_user, process_group_id, process_group_id ) sub_process_group_id = "test_group/test_sub_group" @@ -2596,8 +2595,7 @@ class TestProcessApi(BaseTest): process_model_absolute_dir = os.path.join(bpmn_root, process_model_identifier) output = os.popen("git status").read() # noqa: S605 - test_string = \ - 'Untracked files:\n (use "git add ..." to include in what will be committed)\n\ttest_group' + test_string = 'Untracked files:\n (use "git add ..." to include in what will be committed)\n\ttest_group' assert test_string in output os.system("git add .") @@ -2643,7 +2641,7 @@ class TestProcessApi(BaseTest): file_data = b"abc123" new_file_path = os.path.join(process_model_absolute_dir, "new_file.txt") - with open(new_file_path, 'wb') as f_open: + with open(new_file_path, "wb") as f_open: f_open.write(file_data) output = os.popen("git status").read() # noqa: S605 @@ -2651,7 +2649,9 @@ class TestProcessApi(BaseTest): assert "Untracked files:" in output assert "test_group/test_sub_group/hello_world/new_file.txt" in output - os.system("git add test_group/test_sub_group/hello_world/new_file.txt") # noqa: S605 + os.system( + "git add test_group/test_sub_group/hello_world/new_file.txt" + ) # noqa: S605 output = os.popen("git commit -m 'add new_file.txt'").read() # noqa: S605 assert "add new_file.txt" in output