Refactor the CI pipeline to use WithServiceBinding for the Stalwart mail server, replacing legacy shell scripts and manual port management. Introduces pre-seeded data for the Stalwart service to avoid network hits and improves headless UI testing with Xvfb.
81 lines
2.9 KiB
Bash
Executable File
81 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Starts a Stalwart instance for local development and integration tests.
|
|
#
|
|
# By default it uses STALWART_PORT from the environment. When STALWART_PORT=0
|
|
# or STALWART_RANDOM_PORTS=1, three free random ports are chosen and written to
|
|
# STALWART_TMPDIR/ports.env for other scripts to source.
|
|
set -euo pipefail
|
|
|
|
if [ "${STALWART_RANDOM_PORTS:-0}" = "1" ] || [ "${STALWART_PORT:-0}" = "0" ]; then
|
|
command -v python3 >/dev/null || {
|
|
echo "python3 not in PATH — cannot choose random Stalwart ports"
|
|
exit 1
|
|
}
|
|
read -r STALWART_PORT STALWART_IMAP_PORT STALWART_SMTP_PORT STALWART_SIEVE_PORT < <(
|
|
python3 - <<'PY'
|
|
import socket
|
|
ports = []
|
|
for _ in range(4):
|
|
sock = socket.socket()
|
|
sock.bind(("127.0.0.1", 0))
|
|
ports.append(str(sock.getsockname()[1]))
|
|
sock.close()
|
|
print(" ".join(ports))
|
|
PY
|
|
)
|
|
else
|
|
: "${STALWART_PORT:?STALWART_PORT is not set — run this inside nix develop}"
|
|
STALWART_IMAP_PORT="${STALWART_IMAP_PORT:-$((STALWART_PORT + 1))}"
|
|
STALWART_SMTP_PORT="${STALWART_SMTP_PORT:-$((STALWART_PORT + 2))}"
|
|
STALWART_SIEVE_PORT="${STALWART_SIEVE_PORT:-$((STALWART_PORT + 3))}"
|
|
fi
|
|
|
|
export STALWART_PORT STALWART_IMAP_PORT STALWART_SMTP_PORT STALWART_SIEVE_PORT
|
|
export STALWART_URL="http://127.0.0.1:${STALWART_PORT}"
|
|
|
|
TMPDIR="${STALWART_TMPDIR:-/tmp/stalwart-dev-${STALWART_PORT}}"
|
|
mkdir -p "$TMPDIR"
|
|
|
|
for port in "$STALWART_PORT" "$STALWART_IMAP_PORT" "$STALWART_SMTP_PORT" "$STALWART_SIEVE_PORT"; do
|
|
ss -ltnH "sport = :$port" | grep -q . && {
|
|
echo "Stalwart port $port is already in use"
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
cat >"${TMPDIR}/ports.env" <<EOF
|
|
export STALWART_PORT=${STALWART_PORT}
|
|
export STALWART_IMAP_PORT=${STALWART_IMAP_PORT}
|
|
export STALWART_SMTP_PORT=${STALWART_SMTP_PORT}
|
|
export STALWART_SIEVE_PORT=${STALWART_SIEVE_PORT}
|
|
export STALWART_URL=${STALWART_URL}
|
|
EOF
|
|
|
|
# Find a container runtime
|
|
if command -v podman >/dev/null 2>&1; then
|
|
RUNTIME="podman"
|
|
elif command -v docker >/dev/null 2>&1; then
|
|
RUNTIME="docker"
|
|
else
|
|
echo "No container runtime (podman or docker) found" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Stalwart ports: JMAP=${STALWART_PORT} IMAP=${STALWART_IMAP_PORT} SMTP=${STALWART_SMTP_PORT} SIEVE=${STALWART_SIEVE_PORT}" >&2
|
|
echo "Stalwart is running in a container (${RUNTIME}). Press Ctrl+C to stop." >&2
|
|
echo "Connection info written to ${TMPDIR}/ports.env" >&2
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
|
|
# Run Stalwart in container, mapping the random host ports to the fixed container ports.
|
|
# We mount the config.toml and use /tmp/stalwart for data (mapped to our local TMPDIR).
|
|
exec "${RUNTIME}" run --rm -i \
|
|
-p "${STALWART_PORT}:8080" \
|
|
-p "${STALWART_IMAP_PORT}:1430" \
|
|
-p "${STALWART_SMTP_PORT}:1025" \
|
|
-p "${STALWART_SIEVE_PORT}:4190" \
|
|
-v "${REPO_ROOT}/stalwart-dev/config.toml:/etc/stalwart/config.toml:ro" \
|
|
-v "${TMPDIR}:/tmp/stalwart:rw" \
|
|
docker.io/stalwartlabs/stalwart:v0.14.1 \
|
|
stalwart --config /etc/stalwart/config.toml
|