Compare commits
3
Commits
bc1b09b779
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
210efa5994 | ||
|
|
b4164187d3 | ||
|
|
44dcd0192f |
@@ -21,25 +21,37 @@ main**, puis rapatrie automatiquement le correctif dans le dev.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### En submodule (recommandé)
|
### Au niveau utilisateur (recommandé)
|
||||||
|
|
||||||
|
gitploy est un *outil* : on l'installe une fois, tous les dépôts en profitent.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. cloner une fois dans un emplacement stable
|
||||||
|
git clone gitea-figureslibres.io:bachir/gitploy.git ~/.local/share/gitploy
|
||||||
|
|
||||||
|
# 2. exposer les sous-commandes (via un dossier du PATH, ex. ~/.local/bin)
|
||||||
|
ln -sf ~/.local/share/gitploy/git-deploy ~/.local/bin/git-deploy
|
||||||
|
ln -sf ~/.local/share/gitploy/git-hotfix ~/.local/bin/git-hotfix
|
||||||
|
|
||||||
|
# 3. complétion (une fois)
|
||||||
|
echo 'source "$HOME/.local/share/gitploy/deploy-completion.bash"' >> ~/.bash_completion
|
||||||
|
```
|
||||||
|
|
||||||
|
`git deploy` / `git hotfix` sont alors disponibles dans **tous** tes dépôts,
|
||||||
|
sans alias ni `setup`. Mise à jour globale : `git -C ~/.local/share/gitploy pull`.
|
||||||
|
|
||||||
|
### En submodule (pour figer une version par projet)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# dans le dépôt qui doit déployer
|
# dans le dépôt qui doit déployer
|
||||||
git submodule add https://figureslibres.io/gitea/bachir/gitploy.git gitploy
|
git submodule add https://figureslibres.io/gitea/bachir/gitploy.git gitploy
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
gitploy/setup
|
gitploy/setup # installe des alias git locaux (sans PATH)
|
||||||
```
|
|
||||||
|
|
||||||
### En dépôt autonome
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone gitea-figureslibres.io:bachir/gitploy.git
|
|
||||||
cd gitploy && ./setup # configure le dépôt parent courant
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`setup` installe des **alias git locaux** (`git deploy`, `git hotfix`) pointant
|
`setup` installe des **alias git locaux** (`git deploy`, `git hotfix`) pointant
|
||||||
vers les scripts — **aucune modification du `PATH`**. git n'exécutant jamais une
|
vers les scripts. git n'exécutant jamais une config versionnée tout seul (par
|
||||||
config versionnée tout seul (par sécurité), cette étape unique est nécessaire.
|
sécurité), cette étape est nécessaire à chaque clone — c'est le prix du submodule.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -69,11 +81,22 @@ git deploy gitea prod -m "ajout du bloc contact"
|
|||||||
|
|
||||||
1. commit sur `master` (message obligatoire s'il y a des modifs) ;
|
1. commit sur `master` (message obligatoire s'il y a des modifs) ;
|
||||||
2. merge `master` → `prod` ;
|
2. merge `master` → `prod` ;
|
||||||
3. push atomique (dernière étape) ;
|
3. push de `prod` (dernière étape) ;
|
||||||
4. retour sur `master`.
|
4. retour sur `master`.
|
||||||
|
|
||||||
|
> `git deploy` ne pousse **que les branches nommées**, jamais `master` implicitement.
|
||||||
|
> Ça évite qu'un bare repo serveur (dont le hook n'attend qu'une branche précise)
|
||||||
|
> rejette le push.
|
||||||
|
>
|
||||||
|
> Pour sauvegarder `master` sur un remote central, inclus-le explicitement dans la
|
||||||
|
> liste — il sera poussé tel quel (sans merge) :
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> git deploy gitea master prod stage -m "message"
|
||||||
|
> ```
|
||||||
|
|
||||||
Plusieurs environnements en une commande (commit unique, merges enchaînés,
|
Plusieurs environnements en une commande (commit unique, merges enchaînés,
|
||||||
**push atomique de tout à la fin** — tout ou rien) :
|
**push atomique de toutes les branches nommées à la fin** — tout ou rien) :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git deploy gitea prod stage -m "ajout du bloc contact"
|
git deploy gitea prod stage -m "ajout du bloc contact"
|
||||||
@@ -88,11 +111,13 @@ git hotfix gitea prod -m "fix: lien du menu"
|
|||||||
|
|
||||||
1. met tes modifs de côté (stash) ;
|
1. met tes modifs de côté (stash) ;
|
||||||
2. bascule sur `prod`, applique et committe le correctif ;
|
2. bascule sur `prod`, applique et committe le correctif ;
|
||||||
3. rapatrie le correctif dans `master` (merge) ;
|
3. rapatrie le correctif dans `master` en local (merge) ;
|
||||||
4. push atomique puis retour sur `master`.
|
4. push de `prod` puis retour sur `master`.
|
||||||
|
|
||||||
Résultat : le correctif est sur `prod` **et** sur `master`, sans embarquer les
|
Résultat : le correctif est sur `prod` (poussé) **et** dans ton `master` local,
|
||||||
features non livrées de `master`.
|
sans embarquer les features non livrées de `master`. Comme `git deploy`, `git
|
||||||
|
hotfix` ne pousse **que** la branche d'env, pas `master` : ton `master` distant
|
||||||
|
se mettra à jour quand tu le pousseras explicitement.
|
||||||
|
|
||||||
## Sûreté
|
## Sûreté
|
||||||
|
|
||||||
|
|||||||
+18
-9
@@ -13,7 +13,7 @@
|
|||||||
# git config deploy.push true|false (défaut : false — push désactivé)
|
# git config deploy.push true|false (défaut : false — push désactivé)
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
DIR=$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)
|
||||||
# shellcheck source=_deploy_lib.sh
|
# shellcheck source=_deploy_lib.sh
|
||||||
. "$DIR/_deploy_lib.sh"
|
. "$DIR/_deploy_lib.sh"
|
||||||
|
|
||||||
@@ -40,10 +40,10 @@ git remote get-url "$REMOTE" >/dev/null 2>&1 || die "Remote inconnu : $REMOTE"
|
|||||||
seen=""
|
seen=""
|
||||||
for b in "${BRANCHES[@]}"; do
|
for b in "${BRANCHES[@]}"; do
|
||||||
git show-ref --verify --quiet "refs/heads/$b" || die "Branche locale inconnue : $b"
|
git show-ref --verify --quiet "refs/heads/$b" || die "Branche locale inconnue : $b"
|
||||||
[ "$b" != "$SOURCE" ] || die "'$SOURCE' est la branche de dev, pas une branche de déploiement."
|
|
||||||
case " $seen " in *" $b "*) die "Branche indiquée en double : $b" ;; esac
|
case " $seen " in *" $b "*) die "Branche indiquée en double : $b" ;; esac
|
||||||
seen="$seen $b"
|
seen="$seen $b"
|
||||||
done
|
done
|
||||||
|
# '$SOURCE' est autorisée dans la liste : elle sera poussée telle quelle (pas de merge).
|
||||||
current=$(git branch --show-current)
|
current=$(git branch --show-current)
|
||||||
[ "$current" = "$SOURCE" ] || die "Place-toi sur '$SOURCE' pour déployer (git switch $SOURCE)."
|
[ "$current" = "$SOURCE" ] || die "Place-toi sur '$SOURCE' pour déployer (git switch $SOURCE)."
|
||||||
assert_clean_git_state
|
assert_clean_git_state
|
||||||
@@ -55,10 +55,15 @@ fi
|
|||||||
|
|
||||||
# ---- Confirmation ----------------------------------------------------------
|
# ---- Confirmation ----------------------------------------------------------
|
||||||
list="${BRANCHES[*]}"
|
list="${BRANCHES[*]}"
|
||||||
if [ "$PUSH" = true ]; then push_line="OUI vers '$REMOTE' ($list + '$SOURCE', atomique)"; else push_line="NON (désactivé)"; fi
|
# branches réellement fusionnées = toutes sauf SOURCE (qui est poussée telle quelle)
|
||||||
|
merge_list=""
|
||||||
|
for b in "${BRANCHES[@]}"; do [ "$b" != "$SOURCE" ] && merge_list="$merge_list $b"; done
|
||||||
|
merge_list="${merge_list# }"
|
||||||
|
if [ "$PUSH" = true ]; then push_line="OUI vers '$REMOTE' ($list, atomique)"; else push_line="NON (désactivé)"; fi
|
||||||
[ "$dirty" = 1 ] && commit_line="commit sur '$SOURCE' : \"$MSG\"" || commit_line="aucun commit (arbre propre)"
|
[ "$dirty" = 1 ] && commit_line="commit sur '$SOURCE' : \"$MSG\"" || commit_line="aucun commit (arbre propre)"
|
||||||
|
[ -n "$merge_list" ] && merge_line="merge '$SOURCE' → $merge_list" || merge_line="aucun merge (push direct)"
|
||||||
confirm " • $commit_line
|
confirm " • $commit_line
|
||||||
• merge '$SOURCE' → $list
|
• $merge_line
|
||||||
• push : $push_line"
|
• push : $push_line"
|
||||||
|
|
||||||
# ---- Sauvegarde de l'état pour rollback ------------------------------------
|
# ---- Sauvegarde de l'état pour rollback ------------------------------------
|
||||||
@@ -96,6 +101,10 @@ if [ "$dirty" = 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
for b in "${BRANCHES[@]}"; do
|
for b in "${BRANCHES[@]}"; do
|
||||||
|
if [ "$b" = "$SOURCE" ]; then
|
||||||
|
echo "✓ '$b' (dev) incluse au push telle quelle."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
git switch -q "$b" || fail "Impossible de basculer sur '$b'."
|
git switch -q "$b" || fail "Impossible de basculer sur '$b'."
|
||||||
git merge --no-edit -q "$SOURCE" || fail "Conflit de merge sur '$b'."
|
git merge --no-edit -q "$SOURCE" || fail "Conflit de merge sur '$b'."
|
||||||
echo "✓ '$b' à jour depuis '$SOURCE'."
|
echo "✓ '$b' à jour depuis '$SOURCE'."
|
||||||
@@ -106,14 +115,14 @@ echo "✓ Local OK : $list."
|
|||||||
# ---- Push : dernière étape, atomique, jamais forcé -------------------------
|
# ---- Push : dernière étape, atomique, jamais forcé -------------------------
|
||||||
if [ "$PUSH" = true ]; then
|
if [ "$PUSH" = true ]; then
|
||||||
echo "→ Vérification du push (dry-run)…"
|
echo "→ Vérification du push (dry-run)…"
|
||||||
git push --atomic --dry-run "$REMOTE" "${BRANCHES[@]}" "$SOURCE" \
|
git push --atomic --dry-run "$REMOTE" "${BRANCHES[@]}" \
|
||||||
|| { echo "✗ Push rejeté au dry-run (non fast-forward ?). RIEN poussé. Local conservé." >&2; exit 1; }
|
|| { echo "✗ Push rejeté au dry-run (non fast-forward ?). RIEN poussé. Local conservé." >&2; exit 1; }
|
||||||
echo "→ Push atomique ($list + '$SOURCE') → '$REMOTE'…"
|
echo "→ Push atomique ($list) → '$REMOTE'…"
|
||||||
git push --atomic "$REMOTE" "${BRANCHES[@]}" "$SOURCE" \
|
git push --atomic "$REMOTE" "${BRANCHES[@]}" \
|
||||||
|| { echo "✗ Échec du push. RIEN poussé (atomique). Local conservé." >&2; \
|
|| { echo "✗ Échec du push. RIEN poussé (atomique). Local conservé." >&2; \
|
||||||
echo " Relance : git push --atomic $REMOTE $list $SOURCE" >&2; exit 1; }
|
echo " Relance : git push --atomic $REMOTE $list" >&2; exit 1; }
|
||||||
echo "✓ Poussé sur '$REMOTE'."
|
echo "✓ Poussé sur '$REMOTE'."
|
||||||
else
|
else
|
||||||
echo "→ (push désactivé) aurait fait : git push --atomic $REMOTE $list $SOURCE"
|
echo "→ (push désactivé) aurait fait : git push --atomic $REMOTE $list"
|
||||||
fi
|
fi
|
||||||
echo "✓ Terminé. Tu es sur '$SOURCE'."
|
echo "✓ Terminé. Tu es sur '$SOURCE'."
|
||||||
|
|||||||
+8
-8
@@ -18,7 +18,7 @@
|
|||||||
# git config deploy.push true|false (défaut : false — push désactivé)
|
# git config deploy.push true|false (défaut : false — push désactivé)
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
DIR=$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)
|
||||||
# shellcheck source=_deploy_lib.sh
|
# shellcheck source=_deploy_lib.sh
|
||||||
. "$DIR/_deploy_lib.sh"
|
. "$DIR/_deploy_lib.sh"
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ assert_clean_git_state
|
|||||||
{ [ "$MSG_SET" = 1 ] && [ -n "$MSG" ]; } || die 'Message requis : -m "…".'
|
{ [ "$MSG_SET" = 1 ] && [ -n "$MSG" ]; } || die 'Message requis : -m "…".'
|
||||||
|
|
||||||
# ---- Confirmation ----------------------------------------------------------
|
# ---- Confirmation ----------------------------------------------------------
|
||||||
if [ "$PUSH" = true ]; then push_line="OUI vers '$REMOTE' ('$BRANCH' + '$SOURCE', atomique)"; else push_line="NON (désactivé)"; fi
|
if [ "$PUSH" = true ]; then push_line="OUI vers '$REMOTE' ('$BRANCH')"; else push_line="NON (désactivé)"; fi
|
||||||
confirm " • stash des modifs de '$SOURCE'
|
confirm " • stash des modifs de '$SOURCE'
|
||||||
• application + commit sur '$BRANCH' : \"$MSG\"
|
• application + commit sur '$BRANCH' : \"$MSG\"
|
||||||
• rapatriement (merge) dans '$SOURCE'
|
• rapatriement (merge) dans '$SOURCE'
|
||||||
@@ -99,14 +99,14 @@ echo "✓ Local OK : hotfix sur '$BRANCH' + rapatrié dans '$SOURCE'."
|
|||||||
# ---- Push : dernière étape, atomique, jamais forcé -------------------------
|
# ---- Push : dernière étape, atomique, jamais forcé -------------------------
|
||||||
if [ "$PUSH" = true ]; then
|
if [ "$PUSH" = true ]; then
|
||||||
echo "→ Vérification du push (dry-run)…"
|
echo "→ Vérification du push (dry-run)…"
|
||||||
git push --atomic --dry-run "$REMOTE" "$BRANCH" "$SOURCE" \
|
git push --dry-run "$REMOTE" "$BRANCH" \
|
||||||
|| { echo "✗ Push rejeté au dry-run (non fast-forward ?). RIEN poussé. Local conservé." >&2; exit 1; }
|
|| { echo "✗ Push rejeté au dry-run (non fast-forward ?). RIEN poussé. Local conservé." >&2; exit 1; }
|
||||||
echo "→ Push atomique '$BRANCH' + '$SOURCE' → '$REMOTE'…"
|
echo "→ Push '$BRANCH' → '$REMOTE'…"
|
||||||
git push --atomic "$REMOTE" "$BRANCH" "$SOURCE" \
|
git push "$REMOTE" "$BRANCH" \
|
||||||
|| { echo "✗ Échec du push. RIEN poussé (atomique). Local conservé." >&2; \
|
|| { echo "✗ Échec du push. RIEN poussé. Local conservé." >&2; \
|
||||||
echo " Relance : git push --atomic $REMOTE $BRANCH $SOURCE" >&2; exit 1; }
|
echo " Relance : git push $REMOTE $BRANCH" >&2; exit 1; }
|
||||||
echo "✓ Poussé sur '$REMOTE'."
|
echo "✓ Poussé sur '$REMOTE'."
|
||||||
else
|
else
|
||||||
echo "→ (push désactivé) aurait fait : git push --atomic $REMOTE $BRANCH $SOURCE"
|
echo "→ (push désactivé) aurait fait : git push $REMOTE $BRANCH"
|
||||||
fi
|
fi
|
||||||
echo "✓ Terminé. Tu es sur '$SOURCE'."
|
echo "✓ Terminé. Tu es sur '$SOURCE'."
|
||||||
|
|||||||
Reference in New Issue
Block a user