181 lines
5.9 KiB
Bash
181 lines
5.9 KiB
Bash
#!/usr/bin/env bash
|
|
# gitea skill — setup inicial.
|
|
#
|
|
# Idempotente. Cada corrida:
|
|
# 1. Busca el PAT en la skill bitwarden (item "claudecode0 · Gitea PAT
|
|
# claude-agent-gitops").
|
|
# 2. Si hay duplicados, toma el primero y avisa al usuario que limpie.
|
|
# 3. Escribe ~/.claude/skills/gitea/.env con BASE_URL + PAT + DEFAULT_OWNER.
|
|
# 4. Valida con GET /api/v1/version → debe responder.
|
|
#
|
|
# Re-corré esto cuando rotás el PAT en Gitea y lo guardás de nuevo en bitwarden.
|
|
|
|
set -euo pipefail
|
|
|
|
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
ENV_FILE="$SKILL_DIR/.env"
|
|
ENV_EXAMPLE="$SKILL_DIR/.env.example"
|
|
|
|
BW_QUERY="$HOME/.claude/skills/bitwarden/scripts/query.sh"
|
|
# Matchamos por substring porque los items reales en bitwarden tienen el `·`
|
|
# doble-encodeado (corrupción histórica del web vault). El substring esquiva
|
|
# el carácter roto.
|
|
PAT_NAME_SUBSTR="Gitea PAT claude-agent-gitops"
|
|
PAT_ITEM_DESCRIPTION="claudecode0 · Gitea PAT claude-agent-gitops"
|
|
GITEA_BASE_URL="${GITEA_BASE_URL:-https://gitea.nucleoriofrio.com}"
|
|
DEFAULT_OWNER="${GITEA_DEFAULT_OWNER:-NucleOS}"
|
|
|
|
if [[ ! -x "$BW_QUERY" ]]; then
|
|
cat >&2 <<EOF
|
|
ERROR: la skill bitwarden no está configurada en $BW_QUERY.
|
|
|
|
Setup necesario primero:
|
|
bash ~/.claude/skills/bitwarden/scripts/setup.sh
|
|
|
|
Después re-corré esto.
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
echo "→ Buscando PAT en el vault de bitwarden (claudecode0)..."
|
|
|
|
# Search por substring corto (el `·` en el nombre URL-encoded confunde a
|
|
# bw serve). Filtramos por nombre exacto en el python downstream.
|
|
list_resp="$("$BW_QUERY" "/list/object/items?search=Gitea+PAT+claude-agent-gitops")" || {
|
|
echo "ERROR: query a bitwarden falló. ¿bw serve arriba? ¿session expirada?" >&2
|
|
echo " Probá: bash ~/.claude/skills/bitwarden/scripts/setup.sh" >&2
|
|
exit 2
|
|
}
|
|
|
|
# Filtrar matches por substring del nombre. Python lee JSON por stdin y
|
|
# el substring por env var (export antes del pipe — sino el VAR=val inline
|
|
# solo aplica al `printf`, no al `python`).
|
|
export PAT_NAME_SUBSTR
|
|
mapfile -t pat_ids < <(
|
|
printf '%s' "$list_resp" | python -c '
|
|
import json, os, sys
|
|
target = os.environ["PAT_NAME_SUBSTR"]
|
|
data = json.load(sys.stdin)
|
|
items = (data.get("data") or {}).get("data") or data.get("data") or []
|
|
if isinstance(items, dict):
|
|
items = items.get("data", [])
|
|
for it in items:
|
|
name = it.get("name", "") or ""
|
|
if target in name:
|
|
print(it.get("id", ""))
|
|
' | tr -d '\r'
|
|
)
|
|
|
|
case "${#pat_ids[@]}" in
|
|
0)
|
|
cat >&2 <<EOF
|
|
ERROR: no encontré ningún item con substring "$PAT_NAME_SUBSTR" en el nombre.
|
|
|
|
Pasos:
|
|
1. Generá un PAT en https://gitea.nucleoriofrio.com/user/settings/applications
|
|
con scopes: read:repo, write:repo, read:issue, write:issue, read:user.
|
|
2. Guardalo en bitwarden con un nombre que contenga "$PAT_NAME_SUBSTR".
|
|
(Idealmente: "$PAT_ITEM_DESCRIPTION".)
|
|
3. Re-corré este setup.
|
|
|
|
EOF
|
|
exit 3
|
|
;;
|
|
1)
|
|
pat_id="${pat_ids[0]}"
|
|
;;
|
|
*)
|
|
pat_id="${pat_ids[0]}"
|
|
cat >&2 <<EOF
|
|
⚠️ Hay ${#pat_ids[@]} items en bitwarden con substring "$PAT_NAME_SUBSTR".
|
|
Tomé el primero (id: $pat_id). Si no es el activo, este setup va a fallar
|
|
en la validación más abajo.
|
|
|
|
Limpiá los duplicados desde la web (https://vault.nucleoriofrio.com) — la
|
|
skill bitwarden bloquea DELETE así que no podemos borrarlos desde acá.
|
|
|
|
EOF
|
|
;;
|
|
esac
|
|
|
|
echo "→ Extrayendo password del item $pat_id..."
|
|
pat_value="$("$BW_QUERY" "/object/password/${pat_id}" | python -c "
|
|
import json,sys
|
|
d=json.load(sys.stdin)
|
|
v=d.get('data')
|
|
if isinstance(v, dict):
|
|
v=v.get('data')
|
|
print(v or '')
|
|
" | tr -d '\r')"
|
|
|
|
if [[ -z "$pat_value" ]]; then
|
|
echo "ERROR: el item existe pero el password vino vacío. Revisá en web." >&2
|
|
exit 4
|
|
fi
|
|
|
|
echo "→ Escribiendo $ENV_FILE..."
|
|
{
|
|
echo "# gitea skill — generado por setup.sh"
|
|
echo "# NO editar a mano (re-corré setup.sh para refrescar el PAT)."
|
|
echo ""
|
|
echo "GITEA_BASE_URL=$GITEA_BASE_URL"
|
|
echo "GITEA_PAT=$pat_value"
|
|
echo "GITEA_DEFAULT_OWNER=$DEFAULT_OWNER"
|
|
} > "$ENV_FILE"
|
|
chmod 600 "$ENV_FILE" 2>/dev/null || true
|
|
|
|
echo "→ Validando con GET /api/v1/version..."
|
|
version_resp="$(GITEA_PAT="$pat_value" GITEA_BASE_URL="$GITEA_BASE_URL" \
|
|
curl -sS -m 10 \
|
|
-H "Authorization: token $pat_value" \
|
|
-H "Accept: application/json" \
|
|
"${GITEA_BASE_URL}/api/v1/version")" || {
|
|
echo "ERROR: GET /version falló. ¿base URL correcta? ¿conexión?" >&2
|
|
exit 5
|
|
}
|
|
|
|
version="$(echo "$version_resp" | python -c "import json,sys; print(json.load(sys.stdin).get('version','?'))" 2>/dev/null || echo "?")"
|
|
|
|
if [[ "$version" == "?" || -z "$version" ]]; then
|
|
cat >&2 <<EOF
|
|
ERROR: el server respondió pero no pude parsear la versión.
|
|
Respuesta cruda:
|
|
$version_resp
|
|
|
|
Posibles causas:
|
|
- PAT inválido / revocado (limpiá el duplicado en bitwarden)
|
|
- Base URL mal en .env
|
|
|
|
EOF
|
|
exit 6
|
|
fi
|
|
|
|
# Sanity check del user actual con el PAT — capturamos el login para
|
|
# escribirlo a .env (lo usa repo-create.sh para detectar user vs. org).
|
|
user_resp="$(curl -sS -m 10 \
|
|
-H "Authorization: token $pat_value" \
|
|
-H "Accept: application/json" \
|
|
"${GITEA_BASE_URL}/api/v1/user")"
|
|
username="$(echo "$user_resp" | python -c "import json,sys; print(json.load(sys.stdin).get('login','?'))" 2>/dev/null || echo "?")"
|
|
|
|
if [[ "$username" != "?" && -n "$username" ]]; then
|
|
# Append/replace GITEA_BOT_USER en .env
|
|
if grep -q '^GITEA_BOT_USER=' "$ENV_FILE" 2>/dev/null; then
|
|
# Reemplazar línea existente (sed -i no es portable en Git Bash, usar archivo temp)
|
|
grep -v '^GITEA_BOT_USER=' "$ENV_FILE" > "$ENV_FILE.tmp"
|
|
echo "GITEA_BOT_USER=$username" >> "$ENV_FILE.tmp"
|
|
mv "$ENV_FILE.tmp" "$ENV_FILE"
|
|
else
|
|
echo "GITEA_BOT_USER=$username" >> "$ENV_FILE"
|
|
fi
|
|
chmod 600 "$ENV_FILE" 2>/dev/null || true
|
|
fi
|
|
|
|
echo ""
|
|
echo "→ Listo: Gitea $version | user=$username | $GITEA_BASE_URL"
|
|
echo ""
|
|
echo "Próximos pasos:"
|
|
echo " bash $SKILL_DIR/scripts/query.sh /version"
|
|
echo " bash $SKILL_DIR/scripts/pr-list.sh NucleOS/nucleo-infra"
|
|
echo " bash $SKILL_DIR/scripts/actions-list-runs.sh NucleOS/nucleo-infra"
|