#!/usr/bin/env bash # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set -e # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Function to __log messages with timestamp __log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"; } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Function to cleanup child processes on exit __cleanup() { __log "Shutting down runners..." kill $(jobs -p) 2>/dev/null || true wait __log "All runners stopped" } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Set up signal handling trap __cleanup SIGTERM SIGINT # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate required environment variables if [ -n "$SERVER_ADDRESS" ]; then if ! echo "$SERVER_ADDRESS" | grep -q '://'; then SERVER_ADDRESS="http://$SERVER_ADDRESS" fi else SERVER_ADDRESS=http://$HOSTNAME fi # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if [ -z "$SERVER_TOKEN" ]; then __log "ERROR: SERVER_TOKEN environment variable is required" exit 1 fi # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RUNNER_LABELS="${RUNNER_LABELS:-ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye}" # Determine number of runners to start RUNNERS_COUNT=${RUNNERS_ENABLE:-1} # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate RUNNERS_COUNT is a positive integer if ! [[ "$RUNNERS_COUNT" =~ ^[0-9]+$ ]] || [ "$RUNNERS_COUNT" -lt 1 ]; then __log "WARNING: Invalid RUNNERS_ENABLE value '$RUNNERS_ENABLE', defaulting to 1" RUNNERS_COUNT=1 fi # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __log "Starting $RUNNERS_COUNT act_runner instance(s)" __log "Server Address: $SERVER_ADDRESS" __log "Runner Name Prefix: ${RUNNER_NAME_PREFIX:-runner}" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Function to start a single runner __start_runner() { local runner_id=$1 local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}" local runner_dir="/config/act_runner/reg/${runner_name}" # Create runner directory mkdir -p "$runner_dir" cd "$runner_dir" __log "Starting runner: $runner_name (ID: $runner_id)" # Register the runner (this creates the .runner file) __log "Registering runner: $runner_name" act_runner register --instance "$SERVER_ADDRESS" --token "$SERVER_TOKEN" --name "$runner_name" --labels "$RUNNER_LABELS" --no-interactive if [ $? -ne 0 ]; then __log "ERROR: Failed to register runner $runner_name" return 1 fi # Start the daemon __log "Starting daemon for runner: $runner_name" exec act_runner daemon --config .runner } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Start runners in background for i in $(seq 1 $RUNNERS_COUNT); do (__start_runner $i) & sleep 2 # Small delay between starting runners done unset i # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __log "All $RUNNERS_COUNT runners started successfully" __log "Process IDs: $(jobs -p | tr '\n' ' ')" # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Wait for all background processes wait