Failure to run test pre-action on Xcode 15

I have a script which properly spins up a database for testing on my local machine.

I’m trying to make Xcode test pre-actions execute that, with no success.

When it reaches a line like “open -a Docker”, it successfully opens up Docker, but if you try to execute any Docker commands, e.g. “docker run”, either nothing will happen, or it will hang (not sure which one, probably both of those are related to the command just not working at all, and how the script is set up.)

Is there any hope?

Answered by Mahdi Bm in 771863022

The solution was to 1- Repair the PATH that is passed to the script by:

# Update PATH incase it's run from Xcode scripts.
PATH="$PATH:/usr/local/bin/:/opt/homebrew/bin/"

And also take the BASE_DIR from the script itself:

# Take an argument for BASE_DIR, incase this is run from Xcode scripts.
if [ "$1" != "" ]; then
  note "Got BASE_DIR argument: $1"
  BASE_DIR=$1
fi

The Xcode-pre-script would calculate the BASE_DIR someway like this, and pass it to the script:

BASE_DIR=${WORKSPACE_PATH%%/.swiftpm*}

cd $BASE_DIR

echo "note: Xcode script calculated BASE_DIR to be $BASE_DIR"

. ./scripts/<name>.command $BASE_DIR || true

Worths noting that the script runs fine outside an Xcode pre-action.

For even more context, this is the actual script:

#!/bin/bash

# Creates the test-database
# Assumption is that this is used on a mac
# Docker app must be installed

BASE_DIR=$(dirname $0)
POSTGRES_DB="..."
POSTGRES_USER="..."
POSTGRES_PASSWORD="..."
CONTAINER_NAME="..."

print() {
  echo -n "note: "
  echo "$1"
}

error() {
  echo -n "error: "
  echo "$1"
  exit 1
}

if (ps aux | grep "Docker" | grep -v "grep" > /dev/null); then
  print "Docker is already running, that's good!"
else
  print "Docker is not running, will try to open Docker app"
  open -b com.docker.docker

  # Wait for docker to spin up
  until docker info >/dev/null 2>&1; do sleep 0.1; done
  sleep 0.5
fi

if (docker ps -a | grep $CONTAINER_NAME > /dev/null); then
  print "Docker container is already available, will remove this instance"
  docker rm -f $CONTAINER_NAME >/dev/null 2>&1
fi

print "Will create Docker container"

docker run --name $CONTAINER_NAME \
  -e POSTGRES_DB=$POSTGRES_DB \
  -e POSTGRES_USER=$POSTGRES_USER \
  -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
  -p 5432:5432 \
  -d postgres:14 \
  >/dev/null 2>&1

# Wait for the container to spin up
until [ "`docker inspect -f {{.State.Status}} $CONTAINER_NAME`" = "running" ]; do sleep 0.1; done
sleep 0.5

print "Searching for initial migrations path in $BASE_DIR"

INIT_MIGRS_PATH=$(find $BASE_DIR -type d -name "...")

if [[ -z "$INIT_MIGRS_PATH" ]]; then
  print "Initial migrations not visible from this directory. Will search the parent directory"
  INIT_MIGRS_PATH=$(find $BASE_DIR/.. -type d -name "...")
fi

if [[ -z "$INIT_MIGRS_PATH" ]]; then
  error "Could not find initial migrations path"
fi

print "Found initial migrations path: $INIT_MIGRS_PATH. Will copy them to the container"

docker cp $INIT_MIGRS_PATH/sql $CONTAINER_NAME:/root >/dev/null 2>&1

print "Initial migrations copied to container. Will run them"

docker exec $CONTAINER_NAME /bin/bash -c \
"find /root/sql -iname \"*.sql\" -exec bash -c 'PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h localhost -U $POSTGRES_USER $POSTGRES_DB -f \"{}\"' \\;" >/dev/null 2>&1

print "Test database is ready now!"

And i know Xcode does start executing it because it opens up the Docker app from the first few lines of the command. In the pre-action script, i just have something like ". ./path/to/script" with "/bin/bash" as shell.

Accepted Answer

The solution was to 1- Repair the PATH that is passed to the script by:

# Update PATH incase it's run from Xcode scripts.
PATH="$PATH:/usr/local/bin/:/opt/homebrew/bin/"

And also take the BASE_DIR from the script itself:

# Take an argument for BASE_DIR, incase this is run from Xcode scripts.
if [ "$1" != "" ]; then
  note "Got BASE_DIR argument: $1"
  BASE_DIR=$1
fi

The Xcode-pre-script would calculate the BASE_DIR someway like this, and pass it to the script:

BASE_DIR=${WORKSPACE_PATH%%/.swiftpm*}

cd $BASE_DIR

echo "note: Xcode script calculated BASE_DIR to be $BASE_DIR"

. ./scripts/<name>.command $BASE_DIR || true
Failure to run test pre-action on Xcode 15
 
 
Q