diff --git a/tools/push.sh b/tools/push.sh new file mode 100755 index 0000000..9d977e5 --- /dev/null +++ b/tools/push.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Wrapper `git push` qui charge le token PAT depuis ~/Projets/Redox/.env +# (variable `redox_wayland=...`) et l'injecte temporairement dans +# remote.origin.url pour authentifier le push contre forge.aditua.com. +# +# Le token n'est jamais écrit dans .git/config (on utilise `git -c` qui +# ne persiste pas), n'est pas écrit dans le wrapper, et est redacté du +# stdout/stderr s'il y apparaissait par accident. +# +# Usage : +# tools/push.sh # équivalent à `git push origin` +# tools/push.sh main # push de main spécifiquement +# tools/push.sh --force-with-lease # forward les flags à git push +# tools/push.sh tag v0.1.0 # push d'un tag +# +# Surcharge : `REDOX_ENV=/autre/.env tools/push.sh` pour pointer un +# fichier .env alternatif. + +set -e +set -o pipefail + +ENV_FILE="${REDOX_ENV:-$HOME/Projets/Redox/.env}" + +if [[ ! -f "$ENV_FILE" ]]; then + echo "ERR: fichier env introuvable : $ENV_FILE" >&2 + echo " Définis REDOX_ENV= pour pointer un autre fichier." >&2 + exit 1 +fi + +# Extraction défensive du token. Tolère "=", quotes simples/doubles, +# espaces autour. La regex `^redox_wayland=` exige le format clé=valeur +# en début de ligne. +TOKEN=$(grep -E "^redox_wayland=" "$ENV_FILE" \ + | head -1 \ + | cut -d= -f2- \ + | tr -d '"' \ + | tr -d "'" \ + | tr -d '[:space:]') + +if [[ -z "$TOKEN" ]]; then + echo "ERR: variable redox_wayland vide ou absente dans $ENV_FILE" >&2 + exit 1 +fi + +# URL origin actuelle (sans token — on l'a vérifié à l'initial push). +ORIGIN_URL=$(git remote get-url origin) + +if [[ -z "$ORIGIN_URL" ]]; then + echo "ERR: pas de remote 'origin' configuré dans ce repo" >&2 + exit 1 +fi + +# Injection du token : remplace https:// par https://leyoda:TOKEN@. +# Si l'URL n'est pas en https, on ne sait pas comment l'authentifier +# (SSH n'a pas besoin de cette gymnastique), on signale. +case "$ORIGIN_URL" in + https://*) + # On utilise sed plutôt que l'expansion bash ${VAR/from/to} + # qui ne gère pas bien les `/` dans pattern/replacement. + # `|` comme délimiteur sed pour éviter d'escaper les `/` de l'URL. + TOKENED_URL=$(printf '%s' "$ORIGIN_URL" | sed "s|^https://|https://leyoda:${TOKEN}@|") + ;; + *) + echo "ERR: origin n'est pas en https:// (got: $ORIGIN_URL)" >&2 + echo " Si tu es passé en SSH, ce wrapper n'est plus utile." >&2 + exit 1 + ;; +esac + +# Push direct via l'URL tokenée. `git -c remote.origin.url=` ne fait pas +# l'override d'URL pour le push (au moins sur cette version de git), +# donc on passe l'URL en argument explicite. +# Toute occurrence du token dans la sortie est redactée par sécurité. +git push "$TOKENED_URL" "$@" 2>&1 \ + | sed "s|${TOKEN}|***REDACTED***|g" +PUSH_STATUS=${PIPESTATUS[0]} + +# Si le push a réussi, synchroniser le tracking ref origin/main pour que +# `git status` reflète l'état distant (sinon il reste sur l'ancien tip +# de origin/main car on n'a pas pushé via le nom "origin"). +if [[ $PUSH_STATUS -eq 0 ]]; then + git fetch "$TOKENED_URL" --quiet \ + "+refs/heads/main:refs/remotes/origin/main" 2>/dev/null \ + | sed "s|${TOKEN}|***REDACTED***|g" || true +fi + +unset TOKEN TOKENED_URL +exit $PUSH_STATUS