Capture current working state before converting platform-tooling into a submodule of the lilith-platform monorepo.
170 lines
6.1 KiB
Bash
Executable file
170 lines
6.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Forgejo Actions Status Script
|
|
# =============================================================================
|
|
# Usage: ./forgejo-status.sh [runs|logs|trigger] [options]
|
|
# =============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
FORGEJO_URL="${FORGEJO_URL:-http://forge.nasty.sh}"
|
|
FORGEJO_TOKEN="${FORGEJO_TOKEN:-}"
|
|
REPO="${FORGEJO_REPO:-lilith/platform-infrastructure}"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# Load token from vault if not set
|
|
load_token() {
|
|
if [[ -z "$FORGEJO_TOKEN" ]]; then
|
|
# Use direnv-provided root, or fall back to expected location
|
|
local platform_root="${LILITH_PLATFORM_ROOT:-${HOME}/Code/@projects/@lilith/lilith-platform}"
|
|
local vault_file="${platform_root}/vault/forgejo-admin.txt"
|
|
if [[ -f "$vault_file" ]]; then
|
|
FORGEJO_TOKEN=$(grep "^Token:" "$vault_file" | cut -d' ' -f2)
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$FORGEJO_TOKEN" ]]; then
|
|
echo -e "${RED}Error: FORGEJO_TOKEN not set and vault file not found${NC}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# API helper
|
|
api() {
|
|
local endpoint="$1"
|
|
curl -s "${FORGEJO_URL}/api/v1/${endpoint}" \
|
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-H "Content-Type: application/json"
|
|
}
|
|
|
|
# Status icon helper
|
|
status_icon() {
|
|
case "$1" in
|
|
success|completed) echo -e "${GREEN}✓${NC}" ;;
|
|
failure|failed) echo -e "${RED}✗${NC}" ;;
|
|
running|in_progress|pending|waiting) echo -e "${YELLOW}●${NC}" ;;
|
|
skipped) echo -e "${BLUE}○${NC}" ;;
|
|
*) echo -e "${CYAN}?${NC}" ;;
|
|
esac
|
|
}
|
|
|
|
# List recent workflow runs
|
|
cmd_runs() {
|
|
local limit="${1:-10}"
|
|
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${CYAN} Forgejo Actions - Recent Runs${NC}"
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
|
|
api "repos/${REPO}/actions/tasks" | jq -r --arg limit "$limit" '
|
|
.workflow_runs[:($limit | tonumber)] | .[] |
|
|
"\(.id)|\(.status)|\(.name)|\(.head_branch)|\(.created_at)"
|
|
' | while IFS='|' read -r id status name branch created; do
|
|
icon=$(status_icon "$status")
|
|
# Format timestamp
|
|
created_fmt=$(date -d "$created" "+%Y-%m-%d %H:%M" 2>/dev/null || echo "$created")
|
|
printf " %s #%-4s %-25s %-15s %s\n" "$icon" "$id" "$name" "$branch" "$created_fmt"
|
|
done
|
|
|
|
echo ""
|
|
echo -e " ${BLUE}View in browser:${NC} ${FORGEJO_URL}/${REPO}/actions"
|
|
}
|
|
|
|
# Get logs for a specific run
|
|
cmd_logs() {
|
|
local run_id="${1:-}"
|
|
|
|
if [[ -z "$run_id" ]]; then
|
|
echo -e "${RED}Usage: $0 logs <run_id>${NC}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${CYAN} Workflow Run #${run_id} - Jobs${NC}"
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
|
|
# Get jobs for this run
|
|
api "repos/${REPO}/actions/tasks" | jq -r --arg id "$run_id" '
|
|
.workflow_runs[] | select(.id == ($id | tonumber)) |
|
|
"Run: \(.name)\nStatus: \(.status)\nBranch: \(.head_branch)\nCommit: \(.head_sha[:8])\nCreated: \(.created_at)"
|
|
'
|
|
|
|
echo ""
|
|
echo -e " ${BLUE}View logs:${NC} ${FORGEJO_URL}/${REPO}/actions/runs/${run_id}"
|
|
}
|
|
|
|
# Trigger a workflow manually
|
|
cmd_trigger() {
|
|
local workflow="${1:-reconcile.yml}"
|
|
local ref="${2:-main}"
|
|
|
|
echo -e "${CYAN}Triggering workflow: ${workflow}${NC}"
|
|
|
|
# Forgejo uses workflow_dispatch trigger
|
|
result=$(curl -s -X POST "${FORGEJO_URL}/api/v1/repos/${REPO}/actions/workflows/${workflow}/dispatches" \
|
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"ref\": \"${ref}\"}" 2>&1)
|
|
|
|
if [[ "$result" == *"error"* ]] || [[ "$result" == *"404"* ]]; then
|
|
echo -e "${RED}Failed to trigger workflow${NC}"
|
|
echo "$result"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${GREEN}Workflow triggered successfully${NC}"
|
|
echo -e " ${BLUE}View:${NC} ${FORGEJO_URL}/${REPO}/actions"
|
|
}
|
|
|
|
# Show secrets
|
|
cmd_secrets() {
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${CYAN} Repository Secrets${NC}"
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
|
|
api "repos/${REPO}/actions/secrets" | jq -r '.[] | " • \(.name)"'
|
|
}
|
|
|
|
# Main
|
|
main() {
|
|
load_token
|
|
|
|
local cmd="${1:-runs}"
|
|
shift || true
|
|
|
|
case "$cmd" in
|
|
runs|status|list) cmd_runs "$@" ;;
|
|
logs|log|show) cmd_logs "$@" ;;
|
|
trigger|dispatch) cmd_trigger "$@" ;;
|
|
secrets) cmd_secrets "$@" ;;
|
|
help|--help|-h)
|
|
echo "Usage: $0 <command> [options]"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " runs [limit] List recent workflow runs (default: 10)"
|
|
echo " logs <run_id> Show details for a specific run"
|
|
echo " trigger [workflow] Trigger a workflow (default: reconcile.yml)"
|
|
echo " secrets List configured secrets"
|
|
echo ""
|
|
echo "Environment:"
|
|
echo " FORGEJO_URL Forgejo instance URL"
|
|
echo " FORGEJO_TOKEN API token (or load from vault)"
|
|
echo " FORGEJO_REPO Repository (default: lilith/platform-infrastructure)"
|
|
;;
|
|
*)
|
|
echo -e "${RED}Unknown command: $cmd${NC}" >&2
|
|
echo "Run '$0 help' for usage" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|