Compare commits

..

1 Commits

Author SHA1 Message Date
Jarvis
46cc91ccbe fix(mosaic-tools): pass explicit Gitea repo args
Some checks failed
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/push/ci Pipeline failed
2026-05-26 14:31:19 -05:00
13 changed files with 115 additions and 72 deletions

View File

@@ -52,20 +52,6 @@ _mosaic_sync_woodpecker_env() {
printf '%s\n' "$expected" > "$env_file"
}
# Load legacy flat Woodpecker credentials (.woodpecker.url / .woodpecker.token).
# Some environments export WOODPECKER_INSTANCE=mosaic, but the current
# credentials.json may still use the legacy flat schema. Treat "mosaic" as the
# default flat instance when a nested .woodpecker.mosaic object is absent.
_mosaic_load_woodpecker_legacy() {
export WOODPECKER_URL="$(_mosaic_read_cred '.woodpecker.url')"
export WOODPECKER_TOKEN="$(_mosaic_read_cred '.woodpecker.token')"
export WOODPECKER_INSTANCE="${WOODPECKER_INSTANCE:-mosaic}"
WOODPECKER_URL="${WOODPECKER_URL%/}"
[[ -n "$WOODPECKER_URL" ]] || { echo "Error: woodpecker.url not found" >&2; return 1; }
[[ -n "$WOODPECKER_TOKEN" ]] || { echo "Error: woodpecker.token not found" >&2; return 1; }
_mosaic_sync_woodpecker_env "$WOODPECKER_INSTANCE" "$WOODPECKER_URL" "$WOODPECKER_TOKEN"
}
load_credentials() {
local service="$1"
@@ -169,14 +155,7 @@ EOF
;;
woodpecker-*)
local wp_instance="${service#woodpecker-}"
# credentials.json is authoritative — always read from it, ignore env.
# Backward compatibility: the default Mosaic Woodpecker instance may be
# stored in the legacy flat schema (.woodpecker.url/.token) instead of
# .woodpecker.mosaic.url/.token.
if [[ "$wp_instance" == "mosaic" ]] && [[ -z "$(_mosaic_read_cred '.woodpecker.mosaic.url')" ]] && [[ -n "$(_mosaic_read_cred '.woodpecker.url')" ]]; then
WOODPECKER_INSTANCE="mosaic" _mosaic_load_woodpecker_legacy
return $?
fi
# credentials.json is authoritative — always read from it, ignore env
export WOODPECKER_URL="$(_mosaic_read_cred ".woodpecker.${wp_instance}.url")"
export WOODPECKER_TOKEN="$(_mosaic_read_cred ".woodpecker.${wp_instance}.token")"
export WOODPECKER_INSTANCE="$wp_instance"
@@ -187,10 +166,7 @@ EOF
_mosaic_sync_woodpecker_env "$wp_instance" "$WOODPECKER_URL" "$WOODPECKER_TOKEN"
;;
woodpecker)
# Resolve default instance, then load it. If WOODPECKER_INSTANCE is set to
# "mosaic" by a shell/profile but credentials.json still uses the legacy
# flat .woodpecker.url/.token schema, load the flat credentials instead of
# failing with "woodpecker.mosaic.url not found".
# Resolve default instance, then load it
local wp_default
wp_default="${WOODPECKER_INSTANCE:-$(_mosaic_read_cred '.woodpecker.default')}"
if [[ -z "$wp_default" ]]; then
@@ -198,19 +174,19 @@ EOF
local legacy_url
legacy_url="$(_mosaic_read_cred '.woodpecker.url')"
if [[ -n "$legacy_url" ]]; then
_mosaic_load_woodpecker_legacy
export WOODPECKER_URL="${WOODPECKER_URL:-$legacy_url}"
export WOODPECKER_TOKEN="${WOODPECKER_TOKEN:-$(_mosaic_read_cred '.woodpecker.token')}"
WOODPECKER_URL="${WOODPECKER_URL%/}"
[[ -n "$WOODPECKER_URL" ]] || { echo "Error: woodpecker.url not found" >&2; return 1; }
[[ -n "$WOODPECKER_TOKEN" ]] || { echo "Error: woodpecker.token not found" >&2; return 1; }
else
echo "Error: woodpecker.default not set and no WOODPECKER_INSTANCE env var" >&2
echo "Available instances: $(jq -r '.woodpecker | keys | join(", ")' "$MOSAIC_CREDENTIALS_FILE" 2>/dev/null)" >&2
return 1
fi
else
if [[ "$wp_default" == "mosaic" ]] && [[ -z "$(_mosaic_read_cred '.woodpecker.mosaic.url')" ]] && [[ -n "$(_mosaic_read_cred '.woodpecker.url')" ]]; then
WOODPECKER_INSTANCE="mosaic" _mosaic_load_woodpecker_legacy
else
load_credentials "woodpecker-${wp_default}"
fi
fi
;;
cloudflare-*)
local cf_instance="${service#cloudflare-}"

View File

@@ -74,6 +74,16 @@ get_repo_name() {
echo "${repo_info##*/}"
}
get_repo_slug() {
get_repo_info
}
get_gitea_repo_args() {
local repo
repo=$(get_repo_slug) || return 1
printf -- '--repo %q --login %q' "$repo" "${GITEA_LOGIN:-mosaicstack}"
}
get_remote_host() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null || true)

View File

@@ -53,7 +53,7 @@ if [[ "$PLATFORM" == "github" ]]; then
gh issue comment "$ISSUE_NUMBER" --body "$COMMENT"
echo "Added comment to GitHub issue #$ISSUE_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then
tea issue comment "$ISSUE_NUMBER" "$COMMENT"
tea issue comment "$ISSUE_NUMBER" "$COMMENT" $(get_gitea_repo_args)
echo "Added comment to Gitea issue #$ISSUE_NUMBER"
else
echo "Error: Unknown platform"

View File

@@ -112,20 +112,22 @@ PLATFORM=$(detect_platform)
case "$PLATFORM" in
github)
CMD="gh issue create --title \"$TITLE\""
[[ -n "$BODY" ]] && CMD="$CMD --body \"$BODY\""
[[ -n "$LABELS" ]] && CMD="$CMD --label \"$LABELS\""
[[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\""
eval "$CMD"
CMD=(gh issue create --title "$TITLE")
[[ -n "$BODY" ]] && CMD+=(--body "$BODY")
[[ -n "$LABELS" ]] && CMD+=(--label "$LABELS")
[[ -n "$MILESTONE" ]] && CMD+=(--milestone "$MILESTONE")
"${CMD[@]}"
;;
gitea)
if command -v tea >/dev/null 2>&1; then
CMD="tea issue create --title \"$TITLE\""
[[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\""
[[ -n "$LABELS" ]] && CMD="$CMD --labels \"$LABELS\""
REPO_SLUG=$(get_repo_slug)
REPO_ARGS=(--repo "$REPO_SLUG" --login "${GITEA_LOGIN:-mosaicstack}")
CMD=(tea issue create "${REPO_ARGS[@]}" --title "$TITLE")
[[ -n "$BODY" ]] && CMD+=(--description "$BODY")
[[ -n "$LABELS" ]] && CMD+=(--labels "$LABELS")
# tea accepts milestone by name directly (verified 2026-02-05)
[[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\""
if eval "$CMD"; then
[[ -n "$MILESTONE" ]] && CMD+=(--milestone "$MILESTONE")
if "${CMD[@]}"; then
exit 0
fi
echo "Warning: tea issue create failed, trying Gitea API fallback..." >&2

View File

@@ -80,7 +80,8 @@ case "$PLATFORM" in
eval "$CMD"
;;
gitea)
CMD="tea issues list --state $STATE --limit $LIMIT"
REPO_ARGS=$(get_gitea_repo_args)
CMD="tea issues list $REPO_ARGS --state $STATE --limit $LIMIT"
[[ -n "$LABEL" ]] && CMD="$CMD --labels \"$LABEL\""
[[ -n "$MILESTONE" ]] && CMD="$CMD --milestones \"$MILESTONE\""
# Note: tea may not support assignee filter directly

View File

@@ -52,9 +52,9 @@ if [[ "$PLATFORM" == "github" ]]; then
echo "Reopened GitHub issue #$ISSUE_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then
if [[ -n "$COMMENT" ]]; then
tea issue comment "$ISSUE_NUMBER" "$COMMENT"
tea issue comment "$ISSUE_NUMBER" "$COMMENT" $(get_gitea_repo_args)
fi
tea issue reopen "$ISSUE_NUMBER"
tea issue reopen "$ISSUE_NUMBER" $(get_gitea_repo_args)
echo "Reopened Gitea issue #$ISSUE_NUMBER"
else
echo "Error: Unknown platform"

View File

@@ -67,7 +67,7 @@ if [[ "$PLATFORM" == "github" ]]; then
gh issue view "$ISSUE_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then
if command -v tea >/dev/null 2>&1; then
if tea issue "$ISSUE_NUMBER"; then
if tea issue "$ISSUE_NUMBER" $(get_gitea_repo_args); then
exit 0
fi
echo "Warning: tea issue view failed, trying Gitea API fallback..." >&2

View File

@@ -52,9 +52,9 @@ if [[ "$PLATFORM" == "github" ]]; then
echo "Closed GitHub PR #$PR_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then
if [[ -n "$COMMENT" ]]; then
tea pr comment "$PR_NUMBER" "$COMMENT"
tea pr comment "$PR_NUMBER" "$COMMENT" $(get_gitea_repo_args)
fi
tea pr close "$PR_NUMBER"
tea pr close "$PR_NUMBER" $(get_gitea_repo_args)
echo "Closed Gitea PR #$PR_NUMBER"
else
echo "Error: Unknown platform"

View File

@@ -17,6 +17,51 @@ MILESTONE=""
DRAFT=false
ISSUE=""
# get_remote_host, get_gitea_token, get_repo_info, and get_gitea_repo_args are provided by detect-platform.sh
gitea_pr_create_api() {
local host repo token url payload
host=$(get_remote_host) || {
echo "Error: could not determine remote host for API fallback" >&2
return 1
}
repo=$(get_repo_info) || {
echo "Error: could not determine repo owner/name for API fallback" >&2
return 1
}
token=$(get_gitea_token "$host") || {
echo "Error: Gitea token not found for API fallback (set GITEA_TOKEN or configure ~/.git-credentials)" >&2
return 1
}
if [[ -n "$LABELS" || -n "$MILESTONE" || "$DRAFT" == true ]]; then
echo "Warning: API fallback applies title/body/head/base only; labels/milestone/draft require authenticated tea setup." >&2
fi
payload=$(TITLE="$TITLE" BODY="$BODY" HEAD_BRANCH="$HEAD_BRANCH" BASE_BRANCH="$BASE_BRANCH" python3 - <<'PY'
import json
import os
payload = {
"title": os.environ["TITLE"],
"head": os.environ["HEAD_BRANCH"],
"base": os.environ["BASE_BRANCH"] or "main",
}
body = os.environ.get("BODY", "")
if body:
payload["body"] = body
print(json.dumps(payload))
PY
)
url="https://${host}/api/v1/repos/${repo}/pulls"
curl -fsS -X POST \
-H "Authorization: token ${token}" \
-H "Content-Type: application/json" \
-d "$payload" \
"$url"
}
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
@@ -118,33 +163,37 @@ PLATFORM=$(detect_platform)
case "$PLATFORM" in
github)
CMD="gh pr create --title \"$TITLE\""
[[ -n "$BODY" ]] && CMD="$CMD --body \"$BODY\""
[[ -n "$BASE_BRANCH" ]] && CMD="$CMD --base \"$BASE_BRANCH\""
[[ -n "$HEAD_BRANCH" ]] && CMD="$CMD --head \"$HEAD_BRANCH\""
[[ -n "$LABELS" ]] && CMD="$CMD --label \"$LABELS\""
[[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\""
[[ "$DRAFT" == true ]] && CMD="$CMD --draft"
eval "$CMD"
CMD=(gh pr create --title "$TITLE")
[[ -n "$BODY" ]] && CMD+=(--body "$BODY")
[[ -n "$BASE_BRANCH" ]] && CMD+=(--base "$BASE_BRANCH")
[[ -n "$HEAD_BRANCH" ]] && CMD+=(--head "$HEAD_BRANCH")
[[ -n "$LABELS" ]] && CMD+=(--label "$LABELS")
[[ -n "$MILESTONE" ]] && CMD+=(--milestone "$MILESTONE")
[[ "$DRAFT" == true ]] && CMD+=(--draft)
"${CMD[@]}"
;;
gitea)
# tea pull create syntax
CMD="tea pr create --title \"$TITLE\""
[[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\""
[[ -n "$BASE_BRANCH" ]] && CMD="$CMD --base \"$BASE_BRANCH\""
[[ -n "$HEAD_BRANCH" ]] && CMD="$CMD --head \"$HEAD_BRANCH\""
# tea pull create syntax. Always pass --repo because tea repo inference
# is unreliable in Mosaic worktrees/profile shells. Use arrays instead
# of eval so markdown backticks/body content are not shell-executed.
REPO_SLUG=$(get_repo_slug)
REPO_ARGS=(--repo "$REPO_SLUG" --login "${GITEA_LOGIN:-mosaicstack}")
CMD=(tea pr create "${REPO_ARGS[@]}" --title "$TITLE")
[[ -n "$BODY" ]] && CMD+=(--description "$BODY")
[[ -n "$BASE_BRANCH" ]] && CMD+=(--base "$BASE_BRANCH")
[[ -n "$HEAD_BRANCH" ]] && CMD+=(--head "$HEAD_BRANCH")
# Handle labels for tea
if [[ -n "$LABELS" ]]; then
# tea may use --labels flag
CMD="$CMD --labels \"$LABELS\""
CMD+=(--labels "$LABELS")
fi
# Handle milestone for tea
if [[ -n "$MILESTONE" ]]; then
MILESTONE_ID=$(tea milestones list 2>/dev/null | grep -E "^\s*[0-9]+" | grep "$MILESTONE" | awk '{print $1}' | head -1)
MILESTONE_ID=$(tea milestones list "${REPO_ARGS[@]}" 2>/dev/null | grep -E "^\s*[0-9]+" | grep "$MILESTONE" | awk '{print $1}' | head -1)
if [[ -n "$MILESTONE_ID" ]]; then
CMD="$CMD --milestone $MILESTONE_ID"
CMD+=(--milestone "$MILESTONE_ID")
else
echo "Warning: Could not find milestone '$MILESTONE', creating without milestone" >&2
fi
@@ -155,7 +204,11 @@ case "$PLATFORM" in
echo "Note: Draft PR may not be supported by your tea version" >&2
fi
eval "$CMD"
if "${CMD[@]}"; then
exit 0
fi
echo "Warning: tea pr create failed, trying Gitea API fallback..." >&2
gitea_pr_create_api
;;
*)
echo "Error: Could not detect git platform" >&2

View File

@@ -74,7 +74,8 @@ case "$PLATFORM" in
;;
gitea)
# tea pr list - note: tea uses 'pulls' subcommand in some versions
CMD="tea pr list --state $STATE --limit $LIMIT"
REPO_ARGS=$(get_gitea_repo_args)
CMD="tea pr list $REPO_ARGS --state $STATE --limit $LIMIT"
# tea filtering may be limited
if [[ -n "$LABEL" ]]; then

View File

@@ -85,7 +85,7 @@ if [[ "$PLATFORM" == "github" ]]; then
elif [[ "$PLATFORM" == "gitea" ]]; then
case $ACTION in
approve)
tea pr approve "$PR_NUMBER" ${COMMENT:+--comment "$COMMENT"}
tea pr approve "$PR_NUMBER" $(get_gitea_repo_args) ${COMMENT:+--comment "$COMMENT"}
echo "Approved Gitea PR #$PR_NUMBER"
;;
request-changes)
@@ -93,7 +93,7 @@ elif [[ "$PLATFORM" == "gitea" ]]; then
echo "Error: Comment required for request-changes"
exit 1
fi
tea pr reject "$PR_NUMBER" --comment "$COMMENT"
tea pr reject "$PR_NUMBER" $(get_gitea_repo_args) --comment "$COMMENT"
echo "Requested changes on Gitea PR #$PR_NUMBER"
;;
comment)
@@ -101,7 +101,7 @@ elif [[ "$PLATFORM" == "gitea" ]]; then
echo "Error: Comment required"
exit 1
fi
tea pr comment "$PR_NUMBER" "$COMMENT"
tea pr comment "$PR_NUMBER" "$COMMENT" $(get_gitea_repo_args)
echo "Added comment to Gitea PR #$PR_NUMBER"
;;
*)

View File

@@ -41,7 +41,7 @@ detect_platform
if [[ "$PLATFORM" == "github" ]]; then
gh pr view "$PR_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then
tea pr "$PR_NUMBER"
tea pr "$PR_NUMBER" $(get_gitea_repo_args)
else
echo "Error: Unknown platform"
exit 1

View File

@@ -50,7 +50,7 @@ REPO_ID=$(wp_resolve_repo_id "$REPO") || exit 1
response=$(curl -sk -w "\n%{http_code}" \
-H "Authorization: Bearer $WOODPECKER_TOKEN" \
"${WOODPECKER_URL}/api/repos/${REPO_ID}/pipelines?perPage=${LIMIT}")
"${WOODPECKER_URL}/api/repos/${REPO_ID}/pipelines?per_page=${LIMIT}")
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')