141 lines
3.6 KiB
Bash
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[@]}"
|