diff --git a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo index 13e18da9..62fc0cab 100755 --- a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo +++ b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo @@ -11,11 +11,12 @@ set -o errtrace -o errexit -o nounset -o pipefail bpmn_models_absolute_dir="$1" git_commit_message="$2" -git_commit_username="$3" -git_commit_email="$4" +git_branch="$3" +git_commit_username="$4" +git_commit_email="$5" -if [[ -z "${2:-}" ]]; then - >&2 echo "usage: $(basename "$0") [bpmn_models_absolute_dir] [git_commit_message]" +if [[ -z "${5:-}" ]]; then + >&2 echo "usage: $(basename "$0") [bpmn_models_absolute_dir] [git_commit_message] [git_branch] [git_commit_username] [git_commit_email]" exit 1 fi @@ -26,11 +27,8 @@ git add . if [ -z "$(git status --porcelain)" ]; then echo "No changes to commit" else - if [[ -n "$git_commit_username" ]]; then - git config --local user.name "$git_commit_username" - fi - if [[ -n "$git_commit_email" ]]; then - git config --local user.email "$git_commit_email" - fi + git config --local user.name "$git_commit_username" + git config --local user.email "$git_commit_email" git commit -m "$git_commit_message" + git push --set-upstream origin "$git_branch" fi diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/testing.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/testing.py index bbda9db9..605c1bcc 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/testing.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/testing.py @@ -15,6 +15,7 @@ SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get( SPIFFWORKFLOW_BACKEND_LOG_LEVEL = environ.get( "SPIFFWORKFLOW_BACKEND_LOG_LEVEL", default="debug" ) +GIT_COMMIT_ON_SAVE = False # NOTE: set this here since nox shoves tests and src code to # different places and this allows us to know exactly where we are at the start diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index a89ae953..ba2f65c2 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -170,6 +170,9 @@ def process_group_add(body: dict) -> flask.wrappers.Response: """Add_process_group.""" process_group = ProcessGroup(**body) ProcessModelService.add_process_group(process_group) + commit_and_push_to_git( + f"User: {g.user.username} added process group {process_group.id}" + ) return make_response(jsonify(process_group), 201) @@ -177,6 +180,9 @@ def process_group_delete(modified_process_group_id: str) -> flask.wrappers.Respo """Process_group_delete.""" process_group_id = un_modify_modified_process_model_id(modified_process_group_id) ProcessModelService().process_group_delete(process_group_id) + commit_and_push_to_git( + f"User: {g.user.username} deleted process group {process_group_id}" + ) return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") @@ -194,6 +200,9 @@ def process_group_update( process_group_id = un_modify_modified_process_model_id(modified_process_group_id) process_group = ProcessGroup(id=process_group_id, **body_filtered) ProcessModelService.update_process_group(process_group) + commit_and_push_to_git( + f"User: {g.user.username} updated process group {process_group_id}" + ) return make_response(jsonify(process_group), 200) @@ -258,7 +267,10 @@ def process_group_move( new_process_group = ProcessModelService().process_group_move( original_process_group_id, new_location ) - return make_response(jsonify(new_process_group), 201) + commit_and_push_to_git( + f"User: {g.user.username} moved process group {original_process_group_id} to {new_process_group.id}" + ) + return make_response(jsonify(new_process_group), 200) def process_model_create( @@ -306,6 +318,9 @@ def process_model_create( ) ProcessModelService.add_process_model(process_model_info) + commit_and_push_to_git( + f"User: {g.user.username} created process model {process_model_info.id}" + ) return Response( json.dumps(ProcessModelInfoSchema().dump(process_model_info)), status=201, @@ -319,6 +334,9 @@ def process_model_delete( """Process_model_delete.""" process_model_identifier = modified_process_model_identifier.replace(":", "/") ProcessModelService().process_model_delete(process_model_identifier) + commit_and_push_to_git( + f"User: {g.user.username} deleted process model {process_model_identifier}" + ) return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") @@ -342,6 +360,9 @@ def process_model_update( process_model = get_process_model(process_model_identifier) ProcessModelService.update_process_model(process_model, body_filtered) + commit_and_push_to_git( + f"User: {g.user.username} updated process model {process_model_identifier}" + ) return ProcessModelInfoSchema().dump(process_model) @@ -373,7 +394,10 @@ def process_model_move( new_process_model = ProcessModelService().process_model_move( original_process_model_id, new_location ) - return make_response(jsonify(new_process_model), 201) + commit_and_push_to_git( + f"User: {g.user.username} moved process model {original_process_model_id} to {new_process_model.id}" + ) + return make_response(jsonify(new_process_model), 200) def process_model_publish( @@ -469,14 +493,9 @@ def process_model_file_update( ) SpecFileService.update_file(process_model, file_name, request_file_contents) - - if current_app.config["GIT_COMMIT_ON_SAVE"]: - git_output = GitService.commit( - message=f"User: {g.user.username} clicked save for {process_model_identifier}/{file_name}" - ) - current_app.logger.info(f"git output: {git_output}") - else: - current_app.logger.info("Git commit on save is disabled") + commit_and_push_to_git( + f"User: {g.user.username} clicked save for {process_model_identifier}/{file_name}" + ) return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") @@ -498,6 +517,9 @@ def process_model_file_delete( ) ) from exception + commit_and_push_to_git( + f"User: {g.user.username} deleted process model file {process_model_identifier}/{file_name}" + ) return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") @@ -519,6 +541,9 @@ def add_file(modified_process_model_identifier: str) -> flask.wrappers.Response: file_contents = SpecFileService.get_data(process_model, file.name) file.file_contents = file_contents file.process_model_id = process_model.id + commit_and_push_to_git( + f"User: {g.user.username} added process model file {process_model_identifier}/{file.name}" + ) return Response( json.dumps(FileSchema().dump(file)), status=201, mimetype="application/json" ) @@ -2058,3 +2083,12 @@ def update_task_data( status=200, mimetype="application/json", ) + + +def commit_and_push_to_git(message: str) -> None: + """Commit_and_push_to_git.""" + if current_app.config["GIT_COMMIT_ON_SAVE"]: + git_output = GitService.commit(message=message) + current_app.logger.info(f"git output: {git_output}") + else: + current_app.logger.info("Git commit on save is disabled") diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 152aab1c..8ef952c3 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -68,8 +68,17 @@ class GitService: return cls.run_shell_command_to_get_stdout(shell_command) @classmethod - def commit(cls, message: str, repo_path: Optional[str] = None) -> str: + def commit( + cls, + message: str, + repo_path: Optional[str] = None, + branch_name: Optional[str] = None, + ) -> str: """Commit.""" + cls.check_for_basic_configs() + branch_name_to_use = branch_name + if branch_name_to_use is None: + branch_name_to_use = current_app.config["GIT_BRANCH"] repo_path_to_use = repo_path if repo_path is None: repo_path_to_use = current_app.config["BPMN_SPEC_ABSOLUTE_DIR"] @@ -88,14 +97,25 @@ class GitService: shell_command_path, repo_path_to_use, message, + branch_name_to_use, git_username, git_email, ] return cls.run_shell_command_to_get_stdout(shell_command) @classmethod - def check_for_configs(cls) -> None: + def check_for_basic_configs(cls) -> None: + """Check_for_basic_configs.""" + if current_app.config["GIT_BRANCH"] is None: + raise MissingGitConfigsError( + "Missing config for GIT_BRANCH. " + "This is required for publishing process models" + ) + + @classmethod + def check_for_publish_configs(cls) -> None: """Check_for_configs.""" + cls.check_for_basic_configs() if current_app.config["GIT_BRANCH_TO_PUBLISH_TO"] is None: raise MissingGitConfigsError( "Missing config for GIT_BRANCH_TO_PUBLISH_TO. " @@ -148,7 +168,7 @@ class GitService: @classmethod def handle_web_hook(cls, webhook: dict) -> bool: """Handle_web_hook.""" - cls.check_for_configs() + cls.check_for_publish_configs() if "repository" not in webhook or "clone_url" not in webhook["repository"]: raise InvalidGitWebhookBodyError( @@ -184,7 +204,7 @@ class GitService: @classmethod def publish(cls, process_model_id: str, branch_to_update: str) -> str: """Publish.""" - cls.check_for_configs() + cls.check_for_publish_configs() source_process_model_root = FileSystemService.root_path() source_process_model_path = os.path.join( source_process_model_root, process_model_id @@ -233,10 +253,7 @@ class GitService: f"Request to publish changes to {process_model_id}, " f"from {g.user.username} on {current_app.config['ENV_IDENTIFIER']}" ) - cls.commit(commit_message, destination_process_root) - cls.run_shell_command( - ["git", "push", "--set-upstream", "origin", branch_to_pull_request] - ) + cls.commit(commit_message, destination_process_root, branch_to_pull_request) # build url for github page to open PR git_remote = cls.run_shell_command_to_get_stdout(