Files
git.stella-ops.org/devops/ci-local/run-act.sh
2026-02-01 21:37:40 +02:00

141 lines
3.6 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# LOCAL ACT RUNNER (Bash)
# =============================================================================
# Thin wrapper around nektos/act for local CI execution.
# For full-featured local CI (smoke, pr, module modes) use:
# ./devops/scripts/local-ci.sh
#
# Usage:
# ./devops/ci-local/run-act.sh [options]
#
# Options:
# -w, --workflow <name> Workflow file (with or without .yml)
# -j, --job <name> Run only a specific job
# -l, --list List available jobs
# -n, --dry-run Dry-run mode
# -e, --event <type> Event type: pull_request (default) or push
# -r, --rebuild Force rebuild CI image
# -v, --verbose Verbose output
# -h, --help Show this help
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CI_IMAGE="stellaops-ci:local"
CI_DOCKERFILE="$REPO_ROOT/devops/docker/Dockerfile.ci"
# Defaults
WORKFLOW=""
JOB=""
LIST=false
DRY_RUN=false
EVENT="pull_request"
REBUILD=false
VERBOSE=false
usage() {
head -25 "$0" | grep '^#' | sed 's/^# \?//'
exit 0
}
# ---- Parse args ----
while [[ $# -gt 0 ]]; do
case "$1" in
-w|--workflow) WORKFLOW="$2"; shift 2 ;;
-j|--job) JOB="$2"; shift 2 ;;
-l|--list) LIST=true; shift ;;
-n|--dry-run) DRY_RUN=true; shift ;;
-e|--event) EVENT="$2"; shift 2 ;;
-r|--rebuild) REBUILD=true; shift ;;
-v|--verbose) VERBOSE=true; shift ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
# ---- Prerequisite checks ----
if ! docker info &>/dev/null; then
echo "ERROR: Docker is not running." >&2
exit 1
fi
if ! command -v act &>/dev/null; then
echo "ERROR: act is not installed." >&2
echo " macOS: brew install act" >&2
echo " Linux: curl -sSL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash" >&2
echo " Windows: choco install act-cli" >&2
exit 1
fi
# ---- Build CI image if needed ----
image_exists() {
docker image inspect "$CI_IMAGE" &>/dev/null
}
if [[ "$REBUILD" == "true" ]] || ! image_exists; then
echo "[ci-local] Building CI image $CI_IMAGE ..."
docker build -t "$CI_IMAGE" -f "$CI_DOCKERFILE" "$REPO_ROOT"
fi
# ---- Ensure .env.local ----
ENV_LOCAL="$SCRIPT_DIR/.env.local"
if [[ ! -f "$ENV_LOCAL" ]]; then
echo "[ci-local] Creating .env.local from template ..."
cp "$SCRIPT_DIR/.env.local.template" "$ENV_LOCAL"
fi
# ---- Assemble act arguments ----
act_args=()
if [[ "$LIST" == "true" ]]; then
cd "$REPO_ROOT"
exec act -l
fi
if [[ -n "$WORKFLOW" ]]; then
wf_file="$WORKFLOW"
[[ "$wf_file" != *.yml ]] && wf_file="${wf_file}.yml"
wf_path="$REPO_ROOT/.gitea/workflows/$wf_file"
if [[ ! -f "$wf_path" ]]; then
echo "ERROR: Workflow not found: $wf_path" >&2
exit 1
fi
act_args+=(-W "$wf_path")
fi
if [[ -n "$JOB" ]]; then
act_args+=(-j "$JOB")
fi
# Event file
case "$EVENT" in
pull_request) event_file="$SCRIPT_DIR/events/pull-request.json" ;;
push) event_file="$SCRIPT_DIR/events/push.json" ;;
*) echo "ERROR: Unknown event type: $EVENT" >&2; exit 1 ;;
esac
if [[ -f "$event_file" ]]; then
act_args+=(--eventpath "$event_file")
fi
if [[ "$DRY_RUN" == "true" ]]; then
act_args+=(-n)
fi
if [[ "$VERBOSE" == "true" ]]; then
act_args+=(--verbose)
fi
# ---- Run ----
echo "[ci-local] act ${act_args[*]}"
cd "$REPO_ROOT"
exec act "${act_args[@]}"