From 40bff8a89d5a905b195c575e489d0afda035341c Mon Sep 17 00:00:00 2001 From: conrad96 Date: Wed, 29 Apr 2026 12:39:06 +0300 Subject: [PATCH 01/12] - updated v3.1 image tags - removed residual scripts - updated gitignore --- .gitignore | 3 +- build-install-local.sh | 25 ----------------- config.json | 2 +- install.sh | 62 ------------------------------------------ src/docker-compose.yml | 4 +-- 5 files changed, 5 insertions(+), 91 deletions(-) delete mode 100755 build-install-local.sh delete mode 100755 install.sh diff --git a/.gitignore b/.gitignore index fbf2a5ac..4282723c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build-packages .local -vendor/ \ No newline at end of file +vendor/ +.vscode/ \ No newline at end of file diff --git a/build-install-local.sh b/build-install-local.sh deleted file mode 100755 index a50d3ba7..00000000 --- a/build-install-local.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -# build an app-only package (ie don't include images) and store the package path -echo "building app-only package" -package=$(${LOCATION}/package --app | awk -F'saved package: ' '/^saved package: / {print $2}') -echo "generated package: {package}" - -# use a temp folder for unpacking and make sure to clean up when done -tmp="/tmp/build-install-local-$(date +%s)" -echo "prepping temp folder: {tmp}" -rm -rf $tmp -mkdir -p $tmp -trap 'rm -rf $tmp' EXIT - -# unpack to temp folder -echo "unpacking app package: $package" -tar xf $package -C $tmp - -# install package -echo "installing package" -${tmp}/*/install.sh - -echo "done." diff --git a/config.json b/config.json index 08fad59a..7b39f3b3 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "streamline-emr", "org": "streamline", - "version": "3.0", + "version": "3.1", "platforms": [ "linux/arm64" ] diff --git a/install.sh b/install.sh deleted file mode 100755 index bc754000..00000000 --- a/install.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# -# Copyright (C) Wendepunkt Medical Innovations, Inc - All Rights Reserved. -# Unauthorized copying of this file, via any medium is strictly prohibited. -# Proprietary and confidential -# -# For information: dev@signalytic.ca -# - -# -# Install the streamline-emr application -# -# The caller of this script must check the exit value and possibly do a -# roll-back if it is non-zero. If the exit value is non-zero services have not -# been restarted. -# -# Note: This version resets data from v1 installations - -LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -if [ "$EUID" -ne 0 ] - then echo "Please run as root" - exit 1 -fi - -set -e - -APP_SLUG="streamline_emr" -ORG_SLUG="streamline" -INSTALL_ROOT="/var/signalytic/clientapps/${ORG_SLUG}/${APP_SLUG}" -VERSION_FILE="${INSTALL_ROOT}/version" -DATA_ROOT="${INSTALL_ROOT}/data" - -# stop the application (if installed) -if [ -f ${INSTALL_ROOT}/stop ]; then - ${INSTALL_ROOT}/stop -fi - -# reset data for any v1 or v2.0 installations -if grep -q "^1." ${VERSION_FILE} || grep -q "^2.0" ${VERSION_FILE}; then - echo "demo installation detected (v$(cat ${VERSION_FILE})) - resetting data" - rm -rf ${DATA_ROOT} -fi - -# copy root files (if present) -if [ -d "${LOCATION}/root" ] && [ -n "$(ls -A ${LOCATION}/root)" ]; then - echo "importing root files" - cp -rfv $LOCATION/root/* / -fi - -# import docker images (if present) -for f in $(find $LOCATION/images -name "*.img" 2>/dev/null);do - echo "importing docker image: $f" - docker load -i $f -done -for f in $(find $LOCATION/images -name "*.img.xz" 2>/dev/null);do - echo "importing docker image: $f" - xz -d -c $f | docker load -done - -# start the application -${INSTALL_ROOT}/start diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 7da8be41..f96adf84 100755 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -1,6 +1,6 @@ services: streamline-emr: - image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:v3 + image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.1 container_name: streamline-emr restart: unless-stopped volumes: @@ -18,7 +18,7 @@ services: retries: 5 statistics: - image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/statistics/arm64:v3 + image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/statistics/arm64:3.1 container_name: streamline-emr-statistics restart: unless-stopped environment: From 52d336ae20c26e559c226e80b73a4dace2fb86ed Mon Sep 17 00:00:00 2001 From: conrad96 Date: Wed, 6 May 2026 12:36:31 +0300 Subject: [PATCH 02/12] added clientappctl for app-dev-updates --- scripts/clientappctl | 205 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100755 scripts/clientappctl diff --git a/scripts/clientappctl b/scripts/clientappctl new file mode 100755 index 00000000..ed462881 --- /dev/null +++ b/scripts/clientappctl @@ -0,0 +1,205 @@ +#! /usr/bin/env python3 + +import sys, os, argparse, json, shutil, tempfile, subprocess, traceback + +def run_script(script_path: str) -> int: + """ + Helper to handle subprocess execution + Args: + script_path (str): script path to execute + Returns: + int: 0 if both succeed, 1 if any step fails + """ + if not os.path.exists(script_path): + print(f"Error: Script not found at {script_path}", file=sys.stderr) + return 1 + + try: + subprocess.run(f'{script_path}', check=True, capture_output=True, text=True) + return 0 + except subprocess.CalledProcessError as e: + print(f"Error: {os.path.basename(script_path)} failed (Exit {e.returncode})", file=sys.stderr) + print(f"Details: {e.stderr.strip() or e.stdout.strip()}", file=sys.stderr) + return 1 + except PermissionError: + print(f"Error: {os.path.basename(script_path)} is not executable. Check permissions.", file=sys.stderr) + return 1 + +def handle_start(src_dir, install_path): + """ + Start application + + Args: + src_dir (str): Path to source directory (Working directory) + install_path (str): Path to target installation directory + Returns: + int: 0 -> success + """ + + try: + # disable app + if os.path.exists(os.path.join(install_path, 'disable')): + subprocess.check_output(f'{install_path}/disable') + + # copy all source files to installation path + shutil.copytree(src_dir, install_path, dirs_exist_ok=True) + + # start application + run_script(f'{install_path}/start') + + return 0 + except Exception as ex: + print(f'Error: {ex}') + return 1 + +def handle_stop(install_path: str): + """ + Stop application + Args: + install_path (str): Path to installation directory + Returns: + int: 0 -> success + """ + + if not os.path.exists(os.path.join(install_path, 'stop')): + print(f"Error: stop script not found at {install_path}") + return 1 + + try: + # stop application + run_script(f'{install_path}/stop') + + return 0 + except subprocess.CalledProcessError as e: + print(f"Error: Stop script failed with exit code {e.returncode}") + print(f"Output: {e.stderr or e.stdout}") + return 1 + +def handle_restart(src_path: str, install_path: str): + """ + Restart application + Args: + install_path (str): Path to installation directory + Returns: + int: 0 -> success + """ + if handle_stop(install_path) != 0: + print("Restart aborted: Stop script execution failed.", file=sys.stderr) + return 1 + + if handle_start(src_path, install_path) != 0: + print("Restart aborted: Start script execution failed.", file=sys.stderr) + return 1 + + print('Application restarted successfully.') + return 0 + + +def uninstall_app(args: argparse.Namespace, install_path) -> int: + """ + Uninstall application at specified installation directory. + + Args: + install_path (str): Path to target installation directory. + Returns: + Int + """ + + rval = 0 + try: + + # disable application then uninstall + disable_path = os.path.join(install_path, 'disable') + stop_path = os.path.join(install_path, 'stop') + if os.path.exists(disable_path): + subprocess.check_output(disable_path) + + if os.path.exists(stop_path): + subprocess.check_output(stop_path) + + # reset vols, networks + subprocess.check_output(['docker', 'compose', f'-f {install_path}/docker-compose.yml', 'down', '-v']) + + if os.path.exists(install_path): + shutil.rmtree(install_path) + except Exception as e: + print(f'Exception encountered: {e}') + traceback.print_exc() + rval = 1 + return rval + +# script constants +utils_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) +temp_dir = tempfile.mkdtemp() +build_dir = os.path.join(temp_dir, 'build') +staging_dir = os.path.join(temp_dir, 'staging') +working_dir = working_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +src_path = os.path.join(working_dir, 'src') +CONFIG_JSON = os.path.join(working_dir, 'config.json') + +templates_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'hosted-app-utils', 'templates')) + +template_files = { + f'{templates_dir}/start': f'{working_dir}/src/start', + f'{templates_dir}/stop': f'{working_dir}/src/stop', + f'{templates_dir}/disable': f'{working_dir}/src/disable' +} + +# command line arguments +parser = argparse.ArgumentParser( + prog="clientappctl", + description="Manage client application operations. [ start, stop, restart ]") + +parser.add_argument("-c", "--config", default=CONFIG_JSON, help=f"Path to application configuration (default: {CONFIG_JSON})") + +subparsers = parser.add_subparsers(dest="command", required=True) + +start_parser = subparsers.add_parser("start", help="Start the application") +stop_parser = subparsers.add_parser("stop", help="Stop the application") +restart_parser = subparsers.add_parser("restart", help="Restart the application") + +def main() -> int: + # parse user args + args = parser.parse_args() + + # load configuration + try: + config_path = args.config + if not os.path.exists(config_path): + raise ValueError("Configuration not found.") + + with open(config_path) as f: + config_data = json.load(f) + name_slug = config_data['name'].strip().replace(' ', '_').replace('-', '_').lower() + org_slug = config_data['org'].strip().replace(' ', '_').replace('-', '_').lower() + version = config_data['version'] + + install_path = f'/var/signalytic/clientapps/{org_slug}/{name_slug}' + + # copy temp files into working dir + for src, dest in template_files.items(): + if not os.path.exists(src): + continue + shutil.copy(src, dest) + + if args.command == "start": + print(f"Starting app: {config_data['name']}-{version}") + + if not os.path.exists(install_path): + os.makedirs(install_path) + return handle_start(src_path, install_path) + elif args.command == "stop": + print(f"Stopping app: {config_data['name']}-{version}") + return handle_stop(install_path) + elif args.command == "restart": + print(f"Restarting app: {config_data['name']}-{version}") + return handle_restart(src_path, install_path) + else: + raise ValueError('Invalid operation passed.') + + except Exception as ex: + print(f'Error: {ex}') + return 1 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file From fde938dc9dce96ec63778c46eac5ec74efa53a85 Mon Sep 17 00:00:00 2001 From: conrad96 Date: Wed, 6 May 2026 12:36:50 +0300 Subject: [PATCH 03/12] updated package script --- package | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package b/package index f20f1820..89344df6 100755 --- a/package +++ b/package @@ -5,6 +5,6 @@ LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" CONFIG=${CONFIG:-${LOCATION}/config.json} SRC=${SRC:-${LOCATION}/src} BUILD_DIR=${BUILD_DIR:-${LOCATION}/build-packages} -INSTALL_SCRIPT=${LOCATION}/install.sh +#INSTALL_SCRIPT=${LOCATION}/install.sh -${LOCATION}/hosted-app-utils/package ${CONFIG} ${SRC} ${INSTALL_SCRIPT} output=${BUILD_DIR} $@ +${LOCATION}/hosted-app-utils/package ${CONFIG} ${SRC} output=${BUILD_DIR} $@ From 28fb0e5c53163a71e23305308a1a639788c54b55 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 7 May 2026 16:41:56 +0000 Subject: [PATCH 04/12] bump image and version to 3.2; use latest hosted-app-utils --- config.json | 2 +- hosted-app-utils | 2 +- src/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) mode change 100755 => 100644 src/docker-compose.yml diff --git a/config.json b/config.json index 7b39f3b3..fe3263b8 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "streamline-emr", "org": "streamline", - "version": "3.1", + "version": "3.2", "platforms": [ "linux/arm64" ] diff --git a/hosted-app-utils b/hosted-app-utils index 6af4c4ae..98c3a9ba 160000 --- a/hosted-app-utils +++ b/hosted-app-utils @@ -1 +1 @@ -Subproject commit 6af4c4ae8520e499c53a6bd80567454061e89103 +Subproject commit 98c3a9ba36a477e00c34eeb838674b70132659df diff --git a/src/docker-compose.yml b/src/docker-compose.yml old mode 100755 new mode 100644 index f96adf84..928d62d1 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -1,6 +1,6 @@ services: streamline-emr: - image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.1 + image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.2 container_name: streamline-emr restart: unless-stopped volumes: From ae235109abe23b3040ddfe6e075ad6654ed62dc0 Mon Sep 17 00:00:00 2001 From: conrad96 Date: Fri, 22 May 2026 10:44:14 +0300 Subject: [PATCH 05/12] - updated streamline-image tag - updated package version - edit source image tags --- config.json | 2 +- docker/Dockerfile.streamline-emr.arm64 | 2 +- src/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index fe3263b8..71c6b8be 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "streamline-emr", "org": "streamline", - "version": "3.2", + "version": "3.3", "platforms": [ "linux/arm64" ] diff --git a/docker/Dockerfile.streamline-emr.arm64 b/docker/Dockerfile.streamline-emr.arm64 index 53c93670..eca683ac 100644 --- a/docker/Dockerfile.streamline-emr.arm64 +++ b/docker/Dockerfile.streamline-emr.arm64 @@ -1 +1 @@ -FROM streamlinehealth/streamline:signalytic \ No newline at end of file +FROM streamline:signalytic_latest \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 928d62d1..272200f9 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -1,6 +1,6 @@ services: streamline-emr: - image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.2 + image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.3 container_name: streamline-emr restart: unless-stopped volumes: From b9c59fede7d4c8b668a3a71c27507f28c48546cd Mon Sep 17 00:00:00 2001 From: conrad96 Date: Fri, 28 Aug 2026 11:34:11 +0300 Subject: [PATCH 06/12] - streamline-emr printing bugfixes - updated version --- config.json | 2 +- src/docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 71c6b8be..bd88e6c7 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "name": "streamline-emr", "org": "streamline", - "version": "3.3", + "version": "3.4", "platforms": [ "linux/arm64" ] diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 272200f9..ab7addc1 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -1,6 +1,6 @@ services: streamline-emr: - image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.3 + image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:3.4 container_name: streamline-emr restart: unless-stopped volumes: From d8da3f11eb4bcc51214bea78b24a5e2ab6533987 Mon Sep 17 00:00:00 2001 From: Conrad Mugisha Date: Fri, 28 Aug 2026 09:42:19 +0000 Subject: [PATCH 07/12] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- scripts/clientappctl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/clientappctl b/scripts/clientappctl index ed462881..9099021f 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -45,7 +45,8 @@ def handle_start(src_dir, install_path): shutil.copytree(src_dir, install_path, dirs_exist_ok=True) # start application - run_script(f'{install_path}/start') + if run_script(f'{install_path}/start') != 0: + return 1 return 0 except Exception as ex: From d04fd977915a08140094abac43aa9305b9c2be95 Mon Sep 17 00:00:00 2001 From: Conrad Mugisha Date: Fri, 28 Aug 2026 09:45:28 +0000 Subject: [PATCH 08/12] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- scripts/clientappctl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/clientappctl b/scripts/clientappctl index 9099021f..e1f3250c 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -68,7 +68,8 @@ def handle_stop(install_path: str): try: # stop application - run_script(f'{install_path}/stop') + if run_script(f'{install_path}/stop') != 0: + return 1 return 0 except subprocess.CalledProcessError as e: From 605702f19fa2e0af1850c5692db456b4a9e6f60e Mon Sep 17 00:00:00 2001 From: Conrad Mugisha Date: Fri, 28 Aug 2026 09:45:55 +0000 Subject: [PATCH 09/12] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- scripts/clientappctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/clientappctl b/scripts/clientappctl index e1f3250c..1a72a6f6 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -120,7 +120,7 @@ def uninstall_app(args: argparse.Namespace, install_path) -> int: subprocess.check_output(stop_path) # reset vols, networks - subprocess.check_output(['docker', 'compose', f'-f {install_path}/docker-compose.yml', 'down', '-v']) + subprocess.check_output(['docker', 'compose', '-f', f'{install_path}/docker-compose.yml', 'down', '-v']) if os.path.exists(install_path): shutil.rmtree(install_path) From d2a4558a3913df7f21d8c25acc1cc74b304b60bf Mon Sep 17 00:00:00 2001 From: Conrad Mugisha Date: Fri, 28 Aug 2026 09:48:30 +0000 Subject: [PATCH 10/12] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- scripts/clientappctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/clientappctl b/scripts/clientappctl index 1a72a6f6..4800c223 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -135,7 +135,7 @@ utils_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) temp_dir = tempfile.mkdtemp() build_dir = os.path.join(temp_dir, 'build') staging_dir = os.path.join(temp_dir, 'staging') -working_dir = working_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +working_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) src_path = os.path.join(working_dir, 'src') CONFIG_JSON = os.path.join(working_dir, 'config.json') From 119908dfec57af42c8513ce0a229674e8a1d7824 Mon Sep 17 00:00:00 2001 From: conrad96 Date: Fri, 28 Aug 2026 13:04:44 +0300 Subject: [PATCH 11/12] - review cleanups --- package | 1 - scripts/clientappctl | 37 ++----------------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/package b/package index 89344df6..97c24c5d 100755 --- a/package +++ b/package @@ -5,6 +5,5 @@ LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" CONFIG=${CONFIG:-${LOCATION}/config.json} SRC=${SRC:-${LOCATION}/src} BUILD_DIR=${BUILD_DIR:-${LOCATION}/build-packages} -#INSTALL_SCRIPT=${LOCATION}/install.sh ${LOCATION}/hosted-app-utils/package ${CONFIG} ${SRC} output=${BUILD_DIR} $@ diff --git a/scripts/clientappctl b/scripts/clientappctl index 4800c223..52dc31ce 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -13,7 +13,7 @@ def run_script(script_path: str) -> int: if not os.path.exists(script_path): print(f"Error: Script not found at {script_path}", file=sys.stderr) return 1 - + try: subprocess.run(f'{script_path}', check=True, capture_output=True, text=True) return 0 @@ -97,39 +97,6 @@ def handle_restart(src_path: str, install_path: str): return 0 -def uninstall_app(args: argparse.Namespace, install_path) -> int: - """ - Uninstall application at specified installation directory. - - Args: - install_path (str): Path to target installation directory. - Returns: - Int - """ - - rval = 0 - try: - - # disable application then uninstall - disable_path = os.path.join(install_path, 'disable') - stop_path = os.path.join(install_path, 'stop') - if os.path.exists(disable_path): - subprocess.check_output(disable_path) - - if os.path.exists(stop_path): - subprocess.check_output(stop_path) - - # reset vols, networks - subprocess.check_output(['docker', 'compose', '-f', f'{install_path}/docker-compose.yml', 'down', '-v']) - - if os.path.exists(install_path): - shutil.rmtree(install_path) - except Exception as e: - print(f'Exception encountered: {e}') - traceback.print_exc() - rval = 1 - return rval - # script constants utils_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) temp_dir = tempfile.mkdtemp() @@ -204,4 +171,4 @@ def main() -> int: return 1 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From 4578b8cd300de0f0d25b824f15b16157be298327 Mon Sep 17 00:00:00 2001 From: conrad96 Date: Fri, 28 Aug 2026 13:31:22 +0300 Subject: [PATCH 12/12] removed unused vars --- scripts/clientappctl | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/clientappctl b/scripts/clientappctl index 52dc31ce..17d42886 100755 --- a/scripts/clientappctl +++ b/scripts/clientappctl @@ -99,9 +99,6 @@ def handle_restart(src_path: str, install_path: str): # script constants utils_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) -temp_dir = tempfile.mkdtemp() -build_dir = os.path.join(temp_dir, 'build') -staging_dir = os.path.join(temp_dir, 'staging') working_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) src_path = os.path.join(working_dir, 'src') CONFIG_JSON = os.path.join(working_dir, 'config.json')