added git creds for pushing on publish w/ burnettk cullerton

This commit is contained in:
jasquat 2022-12-08 16:39:23 -05:00
parent 803835e76d
commit 62814da9a6
12 changed files with 116 additions and 83 deletions

View File

@ -1,13 +1,13 @@
"""Grabs tickets from csv and makes process instances.""" """Grabs tickets from csv and makes process instances."""
import os 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 from spiffworkflow_backend.services.data_setup_service import DataSetupService
def main() -> None: def main() -> None:
"""Main.""" """Main."""
app = get_hacked_up_app_for_script() app = create_app()
with app.app_context(): with app.app_context():
failing_process_models = DataSetupService.save_all_process_models() failing_process_models = DataSetupService.save_all_process_models()
for bpmn_errors in failing_process_models: for bpmn_errors in failing_process_models:

View File

@ -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: def setup_config(app: Flask) -> None:
"""Setup_config.""" """Setup_config."""
# ensure the instance folder exists # ensure the instance folder exists
@ -53,19 +64,14 @@ def setup_config(app: Flask) -> None:
app.config.from_object("spiffworkflow_backend.config.default") app.config.from_object("spiffworkflow_backend.config.default")
env_config_prefix = "spiffworkflow_backend.config." 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"] env_config_module = env_config_prefix + app.config["ENV_IDENTIFIER"]
try: load_config_file(app, env_config_module)
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
# This allows config/testing.py or instance/config.py to override the default config # 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": if "ENV_IDENTIFIER" in app.config and app.config["ENV_IDENTIFIER"] == "testing":

View File

@ -2,8 +2,8 @@
from os import environ from os import environ
GIT_COMMIT_ON_SAVE = True GIT_COMMIT_ON_SAVE = True
GIT_COMMIT_USERNAME = "demo" GIT_USERNAME = "demo"
GIT_COMMIT_EMAIL = "demo@example.com" GIT_USER_EMAIL = "demo@example.com"
SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get( SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get(
"SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME", "SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME",
default="terraform_deployed_environment.yml", default="terraform_deployed_environment.yml",

View File

@ -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")

View File

@ -5,8 +5,8 @@ from os import environ
environment_identifier_for_this_config_file_only = environ["SPIFFWORKFLOW_BACKEND_ENV"] environment_identifier_for_this_config_file_only = environ["SPIFFWORKFLOW_BACKEND_ENV"]
GIT_COMMIT_ON_SAVE = True GIT_COMMIT_ON_SAVE = True
GIT_COMMIT_USERNAME = environment_identifier_for_this_config_file_only GIT_USERNAME = environment_identifier_for_this_config_file_only
GIT_COMMIT_EMAIL = f"{environment_identifier_for_this_config_file_only}@example.com" 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 = environ.get(
"SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME", "SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME",
default="terraform_deployed_environment.yml", default="terraform_deployed_environment.yml",

View File

@ -371,12 +371,14 @@ def process_model_move(
def process_model_publish( def process_model_publish(
modified_process_model_identifier: str, modified_process_model_identifier: str, branch_to_update: Optional[str] = None
branch_to_update: Optional[str] = None
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_model_publish."""
if branch_to_update is None: if branch_to_update is None:
branch_to_update = current_app.config["GIT_MERGE_BRANCH"] 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) pr_url = GitService().publish(process_model_identifier, branch_to_update)
data = {"ok": True, "pr_url": pr_url} data = {"ok": True, "pr_url": pr_url}
return Response(json.dumps(data), status=200, mimetype="application/json") return Response(json.dumps(data), status=200, mimetype="application/json")

View File

@ -1,5 +1,6 @@
"""File_system_service.""" """File_system_service."""
import os import os
from contextlib import contextmanager
from datetime import datetime from datetime import datetime
from typing import List from typing import List
from typing import Optional from typing import Optional
@ -23,6 +24,18 @@ class FileSystemService:
PROCESS_GROUP_JSON_FILE = "process_group.json" PROCESS_GROUP_JSON_FILE = "process_group.json"
PROCESS_MODEL_JSON_FILE = "process_model.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 @staticmethod
def root_path() -> str: def root_path() -> str:
"""Root_path.""" """Root_path."""

View File

@ -1,8 +1,8 @@
"""Git_service.""" """Git_service."""
import os import os
import shutil import shutil
import uuid import uuid
from typing import Optional
from flask import current_app from flask import current_app
from flask import g from flask import g
@ -44,64 +44,69 @@ class GitService:
return file_contents.encode("utf-8") return file_contents.encode("utf-8")
@staticmethod @staticmethod
def commit(message: str) -> str: def commit(message: str, repo_path: Optional[str]) -> str:
"""Commit.""" """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_username = ""
git_email = "" git_email = ""
if ( if current_app.config["GIT_USERNAME"] and current_app.config["GIT_USER_EMAIL"]:
current_app.config["GIT_COMMIT_USERNAME"] git_username = current_app.config["GIT_USERNAME"]
and current_app.config["GIT_COMMIT_EMAIL"] git_email = current_app.config["GIT_USER_EMAIL"]
): shell_command_path = os.path.join(
git_username = current_app.config["GIT_COMMIT_USERNAME"] current_app.root_path, "..", "..", "bin", "git_commit_bpmn_models_repo"
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}'" shell_command = f"{shell_command_path} '{repo_path_to_use}' '{message}' '{git_username}' '{git_email}'"
output = os.popen(shell_command).read() # noqa: S605 output = os.popen(shell_command).read() # noqa: S605
return output return output
@staticmethod @classmethod
def publish(process_model_id: str, branch_to_update: str) -> str: def publish(cls, process_model_id: str, branch_to_update: str) -> str:
"""Publish."""
source_process_model_root = FileSystemService.root_path() 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 unique_hex = uuid.uuid4().hex
clone_dir = f"sample-process-models.{unique_hex}" clone_dir = f"sample-process-models.{unique_hex}"
# clone new instance of sample-process-models, checkout branch_to_update # clone new instance of sample-process-models, checkout branch_to_update
os.chdir("/tmp")
destination_process_root = f"/tmp/{clone_dir}" destination_process_root = f"/tmp/{clone_dir}"
os.system(f"git clone https://github.com/sartography/sample-process-models.git {clone_dir}") os.system(
os.chdir(destination_process_root) 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 # copy files from process model into the new publish branch
os.system(f"git checkout {branch_to_update}") # noqa: S605 destination_process_model_path = os.path.join(
publish_branch = f"publish-{process_model_id}" destination_process_root, process_model_id
command = f"git show-ref --verify refs/remotes/origin/{publish_branch}" )
output = os.popen(command).read() # noqa: S605 if os.path.exists(destination_process_model_path):
if output: shutil.rmtree(destination_process_model_path)
os.system(f"git checkout {publish_branch}") shutil.copytree(source_process_model_path, destination_process_model_path)
else:
os.system(f"git checkout -b {publish_branch}") # noqa: S605
# copy files from process model into the new publish branch # add and commit files to publish_branch, then push
destination_process_model_path = os.path.join(destination_process_root, process_model_id) commit_message = f"Request to publish changes to {process_model_id}, from {g.user.username}"
if os.path.exists(destination_process_model_path): cls.commit(commit_message, destination_process_root)
shutil.rmtree(destination_process_model_path) os.system("git push")
shutil.copytree(source_process_model_path, destination_process_model_path)
# add and commit files to publish_branch, then push # build url for github page to open PR
os.chdir(destination_process_root) output = os.popen("git config --get remote.origin.url").read()
os.system("git add .") # noqa: S605 remote_url = output.strip().replace(".git", "")
commit_message = f"Request to publish changes to {process_model_id}, from {g.user.username}" pr_url = f"{remote_url}/compare/{publish_branch}?expand=1"
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"
# try to clean up # try to clean up
os.chdir("/tmp")
if os.path.exists(destination_process_root): if os.path.exists(destination_process_root):
shutil.rmtree(destination_process_root) shutil.rmtree(destination_process_root)

View File

@ -2562,7 +2562,7 @@ class TestProcessApi(BaseTest):
with_db_and_bpmn_file_cleanup: None, with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel, with_super_admin_user: UserModel,
) -> None: ) -> None:
"""Test_process_model_publish."""
bpmn_root = FileSystemService.root_path() bpmn_root = FileSystemService.root_path()
shell_command = f"git init {bpmn_root}" shell_command = f"git init {bpmn_root}"
output = os.popen(shell_command).read() # noqa: S605 output = os.popen(shell_command).read() # noqa: S605
@ -2571,14 +2571,13 @@ class TestProcessApi(BaseTest):
output = os.popen("git status").read() # noqa: S605 output = os.popen("git status").read() # noqa: S605
assert "On branch main" in output assert "On branch main" in output
assert "No commits yet" 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" process_group_id = "test_group"
self.create_process_group( self.create_process_group(
client, client, with_super_admin_user, process_group_id, process_group_id
with_super_admin_user,
process_group_id,
process_group_id
) )
sub_process_group_id = "test_group/test_sub_group" 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) process_model_absolute_dir = os.path.join(bpmn_root, process_model_identifier)
output = os.popen("git status").read() # noqa: S605 output = os.popen("git status").read() # noqa: S605
test_string = \ test_string = 'Untracked files:\n (use "git add <file>..." to include in what will be committed)\n\ttest_group'
'Untracked files:\n (use "git add <file>..." to include in what will be committed)\n\ttest_group'
assert test_string in output assert test_string in output
os.system("git add .") os.system("git add .")
@ -2643,7 +2641,7 @@ class TestProcessApi(BaseTest):
file_data = b"abc123" file_data = b"abc123"
new_file_path = os.path.join(process_model_absolute_dir, "new_file.txt") 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) f_open.write(file_data)
output = os.popen("git status").read() # noqa: S605 output = os.popen("git status").read() # noqa: S605
@ -2651,7 +2649,9 @@ class TestProcessApi(BaseTest):
assert "Untracked files:" in output assert "Untracked files:" in output
assert "test_group/test_sub_group/hello_world/new_file.txt" 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 output = os.popen("git commit -m 'add new_file.txt'").read() # noqa: S605
assert "add new_file.txt" in output assert "add new_file.txt" in output

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React from 'react';
// @ts-ignore // @ts-ignore
import { Close, CheckmarkFilled } from '@carbon/icons-react'; import { Close, CheckmarkFilled } from '@carbon/icons-react';
// @ts-ignore // @ts-ignore

View File

@ -7,7 +7,7 @@ import {
} from 'react-router-dom'; } from 'react-router-dom';
// @ts-ignore // @ts-ignore
import { Filter, Close, AddAlt, CheckmarkFilled } from '@carbon/icons-react'; import { Filter, Close, AddAlt } from '@carbon/icons-react';
import { import {
Button, Button,
ButtonSet, ButtonSet,
@ -22,7 +22,6 @@ import {
TableRow, TableRow,
TimePicker, TimePicker,
Tag, Tag,
InlineNotification,
Stack, Stack,
Modal, Modal,
ComboBox, ComboBox,
@ -373,12 +372,15 @@ export default function ProcessInstanceListTable({
titleOperation = 'Created'; titleOperation = 'Created';
} }
return ( return (
<Notification title={`Perspective: ${titleOperation}`} onClose={() => setProcessInstanceReportJustSaved(null)}> <Notification
<span>{`'${ title={`Perspective: ${titleOperation}`}
processInstanceReportSelection onClose={() => setProcessInstanceReportJustSaved(null)}
? processInstanceReportSelection.identifier >
: '' <span>{`'${
}'`}</span> processInstanceReportSelection
? processInstanceReportSelection.identifier
: ''
}'`}</span>
</Notification> </Notification>
); );
} }

View File

@ -21,7 +21,6 @@ import {
ButtonSet, ButtonSet,
Modal, Modal,
FileUploader, FileUploader,
InlineNotification,
Table, Table,
TableHead, TableHead,
TableHeader, TableHeader,