Add --no-wait flag and CI workflow polling after push via Gitea Actions API
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 6s
Build-Test-Publish / build (linux/arm64) (push) Successful in 12s

This commit is contained in:
j
2026-03-09 07:07:44 +13:00
parent 7b984f5542
commit dadbe23169

154
gp
View File

@@ -34,6 +34,7 @@ OPTIONS:
-b, --branch Specify branch to push to (default: current branch)
-a, --add-all Add all files including untracked (default)
--staged-only Only commit staged changes (don't add untracked files)
--no-wait Don't wait for CI workflow to complete after push
ARGUMENTS:
message Optional custom commit message (overrides auto-generation)
@@ -476,6 +477,139 @@ show_status_and_confirm() {
fi
}
# Function to extract Gitea API URL and token from git remote
# Returns: sets GITEA_API_BASE and GITEA_API_TOKEN, or returns 1
parse_gitea_remote() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null) || return 1
# Match https://TOKEN@HOST/OWNER/REPO.git or https://HOST/OWNER/REPO.git
local token="" host="" owner="" repo=""
if [[ "$remote_url" =~ ^https://([^@]+)@([^/]+)/([^/]+)/([^/]+?)(\.git)?$ ]]; then
token="${BASH_REMATCH[1]}"
host="${BASH_REMATCH[2]}"
owner="${BASH_REMATCH[3]}"
repo="${BASH_REMATCH[4]}"
elif [[ "$remote_url" =~ ^https://([^/]+)/([^/]+)/([^/]+?)(\.git)?$ ]]; then
host="${BASH_REMATCH[1]}"
owner="${BASH_REMATCH[2]}"
repo="${BASH_REMATCH[3]}"
else
return 1
fi
# Only support Gitea instances (not github.com etc)
case "$host" in
github.com|gitlab.com|bitbucket.org) return 1 ;;
esac
# Use GITEA_TOKEN env var if no token in URL
[ -z "$token" ] && token="${GITEA_TOKEN:-}"
[ -z "$token" ] && return 1
GITEA_API_BASE="https://${host}/api/v1/repos/${owner}/${repo}"
GITEA_API_TOKEN="$token"
GITEA_HTML_BASE="https://${host}/${owner}/${repo}"
return 0
}
# Function to wait for CI workflow to complete after push
# Polls Gitea Actions API, shows spinner, ESC cancels
wait_for_workflow() {
local head_sha="$1"
local branch="$2"
if ! parse_gitea_remote; then
return 0 # silently skip if not a Gitea remote or no token
fi
local spinner_chars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local spin_idx=0
local poll_interval=3
local max_wait=600 # 10 minutes max
local elapsed=0
echo
print_info "Waiting for CI workflow... (press ESC to stop waiting)"
# Save terminal settings and enable non-blocking input
local old_tty
old_tty=$(stty -g 2>/dev/null) || true
stty -echo -icanon min 0 time 0 2>/dev/null || true
# Restore terminal on exit
trap 'stty "$old_tty" 2>/dev/null; trap - RETURN' RETURN
local run_url="" status="" conclusion="" found=false
while [ "$elapsed" -lt "$max_wait" ]; do
# Check for ESC key
local key=""
key=$(dd bs=1 count=1 2>/dev/null) || true
if [ "$key" = $'\x1b' ]; then
# Drain any remaining escape sequence bytes
dd bs=1 count=5 2>/dev/null >/dev/null || true
echo -e "\r\033[K"
print_info "Stopped waiting (CI still running in background)"
[ -n "$run_url" ] && print_info "View: $run_url"
return 0
fi
# Poll API
local response
response=$(curl -sf "${GITEA_API_BASE}/actions/runs?limit=5&token=${GITEA_API_TOKEN}" 2>/dev/null) || true
if [ -n "$response" ]; then
# Find the run matching our commit SHA
local run_info
run_info=$(echo "$response" | python3 -c "
import json, sys
d = json.load(sys.stdin)
for r in d.get('workflow_runs', []):
if r.get('head_sha','').startswith('${head_sha}'):
print(r['status'], r.get('conclusion',''), r.get('html_url',''))
break
" 2>/dev/null) || true
if [ -n "$run_info" ]; then
found=true
status=$(echo "$run_info" | awk '{print $1}')
conclusion=$(echo "$run_info" | awk '{print $2}')
run_url=$(echo "$run_info" | awk '{print $3}')
if [ "$status" = "completed" ]; then
echo -e "\r\033[K"
if [ "$conclusion" = "success" ]; then
print_success "CI workflow passed"
else
print_error "CI workflow failed (conclusion: $conclusion)"
[ -n "$run_url" ] && print_info "View: $run_url"
return 1
fi
return 0
fi
fi
fi
# Show spinner
local spin_char="${spinner_chars:$spin_idx:1}"
spin_idx=$(( (spin_idx + 1) % ${#spinner_chars} ))
local status_msg="waiting"
$found && status_msg="$status"
local mins=$((elapsed / 60))
local secs=$((elapsed % 60))
printf "\r %s CI %s (%d:%02d)" "$spin_char" "$status_msg" "$mins" "$secs"
sleep "$poll_interval"
elapsed=$((elapsed + poll_interval))
done
echo -e "\r\033[K"
print_warning "Timed out waiting for CI (${max_wait}s)"
[ -n "$run_url" ] && print_info "View: $run_url"
return 0
}
# Function to perform the actual commit and push
do_commit_and_push() {
local commit_msg="$1"
@@ -493,6 +627,8 @@ do_commit_and_push() {
# Push
print_info "Pushing to $target_branch..."
local push_sha
push_sha=$(git rev-parse HEAD)
# Check if branch exists on remote to determine if we need -u flag
if git ls-remote --exit-code --heads origin "$target_branch" >/dev/null 2>&1; then
# Branch exists on remote, normal push
@@ -513,13 +649,18 @@ do_commit_and_push() {
exit 1
fi
fi
# Wait for CI workflow if enabled
if [ "$WAIT_FOR_CI" = true ]; then
wait_for_workflow "$push_sha" "$target_branch" || true
fi
}
# Autocomplete function for bash
autocomplete() {
local args=("$@")
if [ ${#args[@]} -eq 0 ]; then
printf "%s\n" "--help" "--dry-run" "--force" "--yes" "--add-all" "--staged-only" "--branch" "-h" "-n" "-f" "-y" "-a" "-b"
printf "%s\n" "--help" "--dry-run" "--force" "--yes" "--add-all" "--staged-only" "--no-wait" "--branch" "-h" "-n" "-f" "-y" "-a" "-b"
fi
}
@@ -531,6 +672,7 @@ ADD_ALL=true # Default to adding all files
CUSTOM_MESSAGE=""
TARGET_BRANCH=""
PUSH_ONLY=false
WAIT_FOR_CI=true
# Handle special commands first
case "${1:-}" in
@@ -572,6 +714,10 @@ while [[ $# -gt 0 ]]; do
ADD_ALL=false
shift
;;
--no-wait)
WAIT_FOR_CI=false
shift
;;
-b|--branch)
if [ -z "${2:-}" ]; then
print_error "Option -b/--branch requires a branch name"
@@ -628,6 +774,8 @@ main() {
fi
# Execute push only
local push_sha
push_sha=$(git rev-parse HEAD)
print_info "Pushing existing commits to $TARGET_BRANCH..."
# Check if branch exists on remote to determine if we need -u flag
if git ls-remote --exit-code --heads origin "$TARGET_BRANCH" >/dev/null 2>&1; then
@@ -649,6 +797,10 @@ main() {
exit 1
fi
fi
# Wait for CI workflow if enabled
if [ "$WAIT_FOR_CI" = true ]; then
wait_for_workflow "$push_sha" "$TARGET_BRANCH" || true
fi
exit 0
fi