fix: Wire Woodpecker CI to local Forgejo (#612)

Add ci_commit_status() and ci_pipeline_number() helpers to
lib/ci-helpers.sh that query Woodpecker directly with a forge API
fallback. Replace all 12 inline forge commit status calls across 6
files with the new helpers.

Add setup_woodpecker() to bin/disinto init that creates a Forgejo
OAuth2 app for Woodpecker and activates the repo.

Document manual Woodpecker+Forgejo setup in BOOTSTRAP.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-23 17:19:01 +00:00
parent 7de1dca12c
commit 50dff34b89
9 changed files with 250 additions and 25 deletions

View file

@ -4,6 +4,7 @@ set -euo pipefail
#
# Source from any script: source "$(dirname "$0")/../lib/ci-helpers.sh"
# ci_passed() requires: WOODPECKER_REPO_ID (from env.sh / project config)
# ci_commit_status() / ci_pipeline_number() require: woodpecker_api(), forge_api() (from env.sh)
# classify_pipeline_failure() requires: woodpecker_api() (defined in env.sh)
# ensure_blocked_label_id — look up (or create) the "blocked" label, print its ID.
@ -102,6 +103,55 @@ ci_failed() {
return 0
}
# ci_commit_status <sha> — get CI state for a commit
# Queries Woodpecker API directly, falls back to forge commit status API.
ci_commit_status() {
local sha="$1"
local state=""
# Primary: ask Woodpecker directly
if [ -n "${WOODPECKER_REPO_ID:-}" ] && [ "${WOODPECKER_REPO_ID}" != "0" ]; then
state=$(woodpecker_api "/repos/${WOODPECKER_REPO_ID}/pipelines" \
| jq -r --arg sha "$sha" \
'[.[] | select(.commit == $sha)] | sort_by(.number) | last | .status // empty' \
2>/dev/null) || true
# Map Woodpecker status to Gitea/Forgejo status names
case "$state" in
success) echo "success"; return ;;
failure|error|killed) echo "failure"; return ;;
running|pending|blocked) echo "pending"; return ;;
esac
fi
# Fallback: forge commit status API (works with any Gitea/Forgejo)
forge_api GET "/commits/${sha}/status" 2>/dev/null \
| jq -r '.state // "unknown"'
}
# ci_pipeline_number <sha> — get Woodpecker pipeline number for a commit
# Queries Woodpecker API directly, falls back to forge status target_url parsing.
ci_pipeline_number() {
local sha="$1"
# Primary: ask Woodpecker directly
if [ -n "${WOODPECKER_REPO_ID:-}" ] && [ "${WOODPECKER_REPO_ID}" != "0" ]; then
local num
num=$(woodpecker_api "/repos/${WOODPECKER_REPO_ID}/pipelines" \
| jq -r --arg sha "$sha" \
'[.[] | select(.commit == $sha)] | sort_by(.number) | last | .number // empty' \
2>/dev/null) || true
if [ -n "$num" ]; then
echo "$num"
return
fi
fi
# Fallback: extract from forge status target_url
forge_api GET "/commits/${sha}/status" 2>/dev/null \
| jq -r '.statuses[0].target_url // ""' \
| grep -oP 'pipeline/\K[0-9]+' | head -1 || true
}
# is_infra_step <step_name> <exit_code> [log_data]
# Checks whether a single CI step failure matches infra heuristics.
# Returns 0 (infra) with reason on stdout, or 1 (not infra).