From fd874649e861daea7bd109dcb239d5866dfa31db Mon Sep 17 00:00:00 2001 From: Jarvis Date: Mon, 25 May 2026 11:27:58 -0500 Subject: [PATCH] fix: handle legacy woodpecker mosaic credentials --- .../framework/tools/_lib/credentials.sh | 40 +++++++++++++++---- .../tools/woodpecker/pipeline-list.sh | 2 +- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/mosaic/framework/tools/_lib/credentials.sh b/packages/mosaic/framework/tools/_lib/credentials.sh index 77d3a6a..bbb942c 100755 --- a/packages/mosaic/framework/tools/_lib/credentials.sh +++ b/packages/mosaic/framework/tools/_lib/credentials.sh @@ -52,6 +52,20 @@ _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" @@ -155,7 +169,14 @@ EOF ;; woodpecker-*) local wp_instance="${service#woodpecker-}" - # credentials.json is authoritative — always read from it, ignore env + # 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 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" @@ -166,7 +187,10 @@ EOF _mosaic_sync_woodpecker_env "$wp_instance" "$WOODPECKER_URL" "$WOODPECKER_TOKEN" ;; woodpecker) - # Resolve default instance, then load it + # 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". local wp_default wp_default="${WOODPECKER_INSTANCE:-$(_mosaic_read_cred '.woodpecker.default')}" if [[ -z "$wp_default" ]]; then @@ -174,18 +198,18 @@ EOF local legacy_url legacy_url="$(_mosaic_read_cred '.woodpecker.url')" if [[ -n "$legacy_url" ]]; then - 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; } + _mosaic_load_woodpecker_legacy 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 - load_credentials "woodpecker-${wp_default}" + 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-*) diff --git a/packages/mosaic/framework/tools/woodpecker/pipeline-list.sh b/packages/mosaic/framework/tools/woodpecker/pipeline-list.sh index 8eae7b7..d77ca37 100755 --- a/packages/mosaic/framework/tools/woodpecker/pipeline-list.sh +++ b/packages/mosaic/framework/tools/woodpecker/pipeline-list.sh @@ -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?per_page=${LIMIT}") + "${WOODPECKER_URL}/api/repos/${REPO_ID}/pipelines?perPage=${LIMIT}") http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$d')