diff --git a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo index f8983cedd..d224881fd 100755 --- a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo +++ b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo @@ -1,7 +1,7 @@ #!/usr/bin/env bash function error_handler() { - >&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}." + echo >&2 "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}." exit "$2" } trap 'error_handler ${LINENO} $?' ERR @@ -10,40 +10,54 @@ set -o errtrace -o errexit -o nounset -o pipefail # HELP: git adds and commits the entire BPMN models directory, including all process groups bpmn_models_absolute_dir="$1" -git_commit_message="$2" -git_branch="$3" +actions="$2" -if [[ -z "${3:-}" ]]; then - >&2 echo "usage: $(basename "${0}") [bpmn_models_absolute_dir] [git_commit_message] [git_branch]" +if [[ -z "${4:-}" ]]; then + echo >&2 "usage: $(basename "${0}") [bpmn_models_absolute_dir] [actions: commit,push]" exit 1 fi function failed_to_get_lock() { - >&2 echo "ERROR: Failed to get lock." + echo >&2 "ERROR: Failed to get lock." exit 1 } +if grep -qE '\' <<<"$actions" && [[ -z "${GIT_COMMIT_MESSAGE:-}" ]]; then + echo >&2 "ERROR: GIT_COMMIT_MESSAGE must be set if committing" + exit 1 +fi + +if grep -qE '\' <<<"$actions" && [[ -z "${GIT_BRANCH:-}" ]]; then + echo >&2 "ERROR: GIT_BRANCH must be set if pushing" + exit 1 +fi + function run() { # we are very careful not to run "cd" from python, since it is at the process level and will screw up other threads. # we are safe in this case because this entire script is run in a new process. cd "${bpmn_models_absolute_dir}" - git add . - # https://unix.stackexchange.com/a/155077/456630 - if [ -z "$(git status --porcelain)" ]; then - echo "No changes to commit" - return - fi + if grep -qE '\' <<<"$actions"; then + git add . - # FIXME: the environment variables may not be working with the root user which we are using in the docker container. - # we see some evidence with this issue https://stackoverflow.com/questions/68975943/git-config-environment-variables - # and it didn't seem to work for us either so set them like this for now. - # One day we should probably not use the root user in the docker container. - git config --local user.email "$GIT_COMMITTER_EMAIL" - git config --local user.name "$GIT_COMMITTER_NAME" + # https://unix.stackexchange.com/a/155077/456630 + if [ -z "$(git status --porcelain)" ]; then + echo "No changes to commit" + return + fi - git commit -m "${git_commit_message}" - git push --set-upstream origin "${git_branch}" + # FIXME: the environment variables may not be working with the root user which we are using in the docker container. + # we see some evidence with this issue https://stackoverflow.com/questions/68975943/git-config-environment-variables + # and it didn't seem to work for us either so set them like this for now. + # One day we should probably not use the root user in the docker container. + git config --local user.email "$GIT_COMMITTER_EMAIL" + git config --local user.name "$GIT_COMMITTER_NAME" + git commit -m "${GIT_COMMIT_MESSAGE}" + fi + + if grep -qE '\' <<<"$actions"; then + git push --set-upstream origin "${GIT_BRANCH}" + fi } lock_directory="/var/lock" @@ -56,7 +70,7 @@ if ! command -v flock >/dev/null 2>&1; then # some hero made this available on mac: https://github.com/discoteq/flock brew install flock else - >&2 echo "ERROR: flock is not installed and we cannot install it." + echo >&2 "ERROR: flock is not installed and we cannot install it." exit 1 fi fi diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 0d6cbf039..7459c4d41 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -90,14 +90,23 @@ def get_file_contents_for_revision_if_git_revision( @classmethod def commit( cls, - message: str, - repo_path: str | None = None, + message: str | None = None, branch_name: str | None = None, + repo_path: str | None = None, + actions: list[str] | None = None, ) -> str: cls.check_for_basic_configs() + + if actions is None: + if current_app.config["SPIFFWORKFLOW_BACKEND_CELERY_ENABLED"]: + actions = ["commit"] + else: + actions = ["commit", "push"] + branch_name_to_use = branch_name if branch_name_to_use is None: branch_name_to_use = current_app.config["SPIFFWORKFLOW_BACKEND_GIT_SOURCE_BRANCH"] + repo_path_to_use = repo_path if repo_path is None: repo_path_to_use = current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"] @@ -108,10 +117,18 @@ def commit( shell_command = [ shell_command_path, repo_path_to_use, - message, - branch_name_to_use, + ",".join(actions), ] - return cls.run_shell_command_to_get_stdout(shell_command, prepend_with_git=False) + extra_env = {} + if "commit" in actions: + extra_env["GIT_COMMIT_MESSAGE"]= message + if "push" in actions: + extra_env["GIT_BRANCH"]= branch_name_to_use + result = cls.run_shell_command_to_get_stdout(shell_command, prepend_with_git=False, extra_env=extra_env) + + if current_app.config["SPIFFWORKFLOW_BACKEND_CELERY_ENABLED"] and "push" not in actions: + # queue it + pass @classmethod def check_for_basic_configs(cls, raise_on_missing: bool = True) -> bool: @@ -154,11 +171,19 @@ def run_shell_command_as_boolean(cls, command: list[str], context_directory: str @classmethod def run_shell_command_to_get_stdout( - cls, command: list[str], context_directory: str | None = None, prepend_with_git: bool = True + cls, + command: list[str], + context_directory: str | None = None, + prepend_with_git: bool = True, + extra_env: dict | None = None, ) -> str: # we know result will be a CompletedProcess here result: subprocess.CompletedProcess[bytes] = cls.run_shell_command( - command, return_success_state=False, context_directory=context_directory, prepend_with_git=prepend_with_git + command, + return_success_state=False, + context_directory=context_directory, + prepend_with_git=prepend_with_git, + extra_env=extra_env, ) # type: ignore return result.stdout.decode("utf-8").strip() @@ -169,11 +194,13 @@ def run_shell_command( context_directory: str | None = None, return_success_state: bool = False, prepend_with_git: bool = True, + extra_env: dict | None = None, ) -> subprocess.CompletedProcess[bytes] | bool: my_env = os.environ.copy() my_env["GIT_COMMITTER_NAME"] = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USERNAME") or "unknown" my_env["GIT_COMMITTER_EMAIL"] = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL") or "unknown@example.org" + my_env = {**my_env, **(extra_env or {})} # SSH authentication can be also provided via gitconfig. ssh_key_path = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH")