Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/backend-verify-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,34 @@
run:
working-directory: "./backend"
jobs:
test-start-sh:
name: 'Common Tests'
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
cache-dependency-path: backend/package-lock.json

- name: Install dependencies
run: npm ci

- name: 'Bats start.sh Tests'
run: |
npm install -g bats
npm run test:bats-start
env:
GITHUB_WORKSPACE: ${{ github.workspace }}

backend-build:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"start:watch": "npx tsx --watch index.ts",
"start:dev": "set -a ; . ./.env.social-app-backend ; npx tsx --watch index.ts",
"test": "set -a ; . ./environment/env.social-app-backend.template ; vitest run",
"test:bats-start": "bats -t ../tools/bats/test_start.bats",
"format": "eslint --fix . && prettier --write .",
"lint": "eslint . && prettier --check .",
"container-run:dev": "npm install && npm run start:watch",
Expand Down
40 changes: 26 additions & 14 deletions backend/scripts/local-init.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,26 @@ const main = async () => {
console.log('Creating an MSA...');
api.tx.msa.create().signAndSend(keys, {}, ({ status, events, dispatchError }) => {
if (dispatchError) {
console.error('ERROR: ', dispatchError.toHuman());
reject();
const errorDetails = dispatchError.toHuman();
console.log('Dispatch error details:', errorDetails);

// Check if the error is MsaAlreadyExists (Module index 60, error 0x00000000)
if (errorDetails.Module && errorDetails.Module.index === '60' && errorDetails.Module.error === '0x00000000') {
console.log('INFO: MSA already exists, continuing...');
resolve();
} else {
console.error('ERROR: ', errorDetails);
reject();
}
} else if (status.isInBlock || status.isFinalized) {
const evt = eventWithSectionAndMethod(events, 'msa', 'MsaCreated');
if (evt) {
const id = evt?.data[0];
console.log('SUCCESS: MSA Created: ' + id);
resolve();
} else {
console.error(
'ERROR: Expected event not found',
events.map((x) => x.toHuman())
);
reject();
console.log('INFO: MSA transaction completed');
resolve();
}
}
});
Expand All @@ -51,20 +57,26 @@ const main = async () => {
console.log('Creating a Provider...');
api.tx.msa.createProvider('alice').signAndSend(keys, {}, ({ status, events, dispatchError }) => {
if (dispatchError) {
console.error('ERROR: ', dispatchError.toHuman());
reject();
const errorDetails = dispatchError.toHuman();
console.log('Provider creation error details:', errorDetails);

// Check if it's a known "already exists" type error and continue
if (errorDetails.Module && errorDetails.Module.index === '60' && errorDetails.Module.error === '0x11000000') {
console.log('INFO: Provider may already exist, continuing...');
resolve();
} else {
console.error('ERROR: ', errorDetails);
reject();
}
} else if (status.isInBlock || status.isFinalized) {
const evt = eventWithSectionAndMethod(events, 'msa', 'ProviderCreated');
if (evt) {
const id = evt?.data[0];
console.log('SUCCESS: Provider Created: ' + id);
resolve();
} else {
console.error(
'ERROR: Expected event not found',
events.map((x) => x.toHuman())
);
reject();
console.log('INFO: Provider transaction completed');
resolve();
}
}
});
Expand Down
36 changes: 19 additions & 17 deletions bash_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,34 @@ BOX_WIDTH=96
# Wrangle grep because MacOS doesn't come with a PCRE-enabled grep by default.
# If we don't find one, disable our "pretty" output function.
###################################################################################
PCRE_GREP=
if echo "foobar" | grep -q -P "foo(?=bar)" >/dev/null 2>&1; then
PCRE_GREP=grep
else
# Grep is not PCRE compatible, check for other greps
if command -v ggrep >/dev/null; then # MacOS Homebrew might have ggrep
PCRE_GREP=ggrep
elif command -v pcre2grep > /dev/null; then # MacOS Homebrew could also have pcre2grep
PCRE_GREP=pcre2grep
function check_pcre_grep() {
PCRE_GREP=
if echo "foobar" | grep -q -P "foo(?=bar)" >/dev/null 2>&1; then
PCRE_GREP=grep
else
# Grep is not PCRE compatible, check for other greps
if command -v ggrep >/dev/null; then # MacOS Homebrew might have ggrep
PCRE_GREP=ggrep
elif command -v pcre2grep > /dev/null; then # MacOS Homebrew could also have pcre2grep
PCRE_GREP=pcre2grep
fi
fi
fi

if [ -z "${PCRE_GREP}" ]; then
cat << EOI
if [ -z "${PCRE_GREP}" ]; then
cat << EOI
WARNING: No PCRE-capable 'grep' utility found; pretty terminal output disabled.

If you're on a Mac, try installing GNU grep:
brew install grep

EOI
read -p 'Press any key to continue... '
read -p 'Press any key to continue... '

OUTPUT='echo -e'
else
OUTPUT="box_text -w ${BOX_WIDTH}"
fi
OUTPUT='echo -e'
else
OUTPUT="box_text -w ${BOX_WIDTH}"
fi
}

###################################################################################
# yesno
Expand Down
166 changes: 119 additions & 47 deletions start.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/bin/bash
# Script to start all SAT services on the Frequency Paseo Testnet

. ./bash_functions.sh
# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

. "${SCRIPT_DIR}/bash_functions.sh"

SKIP_CHAIN_SETUP=false

Expand All @@ -22,59 +25,86 @@ function show_help() {
###################################################################################
# Parse command-line arguments
###################################################################################
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--help) show_help; exit 0 ;;
-n|--name) BASE_NAME="$2"; shift ;;
-s|--skip-setup) SKIP_CHAIN_SETUP=true ;;
*) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
esac
shift
done

if [ ! -d ${BASE_DIR} ]
then
mkdir -p ${BASE_DIR}
fi
function parse_arguments() {
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--help) show_help; exit 0 ;;
-n|--name) BASE_NAME="$2"; shift ;;
-s|--skip-setup) SKIP_CHAIN_SETUP=true ;;
*) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
esac
shift
done
}

ENV_FILE=${BASE_DIR}/.env.${BASE_NAME}
COMPOSE_PROJECT_NAME=${BASE_NAME}
###################################################################################
# setup_environment
#
# Description: Set up environment variables and directories
#
###################################################################################
function setup_environment() {
if [ ! -d "${BASE_DIR}" ]; then
mkdir -p "${BASE_DIR}"
fi

if [[ -n $ENV_FILE ]]; then
echo -e "Using environment file: $ENV_FILE\n"
fi
ENV_FILE=${BASE_DIR}/.env.${BASE_NAME}
COMPOSE_PROJECT_NAME=${BASE_NAME}

####### Check for Docker and Docker Compose
if ! command -v docker &> /dev/null || ! command -v docker compose &> /dev/null; then
printf "Docker and Docker Compose are required but not installed. Please install them and try again.\n"
exit 1
fi
if [[ -n $ENV_FILE ]]; then
${OUTPUT} "Using environment file: $ENV_FILE"
fi
return 0
}

####### Check for existing ENV_FILE and ask user if they want to re-use it
if [ -f ${ENV_FILE} ]; then
echo -e "Found saved environment from a previous run:\n"
redacted_content=$(redact_sensitive_values "${ENV_FILE}")
echo "${redacted_content}"
###################################################################################
# check_dependencies
#
# Description: Ensure Docker and Docker Compose are installed
#
###################################################################################
function check_dependencies() {
if ! command -v docker &> /dev/null || ! command -v docker compose &> /dev/null; then
${OUTPUT} "Docker and Docker Compose are required but not installed. Please install them and try again.\n"
exit 1
fi
}

if yesno "Do you want to re-use the saved parameters" Y
then
${OUTPUT} "Loading environment values from file..."
else
clear
${OUTPUT} "Removing previous saved environment..."

rm ${ENV_FILE}
# If the file fails to delete, exit the script
if [ -f ${ENV_FILE} ]
then
${OUTPUT} "Failed to remove previous saved environment. Exiting..."
###################################################################################
# handle_env_file
#
# Description: Manage existing environment files
#
###################################################################################
function handle_env_file() {
if [ -f ${ENV_FILE} ]; then
echo -e "Found saved environment from a previous run:\n"
redacted_content=$(redact_sensitive_values "${ENV_FILE}")
echo "${redacted_content}"

if yesno "Do you want to re-use the saved parameters" Y; then
${OUTPUT} "Loading environment values from file..."
else
${OUTPUT} "Removing previous saved environment..."

rm ${ENV_FILE}
# If the file fails to delete, exit the script
if [ -f ${ENV_FILE} ]; then
${OUTPUT} "Failed to remove previous saved environment. Exiting..."
exit 1
fi
fi
fi
fi
return 0
}

######
###### If no existing ENV_FILE, run through all prompts
######
###################################################################################
# prompt_for_configuration
#
# Description: Interactive prompts to gather necessary configuration
#
###################################################################################
function prompt_for_configuration() {
if [ ! -f ${ENV_FILE} ]
then
${OUTPUT} << EOI
Expand Down Expand Up @@ -251,13 +281,17 @@ EOI

export_save_variable PROFILES "${PROFILES}"
fi
}

###################################################################################
# start_services
#
# Description: Start Docker Compose services based on selected profiles
# Finished with prompting (or skipped).
#
# Now read the resulting ENV_FILE and launch the services
###################################################################################

function start_services() {
set -a; source ${ENV_FILE}; set +a

if [ $DEV_CONTAINERS = true ]
Expand Down Expand Up @@ -302,7 +336,15 @@ ${OUTPUT} << EOI
🚀 You can access the Social App Template frontend at http://localhost:${FRONTEND_PORT} 🚀
EOI
fi
}

###################################################################################
# display_services_info
#
# Description: Display information about the running services
#
###################################################################################
function display_services_info() {
SERVICES_STR="\
The selected services are running.
You can access the Gateway at the following local addresses:
Expand Down Expand Up @@ -362,3 +404,33 @@ SERVICES_STR="${SERVICES_STR}
fi

box_text_attention -w 0 "${SERVICES_STR}"
}

###################################################################################
# main
#
# Description: Main function to execute the script logic
#
###################################################################################
function main() {
# Call the check_pcre_grep function to initialize PCRE_GREP and OUTPUT
check_pcre_grep
parse_arguments "$@"
setup_environment
check_dependencies
handle_env_file

if [ ! -f "${ENV_FILE}" ]; then
prompt_for_configuration
fi

start_services
display_services_info

exit 0
}

# Call main function if the script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
Loading