From 2cbe912a994b06655e81f22d6623de7b4a59c5c5 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 6 Dec 2022 15:31:03 -0500 Subject: [PATCH 01/11] First pass at git integration --- .../src/spiffworkflow_backend/api.yml | 26 ++++++++++++ .../spiffworkflow_backend/config/default.py | 1 + .../routes/process_api_blueprint.py | 11 +++++ .../services/file_system_service.py | 2 +- .../services/git_service.py | 40 +++++++++++++++++++ .../src/routes/ProcessModelShow.tsx | 11 +++++ 6 files changed, 90 insertions(+), 1 deletion(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index e7dc00fe..d979c662 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -445,6 +445,32 @@ paths: schema: $ref: "#/components/schemas/ProcessModel" + /process-models/{modified_process_model_identifier}/publish: + parameters: + - name: modified_process_model_identifier + in: path + required: true + description: the modified process model id + schema: + type: string + - name: branch_to_update + in: query + required: false + description: the name of the branch we want to merge into + schema: + type: string + put: + operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_publish + summary: Merge changes from this model to another branch. + tags: + - Process Models + responses: + "200": + description: The process model was published. + content: + application/json: + schema: + $ref: "#/components/schemas/OkTrue" /processes: get: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py index 53d670c7..252b0534 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py @@ -57,3 +57,4 @@ SENTRY_TRACES_SAMPLE_RATE = environ.get( SPIFFWORKFLOW_BACKEND_LOG_LEVEL = environ.get( "SPIFFWORKFLOW_BACKEND_LOG_LEVEL", default="info" ) +GIT_MERGE_BRANCH = environ.get("GIT_MERGE_BRANCH", default="staging") 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 739e689d..e82d1247 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -353,6 +353,17 @@ def process_model_move( return make_response(jsonify(new_process_model), 201) +def process_model_publish( + modified_process_model_identifier: str, + branch_to_update: Optional[str] = None +) -> flask.wrappers.Response: + 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) + GitService().publish(process_model_identifier, branch_to_update) + return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") + + def process_model_list( process_group_identifier: Optional[str] = None, recursive: Optional[bool] = False, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py index 5812748c..ccf992e4 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py @@ -29,7 +29,7 @@ class FileSystemService: # fixme: allow absolute files dir_name = current_app.config["BPMN_SPEC_ABSOLUTE_DIR"] app_root = current_app.root_path - return os.path.join(app_root, "..", dir_name) + return os.path.abspath(os.path.join(app_root, "..", dir_name)) @staticmethod def id_string_to_relative_path(id_string: str) -> str: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 815e4cad..dc8f1c24 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -1,7 +1,10 @@ """Git_service.""" +import datetime import os +import shutil from flask import current_app +from flask import g from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.services.file_system_service import FileSystemService @@ -54,3 +57,40 @@ class GitService: shell_command = f"./bin/git_commit_bpmn_models_repo '{bpmn_spec_absolute_dir}' '{message}' '{git_username}' '{git_email}'" output = os.popen(shell_command).read() # noqa: S605 return output + + @staticmethod + def publish(process_model_id, branch_to_update): + source_process_model_root = FileSystemService.root_path() + source_process_model_path = os.path.join(source_process_model_root, process_model_id) + + # clone new instance of sample-process-models, checkout branch_to_update + os.chdir("/tmp") + destination_process_root = "/tmp/sample-process-models" + if os.path.exists(destination_process_root): + shutil.rmtree(destination_process_root) + os.system("git clone https://github.com/sartography/sample-process-models.git") + os.chdir(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 + + # 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 + 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") + print("publish") diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 2882e183..fc1c354f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -203,6 +203,14 @@ export default function ProcessModelShow() { }); }; + const publishProcessModel = () => { + HttpService.makeCallToBackend({ + path: `/process-models/${modifiedProcessModelId}/publish`, + successCallback: navigateToProcessModels, + httpMethod: 'PUT', + }); + }; + const navigateToFileEdit = (processModelFile: ProcessFile) => { const url = profileModelFileEditUrl(processModelFile); if (url) { @@ -568,6 +576,9 @@ export default function ProcessModelShow() {
+
+ +
{processInstanceRunResultTag()} {processModelFilesSection()} From ae4dfa2dd8e182021ff996918470e1a8f74b61cb Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 6 Dec 2022 15:42:41 -0500 Subject: [PATCH 02/11] typing --- .../src/spiffworkflow_backend/services/git_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index dc8f1c24..d4bb3f30 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -59,7 +59,7 @@ class GitService: return output @staticmethod - def publish(process_model_id, branch_to_update): + def publish(process_model_id: str, branch_to_update: str) -> None: source_process_model_root = FileSystemService.root_path() source_process_model_path = os.path.join(source_process_model_root, process_model_id) From cfe4c521c8dddd055766ea98a9e9a9e6c2841c36 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 6 Dec 2022 16:14:46 -0500 Subject: [PATCH 03/11] Merging this unfinished test so I don't lose it. It doesn't test anything yet. Need to deal w/ a bunch of mock stuff --- .../integration/test_process_api.py | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 5ee5ae9f..054be4ed 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -2544,3 +2544,120 @@ class TestProcessApi(BaseTest): # make sure the new subgroup does exist new_process_group = ProcessModelService.get_process_group(new_sub_path) assert new_process_group.id == new_sub_path + + def test_process_model_publish( + self, + app: Flask, + client: FlaskClient, + with_db_and_bpmn_file_cleanup: None, + with_super_admin_user: UserModel, + ) -> None: + + bpmn_root = FileSystemService.root_path() + shell_command = f"git init {bpmn_root}" + output = os.popen(shell_command).read() # noqa: S605 + assert output == f"Initialized empty Git repository in {bpmn_root}/.git/\n" + os.chdir(bpmn_root) + 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 + + process_group_id = "test_group" + self.create_process_group( + client, + with_super_admin_user, + process_group_id, + process_group_id + ) + + sub_process_group_id = "test_group/test_sub_group" + process_model_id = "hello_world" + bpmn_file_name = "hello_world.bpmn" + bpmn_file_location = "hello_world" + process_model_identifier = self.create_group_and_model_with_bpmn( + client=client, + user=with_super_admin_user, + process_group_id=sub_process_group_id, + process_model_id=process_model_id, + bpmn_file_name=bpmn_file_name, + bpmn_file_location=bpmn_file_location, + ) + 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' + assert test_string in output + + os.system("git add .") + output = os.popen("git commit -m 'Initial Commit'").read() + assert "Initial Commit" in output + assert "4 files changed" in output + assert "test_group/process_group.json" in output + assert "test_group/test_sub_group/hello_world/hello_world.bpmn" in output + assert "test_group/test_sub_group/hello_world/process_model.json" in output + assert "test_group/test_sub_group/process_group.json" in output + + output = os.popen("git status").read() # noqa: S605 + assert "On branch main" in output + assert "nothing to commit" in output + assert "working tree clean" in output + + output = os.popen("git branch --list").read() # noqa: S605 + assert output == "* main\n" + os.system("git branch staging") + output = os.popen("git branch --list").read() # noqa: S605 + assert output == "* main\n staging\n" + + os.system("git checkout staging") + + output = os.popen("git status").read() # noqa: S605 + assert "On branch staging" in output + assert "nothing to commit" in output + assert "working tree clean" in output + + # process_model = ProcessModelService.get_process_model(process_model_identifier) + + listing = os.listdir(process_model_absolute_dir) + assert len(listing) == 2 + assert "hello_world.bpmn" in listing + assert "process_model.json" in listing + + os.system("git checkout main") + + output = os.popen("git status").read() # noqa: S605 + assert "On branch main" in output + assert "nothing to commit" in output + assert "working tree clean" in output + + 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: + f_open.write(file_data) + + output = os.popen("git status").read() # noqa: S605 + assert "On branch main" in output + 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 + output = os.popen("git commit -m 'add new_file.txt'").read() # noqa: S605 + + assert "add new_file.txt" in output + assert "1 file changed, 1 insertion(+)" in output + assert "test_group/test_sub_group/hello_world/new_file.txt" in output + + listing = os.listdir(process_model_absolute_dir) + assert len(listing) == 3 + assert "hello_world.bpmn" in listing + assert "process_model.json" in listing + assert "new_file.txt" in listing + + modified_process_model_id = process_model_identifier.replace("/", ":") + # response = client.put( + # f"/v1.0/process-models/{modified_process_model_id}/publish?branch_to_update=staging", + # headers=self.logged_in_headers(with_super_admin_user), + # ) + + print("test_process_model_publish") From 68afdb0d38c1148cc81cff1b14013941d9bb995e Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Wed, 7 Dec 2022 14:00:11 -0500 Subject: [PATCH 04/11] Add comment about the new environment variable --- .../src/spiffworkflow_backend/config/default.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py index 252b0534..a75a4cd7 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py @@ -57,4 +57,6 @@ SENTRY_TRACES_SAMPLE_RATE = environ.get( SPIFFWORKFLOW_BACKEND_LOG_LEVEL = environ.get( "SPIFFWORKFLOW_BACKEND_LOG_LEVEL", default="info" ) +# When a user clicks on the `Publish` button, this is the default branch this server merges into. +# I.e., dev server could have `staging` here. Staging server might have `production` here. GIT_MERGE_BRANCH = environ.get("GIT_MERGE_BRANCH", default="staging") From 97f2291a4458308aa04a1d8749ba31f0f1b35190 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Wed, 7 Dec 2022 14:00:46 -0500 Subject: [PATCH 05/11] Return message to use on successful publish --- .../src/routes/ProcessModelShow.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 1b55b007..50f31b8b 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -21,6 +21,7 @@ import { ButtonSet, Modal, FileUploader, + InlineNotification, Table, TableHead, TableHeader, @@ -60,6 +61,7 @@ export default function ProcessModelShow() { const [filesToUpload, setFilesToUpload] = useState(null); const [showFileUploadModal, setShowFileUploadModal] = useState(false); + const [processModelPublished, setProcessModelPublished] = useState(null); const navigate = useNavigate(); const { targetUris } = useUriListForPermissions(); @@ -203,10 +205,14 @@ export default function ProcessModelShow() { }); }; + const postPublish = (value: any) => { + setProcessModelPublished(value); + }; + const publishProcessModel = () => { HttpService.makeCallToBackend({ path: `/process-models/${modifiedProcessModelId}/publish`, - successCallback: navigateToProcessModels, + successCallback: postPublish, httpMethod: 'PUT', }); }; @@ -518,10 +524,28 @@ export default function ProcessModelShow() { return null; }; + const processModelPublishMessage = () => { + console.log(`processModelPublishMessage: `); + if (processModelPublished) { + return ( + <> + +
+ + ); + } + return null; + }; + if (processModel) { return ( <> {fileUploadModal()} + {processModelPublishMessage()} Date: Thu, 8 Dec 2022 09:25:27 -0500 Subject: [PATCH 06/11] Clone into unique directory so we don't step on a previous publish that hasn't finished. --- .../spiffworkflow_backend/services/git_service.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index d4bb3f30..0c24e965 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -1,7 +1,8 @@ """Git_service.""" -import datetime + import os import shutil +import uuid from flask import current_app from flask import g @@ -59,16 +60,16 @@ class GitService: return output @staticmethod - def publish(process_model_id: str, branch_to_update: str) -> None: + def publish(process_model_id: str, branch_to_update: str) -> str: source_process_model_root = FileSystemService.root_path() 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 = "/tmp/sample-process-models" - if os.path.exists(destination_process_root): - shutil.rmtree(destination_process_root) - os.system("git clone https://github.com/sartography/sample-process-models.git") + 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) # create publish branch from branch_to_update From fc558b2218aee8a3fb98ba91d1bc36b7fd4bf0d5 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 8 Dec 2022 09:26:10 -0500 Subject: [PATCH 07/11] Return URL where they can view changes and open PR --- .../src/spiffworkflow_backend/api.yml | 2 +- .../routes/process_api_blueprint.py | 5 +++-- .../spiffworkflow_backend/services/git_service.py | 13 ++++++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index ea3e6998..3dc70061 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -470,7 +470,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/OkTrue" + type: string /processes: get: 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 cdd2ec30..e5fde203 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -377,8 +377,9 @@ def 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) - GitService().publish(process_model_identifier, branch_to_update) - return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") + 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") def process_model_list( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 0c24e965..b5c451b4 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -94,4 +94,15 @@ class GitService: 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") - print("publish") + + # build url for github page to open PR + output = os.popen("git remote -v").read() + remote_url = output.strip().split("\n")[0].split("\t")[1].split(" ")[0].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) + + return pr_url From d38217cb0ab919d256259c091a388d3d0907f47e Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 8 Dec 2022 09:28:41 -0500 Subject: [PATCH 08/11] display URL to open PR *** Need to figure out how to turn this into a link *** --- .../src/routes/ProcessModelShow.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 50f31b8b..ecd6cada 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -61,7 +61,7 @@ export default function ProcessModelShow() { const [filesToUpload, setFilesToUpload] = useState(null); const [showFileUploadModal, setShowFileUploadModal] = useState(false); - const [processModelPublished, setProcessModelPublished] = useState(null); + const [processModelPublished, setProcessModelPublished] = useState(null); const navigate = useNavigate(); const { targetUris } = useUriListForPermissions(); @@ -210,6 +210,7 @@ export default function ProcessModelShow() { }; const publishProcessModel = () => { + setProcessModelPublished(null); HttpService.makeCallToBackend({ path: `/process-models/${modifiedProcessModelId}/publish`, successCallback: postPublish, @@ -525,14 +526,16 @@ export default function ProcessModelShow() { }; const processModelPublishMessage = () => { - console.log(`processModelPublishMessage: `); if (processModelPublished) { + const prUrl: string = processModelPublished.pr_url; return ( <>
From 375e4023dd83d004de419f6ad7cf811711f1b597 Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 8 Dec 2022 12:28:23 -0500 Subject: [PATCH 09/11] added new notification component that allows links based on carbons w/ burnettk cullerton --- .../src/spiffworkflow_backend/api.yml | 2 +- .../services/git_service.py | 4 +- .../integration/test_process_api.py | 2 +- .../src/components/Notification.tsx | 48 ++++++++++++++ .../components/ProcessInstanceListTable.tsx | 16 ++--- .../src/hooks/UriListForPermissions.tsx | 1 + spiffworkflow-frontend/src/index.css | 11 +++- .../src/routes/ProcessModelShow.tsx | 65 ++++++++++--------- 8 files changed, 105 insertions(+), 44 deletions(-) create mode 100644 spiffworkflow-frontend/src/components/Notification.tsx diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index 3dc70061..d4ed3755 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -459,7 +459,7 @@ paths: description: the name of the branch we want to merge into schema: type: string - put: + post: operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_publish summary: Merge changes from this model to another branch. tags: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index b5c451b4..27d94025 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -96,8 +96,8 @@ class GitService: os.system("git push") # build url for github page to open PR - output = os.popen("git remote -v").read() - remote_url = output.strip().split("\n")[0].split("\t")[1].split(" ")[0].replace(".git", "") + 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 diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 8f993302..495dbfc7 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -2665,7 +2665,7 @@ class TestProcessApi(BaseTest): assert "new_file.txt" in listing modified_process_model_id = process_model_identifier.replace("/", ":") - # response = client.put( + # response = client.post( # f"/v1.0/process-models/{modified_process_model_id}/publish?branch_to_update=staging", # headers=self.logged_in_headers(with_super_admin_user), # ) diff --git a/spiffworkflow-frontend/src/components/Notification.tsx b/spiffworkflow-frontend/src/components/Notification.tsx new file mode 100644 index 00000000..a3a20077 --- /dev/null +++ b/spiffworkflow-frontend/src/components/Notification.tsx @@ -0,0 +1,48 @@ +import React, { useState } from 'react'; +// @ts-ignore +import { Close, CheckmarkFilled } from '@carbon/icons-react'; +// @ts-ignore +import { Button } from '@carbon/react'; + +type OwnProps = { + title: string; + children: React.ReactNode; + onClose: (..._args: any[]) => any; + type?: string; +}; + +export function Notification({ + title, + children, + onClose, + type = 'success', +}: OwnProps) { + let iconClassName = 'green-icon'; + if (type === 'error') { + iconClassName = 'red-icon'; + } + return ( +
+
+
+ +
{title}
+
{children}
+
+
+
+ ); +} diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index eee5a273..51d20d64 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -7,7 +7,7 @@ import { } from 'react-router-dom'; // @ts-ignore -import { Filter, Close, AddAlt } from '@carbon/icons-react'; +import { Filter, Close, AddAlt, CheckmarkFilled } from '@carbon/icons-react'; import { Button, ButtonSet, @@ -65,6 +65,7 @@ import ProcessModelSearch from './ProcessModelSearch'; import ProcessInstanceReportSearch from './ProcessInstanceReportSearch'; import ProcessInstanceListSaveAsReport from './ProcessInstanceListSaveAsReport'; import { FormatProcessModelDisplayName } from './MiniComponents'; +import { Notification } from './Notification'; const REFRESH_INTERVAL = 5; const REFRESH_TIMEOUT = 600; @@ -372,18 +373,13 @@ export default function ProcessInstanceListTable({ titleOperation = 'Created'; } return ( - <> - setProcessInstanceReportJustSaved(null)}> + {`'${ processInstanceReportSelection ? processInstanceReportSelection.identifier : '' - }'`} - kind="success" - /> -
- + }'`}
+ ); } return null; diff --git a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx index eff30a82..f84465c8 100644 --- a/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx +++ b/spiffworkflow-frontend/src/hooks/UriListForPermissions.tsx @@ -18,6 +18,7 @@ export const useUriListForPermissions = () => { processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`, processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`, processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`, + processModelPublishPath: `/v1.0/process-models/${params.process_model_id}/publish`, processModelShowPath: `/v1.0/process-models/${params.process_model_id}`, secretListPath: `/v1.0/secrets`, }; diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index f4094785..5701a4f1 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -332,6 +332,14 @@ td.actions-cell { fill: red; } +svg.green-icon { + fill: #198038; +} + +svg.notification-icon { + margin-right: 1rem; +} + .failure-string { color: red; } @@ -358,7 +366,8 @@ td.actions-cell { } +/* lime green */ .tag-type-green:hover { - background-color: #00FF00; + background-color: #80ee90; } diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index ecd6cada..24abd140 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -49,6 +49,7 @@ import ProcessInstanceListTable from '../components/ProcessInstanceListTable'; import { usePermissionFetcher } from '../hooks/PermissionService'; import { useUriListForPermissions } from '../hooks/UriListForPermissions'; import ProcessInstanceRun from '../components/ProcessInstanceRun'; +import { Notification } from '../components/Notification'; export default function ProcessModelShow() { const params = useParams(); @@ -62,11 +63,13 @@ export default function ProcessModelShow() { const [showFileUploadModal, setShowFileUploadModal] = useState(false); const [processModelPublished, setProcessModelPublished] = useState(null); + const [publishDisabled, setPublishDisabled] = useState(false); const navigate = useNavigate(); const { targetUris } = useUriListForPermissions(); const permissionRequestData: PermissionsToCheck = { [targetUris.processModelShowPath]: ['PUT', 'DELETE'], + [targetUris.processModelPublishPath]: ['POST'], [targetUris.processInstanceListPath]: ['GET'], [targetUris.processInstanceCreatePath]: ['POST'], [targetUris.processModelFileCreatePath]: ['POST', 'PUT', 'GET', 'DELETE'], @@ -93,19 +96,17 @@ export default function ProcessModelShow() { const processInstanceRunResultTag = () => { if (processInstance) { return ( -
-

- Process Instance {processInstance.id} kicked off ( - - view - - ). -

-
-
+ setProcessInstance(null)} + > + + view + + ); } return null; @@ -206,15 +207,17 @@ export default function ProcessModelShow() { }; const postPublish = (value: any) => { + setPublishDisabled(false); setProcessModelPublished(value); }; const publishProcessModel = () => { + setPublishDisabled(true); setProcessModelPublished(null); HttpService.makeCallToBackend({ path: `/process-models/${modifiedProcessModelId}/publish`, successCallback: postPublish, - httpMethod: 'PUT', + httpMethod: 'POST', }); }; @@ -529,16 +532,14 @@ export default function ProcessModelShow() { if (processModelPublished) { const prUrl: string = processModelPublished.pr_url; return ( - <> - -
- + setProcessModelPublished(false)} + > + + view the changes and create a Pull Request + + ); } return null; @@ -548,7 +549,6 @@ export default function ProcessModelShow() { return ( <> {fileUploadModal()} - {processModelPublishMessage()} + {processModelPublishMessage()} + {processInstanceRunResultTag()}

Process Model: {processModel.display_name} @@ -603,11 +605,16 @@ export default function ProcessModelShow() {
-
- -
+ + + - {processInstanceRunResultTag()} {processModelFilesSection()} {processInstanceListTableButton()} From 62814da9a62e6d1b66dee4cf5c75d8b0dd5102cb Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 8 Dec 2022 16:39:23 -0500 Subject: [PATCH 10/11] added git creds for pushing on publish w/ burnettk cullerton --- spiffworkflow-backend/bin/save_all_bpmn.py | 4 +- .../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 ++--- .../src/components/Notification.tsx | 2 +- .../components/ProcessInstanceListTable.tsx | 18 ++-- .../src/routes/ProcessModelShow.tsx | 1 - 12 files changed, 116 insertions(+), 83 deletions(-) create mode 100644 spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py diff --git a/spiffworkflow-backend/bin/save_all_bpmn.py b/spiffworkflow-backend/bin/save_all_bpmn.py index 54a40841..fd44bb54 100644 --- a/spiffworkflow-backend/bin/save_all_bpmn.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py index 4bd175a7..106b0735 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/__init__.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/config/demo.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/demo.py index db5abf0e..06e9184d 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/demo.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py new file mode 100644 index 00000000..f20189e9 --- /dev/null +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/config/terraform_deployed_environment.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/terraform_deployed_environment.py index 458e541c..4310d76a 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/terraform_deployed_environment.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index b804563f..b4437ef8 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py index ccf992e4..0567120d 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 27d94025..d0d45918 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/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/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 495dbfc7..d3abd732 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/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 diff --git a/spiffworkflow-frontend/src/components/Notification.tsx b/spiffworkflow-frontend/src/components/Notification.tsx index a3a20077..d7f14e02 100644 --- a/spiffworkflow-frontend/src/components/Notification.tsx +++ b/spiffworkflow-frontend/src/components/Notification.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; // @ts-ignore import { Close, CheckmarkFilled } from '@carbon/icons-react'; // @ts-ignore diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 51d20d64..98b76df3 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -7,7 +7,7 @@ import { } from 'react-router-dom'; // @ts-ignore -import { Filter, Close, AddAlt, CheckmarkFilled } from '@carbon/icons-react'; +import { Filter, Close, AddAlt } from '@carbon/icons-react'; import { Button, ButtonSet, @@ -22,7 +22,6 @@ import { TableRow, TimePicker, Tag, - InlineNotification, Stack, Modal, ComboBox, @@ -373,12 +372,15 @@ export default function ProcessInstanceListTable({ titleOperation = 'Created'; } return ( - setProcessInstanceReportJustSaved(null)}> - {`'${ - processInstanceReportSelection - ? processInstanceReportSelection.identifier - : '' - }'`} + setProcessInstanceReportJustSaved(null)} + > + {`'${ + processInstanceReportSelection + ? processInstanceReportSelection.identifier + : '' + }'`} ); } diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 24abd140..ef0c65c1 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -21,7 +21,6 @@ import { ButtonSet, Modal, FileUploader, - InlineNotification, Table, TableHead, TableHeader, From 27099a0d8ef8d153af5f99e6d98e59276d72a878 Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 8 Dec 2022 17:12:19 -0500 Subject: [PATCH 11/11] mypy w/ burnettk cullerton --- .flake8 | 5 +++++ spiffworkflow-backend/.flake8 | 2 ++ .../src/spiffworkflow_backend/config/dev.py | 6 ++++-- .../services/file_system_service.py | 6 +++--- .../services/git_service.py | 18 +++++++++++------- .../integration/test_process_api.py | 2 +- spiffworkflow-frontend/.gitignore | 2 +- spiffworkflow-frontend/public/index.html | 1 - spiffworkflow-frontend/src/index.css | 1 - 9 files changed, 27 insertions(+), 16 deletions(-) diff --git a/.flake8 b/.flake8 index 07c407f7..d404e7fd 100644 --- a/.flake8 +++ b/.flake8 @@ -27,3 +27,8 @@ per-file-ignores = # this file overwrites methods from the logging library so we can't change them # and ignore long comment line spiffworkflow-backend/src/spiffworkflow_backend/services/logging_service.py:N802,B950 + + # TODO: fix the S issues: + # S607 Starting a process with a partial executable path + # S605 Starting a process with a shell: Seems safe, but may be changed in the future, consider rewriting without shell + spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py:S607,S101,D103,S605 diff --git a/spiffworkflow-backend/.flake8 b/spiffworkflow-backend/.flake8 index 16f7c559..1cc09c97 100644 --- a/spiffworkflow-backend/.flake8 +++ b/spiffworkflow-backend/.flake8 @@ -27,3 +27,5 @@ per-file-ignores = # this file overwrites methods from the logging library so we can't change them # and ignore long comment line src/spiffworkflow_backend/services/logging_service.py:N802,B950 + + tests/spiffworkflow_backend/integration/test_process_api.py:S607,S101,D103,S605 diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py index f20189e9..182d08de 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/dev.py @@ -1,6 +1,8 @@ -"""dev.""" +"""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") +GIT_USER_EMAIL = environ.get( + "GIT_USER_EMAIL", default="sartography-automated-committer@users.noreply.github.com" +) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py index 0567120d..eb37afca 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/file_system_service.py @@ -2,7 +2,7 @@ import os from contextlib import contextmanager from datetime import datetime -from typing import List +from typing import Generator, List from typing import Optional import pytz @@ -25,9 +25,9 @@ class FileSystemService: PROCESS_MODEL_JSON_FILE = "process_model.json" # https://stackoverflow.com/a/24176022/6090676 - @contextmanager @staticmethod - def cd(newdir): + @contextmanager + def cd(newdir: str) -> Generator: """Cd.""" prevdir = os.getcwd() os.chdir(os.path.expanduser(newdir)) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index d0d45918..4a903736 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -44,7 +44,7 @@ class GitService: return file_contents.encode("utf-8") @staticmethod - def commit(message: str, repo_path: Optional[str]) -> str: + def commit(message: str, repo_path: Optional[str] = None) -> str: """Commit.""" repo_path_to_use = repo_path if repo_path is None: @@ -73,10 +73,14 @@ class GitService: clone_dir = f"sample-process-models.{unique_hex}" # clone new instance of sample-process-models, checkout branch_to_update - destination_process_root = f"/tmp/{clone_dir}" - 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}" + # we are adding a guid to this so the flake8 issue has been mitigated + destination_process_root = f"/tmp/{clone_dir}" # noqa + + cmd = ( + f"git clone https://{current_app.config['GIT_USERNAME']}:{current_app.config['GIT_USER_PASSWORD']}" + f"@github.com/sartography/sample-process-models.git {destination_process_root}" ) + os.system(cmd) # noqa: S605 with FileSystemService.cd(destination_process_root): # create publish branch from branch_to_update os.system(f"git checkout {branch_to_update}") # noqa: S605 @@ -84,7 +88,7 @@ class GitService: 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}") + os.system(f"git checkout {publish_branch}") # noqa: S605 else: os.system(f"git checkout -b {publish_branch}") # noqa: S605 @@ -99,10 +103,10 @@ class GitService: # 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") + os.system("git push") # noqa # build url for github page to open PR - output = os.popen("git config --get remote.origin.url").read() + output = os.popen("git config --get remote.origin.url").read() # noqa remote_url = output.strip().replace(".git", "") pr_url = f"{remote_url}/compare/{publish_branch}?expand=1" diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index d3abd732..e7edae60 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -2664,7 +2664,7 @@ class TestProcessApi(BaseTest): assert "process_model.json" in listing assert "new_file.txt" in listing - modified_process_model_id = process_model_identifier.replace("/", ":") + # modified_process_model_id = process_model_identifier.replace("/", ":") # response = client.post( # f"/v1.0/process-models/{modified_process_model_id}/publish?branch_to_update=staging", # headers=self.logged_in_headers(with_super_admin_user), diff --git a/spiffworkflow-frontend/.gitignore b/spiffworkflow-frontend/.gitignore index a694da80..8ff3e35c 100644 --- a/spiffworkflow-frontend/.gitignore +++ b/spiffworkflow-frontend/.gitignore @@ -29,4 +29,4 @@ cypress/screenshots /test*.json # Editors -.idea \ No newline at end of file +.idea diff --git a/spiffworkflow-frontend/public/index.html b/spiffworkflow-frontend/public/index.html index 8e5b00b0..ae3a2307 100644 --- a/spiffworkflow-frontend/public/index.html +++ b/spiffworkflow-frontend/public/index.html @@ -41,4 +41,3 @@ --> - diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index 5701a4f1..248a23d7 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -370,4 +370,3 @@ svg.notification-icon { .tag-type-green:hover { background-color: #80ee90; } -