Add --no-wait flag and CI workflow polling after push via Gitea Actions API
This commit is contained in:
154
gp
154
gp
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user