From 4df38f7e8108fdcb90c7ae6102dfb0226d3abaee Mon Sep 17 00:00:00 2001 From: "jason.woltje" Date: Fri, 10 Jul 2026 01:57:12 +0000 Subject: [PATCH] fix(tools/_lib): /etc/mosaic host-level fallback for credential resolution (#700) --- packages/mosaic/framework/tools/_lib/credentials.sh | 12 +++++++++++- .../mosaic/framework/tools/git/detect-platform.sh | 11 ++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/mosaic/framework/tools/_lib/credentials.sh b/packages/mosaic/framework/tools/_lib/credentials.sh index dd05972..64d4d63 100755 --- a/packages/mosaic/framework/tools/_lib/credentials.sh +++ b/packages/mosaic/framework/tools/_lib/credentials.sh @@ -15,13 +15,23 @@ # # After loading, service-specific env vars are exported. # Run `load_credentials --help` for details. +# +# Resolution order (first match wins): +# 1. $MOSAIC_CREDENTIALS_FILE (explicit override — never second-guessed) +# 2. $HOME/.config/mosaic/credentials.json +# 3. /etc/mosaic/credentials.json (host-level fallback) +# The /etc fallback exists for HOME-redirected profile environments, where +# $HOME points at a per-profile directory that has no credentials file. +# Operators symlink /etc/mosaic/credentials.json to the host's canonical +# file once, instead of exporting MOSAIC_CREDENTIALS_FILE per invocation. if [[ -z "${MOSAIC_CREDENTIALS_FILE:-}" ]]; then - for _cand in "$HOME/.config/mosaic/credentials.json"; do + for _cand in "$HOME/.config/mosaic/credentials.json" "/etc/mosaic/credentials.json"; do if [[ -f "$_cand" ]]; then MOSAIC_CREDENTIALS_FILE="$_cand"; break; fi done : "${MOSAIC_CREDENTIALS_FILE:=$HOME/.config/mosaic/credentials.json}" fi +export MOSAIC_CREDENTIALS_FILE _mosaic_require_jq() { if ! command -v jq &>/dev/null; then diff --git a/packages/mosaic/framework/tools/git/detect-platform.sh b/packages/mosaic/framework/tools/git/detect-platform.sh index 69156e9..626e1a0 100755 --- a/packages/mosaic/framework/tools/git/detect-platform.sh +++ b/packages/mosaic/framework/tools/git/detect-platform.sh @@ -86,7 +86,16 @@ gitea_url_matches_host() { get_gitea_service_for_host() { local host="$1" - local cred_file="${MOSAIC_CREDENTIALS_FILE:-$HOME/.config/mosaic/credentials.json}" + local cred_file="${MOSAIC_CREDENTIALS_FILE:-}" + if [[ -z "$cred_file" ]]; then + # Same resolution chain as _lib/credentials.sh: profile HOME, then + # host-level /etc only if it exists; neither existing keeps the + # $HOME default (matches the lib's final := fallback). + cred_file="$HOME/.config/mosaic/credentials.json" + if [[ ! -f "$cred_file" && -f /etc/mosaic/credentials.json ]]; then + cred_file="/etc/mosaic/credentials.json" + fi + fi case "$host" in git.mosaicstack.dev)