chore(deploy): possibilidade de fazer multiplos commits antes do push
This commit is contained in:
239
deploy.sh
239
deploy.sh
@@ -96,123 +96,138 @@ success "Branch: ${BOLD}$BRANCH${RESET}"
|
|||||||
# ──────────────────────────────────────────
|
# ──────────────────────────────────────────
|
||||||
# GATE 2 — Working tree limpa
|
# GATE 2 — Working tree limpa
|
||||||
# ──────────────────────────────────────────
|
# ──────────────────────────────────────────
|
||||||
|
function worktree() {
|
||||||
|
# Em modo release, working tree tem de estar absolutamente limpa
|
||||||
|
if [[ -n "$RELEASE_TYPE" ]]; then
|
||||||
|
warn "Arquivos não commitados:"
|
||||||
|
[[ -n "$STAGED" ]] && echo -e " ${GREEN}Staged:${RESET}\n$(echo "$STAGED" | sed 's/^/ /')"
|
||||||
|
[[ -n "$MODIFIED" ]] && echo -e " ${YELLOW}Modificados:${RESET}\n$(echo "$MODIFIED" | sed 's/^/ /')"
|
||||||
|
[[ -n "$UNTRACKED" ]] && echo -e " ${RED}Não rastreados:${RESET}\n$(echo "$UNTRACKED" | sed 's/^/ /')"
|
||||||
|
die "Working tree suja. Faça commit ou stash antes de um release."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Seletor interativo de arquivos ──────────────────────────────────────
|
||||||
|
# Monta lista indexada: staged (S), modificados (M), não rastreados (?)
|
||||||
|
declare -a ALL_FILES
|
||||||
|
declare -a ALL_LABELS
|
||||||
|
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${GREEN}staged${RESET}"); done <<< "$STAGED"
|
||||||
|
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${YELLOW}modificado${RESET}"); done <<< "$MODIFIED"
|
||||||
|
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${RED}novo${RESET}"); done <<< "$UNTRACKED"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Mudanças detectadas:${RESET}"
|
||||||
|
for i in "${!ALL_FILES[@]}"; do
|
||||||
|
printf " %2d) %b %s\n" "$((i+1))" "${ALL_LABELS[$i]}" "${ALL_FILES[$i]}"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
declare -a SELECTED_FILES
|
||||||
|
|
||||||
|
echo -e "Digite os números para adicionar ao commit, ${BOLD}all${RESET} para todos, ou ${BOLD}done${RESET} para encerrar:"
|
||||||
|
while true; do
|
||||||
|
echo -ne "${BLUE}▸${RESET} "
|
||||||
|
read -r INPUT
|
||||||
|
|
||||||
|
case "$INPUT" in
|
||||||
|
done|"")
|
||||||
|
[[ ${#SELECTED_FILES[@]} -eq 0 ]] && die "Nenhum arquivo selecionado. Operação cancelada."
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
all)
|
||||||
|
SELECTED_FILES=("${ALL_FILES[@]}")
|
||||||
|
echo -e " ${GREEN}✔${RESET} Todos os arquivos adicionados."
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Aceita múltiplos números na mesma linha (ex: "1 3 5")
|
||||||
|
for TOKEN in $INPUT; do
|
||||||
|
if [[ "$TOKEN" =~ ^[0-9]+$ ]] && (( TOKEN >= 1 && TOKEN <= ${#ALL_FILES[@]} )); then
|
||||||
|
FILE="${ALL_FILES[$((TOKEN-1))]}"
|
||||||
|
# Evita duplicatas
|
||||||
|
if printf '%s\n' "${SELECTED_FILES[@]+"${SELECTED_FILES[@]}"}" | grep -qxF "$FILE"; then
|
||||||
|
warn "$FILE já está na lista."
|
||||||
|
else
|
||||||
|
SELECTED_FILES+=("$FILE")
|
||||||
|
echo -e " ${GREEN}✔${RESET} adicionado: ${BOLD}$FILE${RESET}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Entrada inválida: '$TOKEN' — use um número entre 1 e ${#ALL_FILES[@]}, 'all' ou 'done'."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "Arquivos no commit:"
|
||||||
|
for f in "${SELECTED_FILES[@]}"; do echo " $f"; done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ── Mensagem de commit ──────────────────────────────────────────────────
|
||||||
|
echo "Tipos de commit (Conventional Commits):"
|
||||||
|
echo " feat → nova funcionalidade"
|
||||||
|
echo " fix → correção de bug"
|
||||||
|
echo " docs → só documentação"
|
||||||
|
echo " refactor → refatoração sem mudança de comportamento"
|
||||||
|
echo " test → adição/correção de testes"
|
||||||
|
echo " chore → manutenção, dependências, CI"
|
||||||
|
echo " style → formatação, whitespace"
|
||||||
|
echo ""
|
||||||
|
echo -n "Tipo: "
|
||||||
|
read -r COMMIT_TYPE
|
||||||
|
[[ "$COMMIT_TYPE" =~ ^(feat|fix|docs|refactor|test|chore|style)$ ]] \
|
||||||
|
|| die "Tipo inválido. Use um dos listados acima."
|
||||||
|
|
||||||
|
echo -n "Escopo (opcional, ex: auth, api, ui — Enter para pular): "
|
||||||
|
read -r COMMIT_SCOPE
|
||||||
|
|
||||||
|
echo -n "Descrição curta: "
|
||||||
|
read -r COMMIT_DESC
|
||||||
|
[[ -z "$COMMIT_DESC" ]] && die "Descrição não pode ser vazia."
|
||||||
|
|
||||||
|
echo -n "Há breaking changes? [s/N]: "
|
||||||
|
read -r BREAKING
|
||||||
|
BREAKING_FOOTER=""
|
||||||
|
if [[ "$BREAKING" =~ ^[sS]$ ]]; then
|
||||||
|
echo -n "Descreva o breaking change: "
|
||||||
|
read -r BREAKING_MSG
|
||||||
|
BREAKING_FOOTER=$'\n\nBREAKING CHANGE: '"$BREAKING_MSG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$COMMIT_SCOPE" ]]; then
|
||||||
|
COMMIT_MSG="${COMMIT_TYPE}(${COMMIT_SCOPE}): ${COMMIT_DESC}${BREAKING_FOOTER}"
|
||||||
|
else
|
||||||
|
COMMIT_MSG="${COMMIT_TYPE}: ${COMMIT_DESC}${BREAKING_FOOTER}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "Mensagem: ${BOLD}${COMMIT_MSG}${RESET}"
|
||||||
|
|
||||||
|
for f in "${SELECTED_FILES[@]}"; do run git add -- "$f"; done
|
||||||
|
run git commit -m "$COMMIT_MSG"
|
||||||
|
success "Commit criado."
|
||||||
|
}
|
||||||
|
|
||||||
step "[ 2/6 ] Verificando working tree..."
|
step "[ 2/6 ] Verificando working tree..."
|
||||||
|
|
||||||
UNTRACKED=$(git ls-files --others --exclude-standard)
|
function thereschanges(){
|
||||||
MODIFIED=$(git diff --name-only)
|
UNTRACKED=$(git ls-files --others --exclude-standard)
|
||||||
STAGED=$(git diff --cached --name-only)
|
MODIFIED=$(git diff --name-only)
|
||||||
|
STAGED=$(git diff --cached --name-only)
|
||||||
if [[ -n "$UNTRACKED" || -n "$MODIFIED" || -n "$STAGED" ]]; then
|
if [[ -n "$UNTRACKED" || -n "$MODIFIED" || -n "$STAGED" ]]; then
|
||||||
|
return 0
|
||||||
# Em modo release, working tree tem de estar absolutamente limpa
|
|
||||||
if [[ -n "$RELEASE_TYPE" ]]; then
|
|
||||||
warn "Arquivos não commitados:"
|
|
||||||
[[ -n "$STAGED" ]] && echo -e " ${GREEN}Staged:${RESET}\n$(echo "$STAGED" | sed 's/^/ /')"
|
|
||||||
[[ -n "$MODIFIED" ]] && echo -e " ${YELLOW}Modificados:${RESET}\n$(echo "$MODIFIED" | sed 's/^/ /')"
|
|
||||||
[[ -n "$UNTRACKED" ]] && echo -e " ${RED}Não rastreados:${RESET}\n$(echo "$UNTRACKED" | sed 's/^/ /')"
|
|
||||||
die "Working tree suja. Faça commit ou stash antes de um release."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Seletor interativo de arquivos ──────────────────────────────────────
|
|
||||||
# Monta lista indexada: staged (S), modificados (M), não rastreados (?)
|
|
||||||
declare -a ALL_FILES
|
|
||||||
declare -a ALL_LABELS
|
|
||||||
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${GREEN}staged${RESET}"); done <<< "$STAGED"
|
|
||||||
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${YELLOW}modificado${RESET}"); done <<< "$MODIFIED"
|
|
||||||
while IFS= read -r f; do [[ -n "$f" ]] && ALL_FILES+=("$f") && ALL_LABELS+=("${RED}novo${RESET}"); done <<< "$UNTRACKED"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BOLD}Mudanças detectadas:${RESET}"
|
|
||||||
for i in "${!ALL_FILES[@]}"; do
|
|
||||||
printf " %2d) %b %s\n" "$((i+1))" "${ALL_LABELS[$i]}" "${ALL_FILES[$i]}"
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
declare -a SELECTED_FILES
|
|
||||||
|
|
||||||
echo -e "Digite os números para adicionar ao commit, ${BOLD}all${RESET} para todos, ou ${BOLD}done${RESET} para encerrar:"
|
|
||||||
while true; do
|
|
||||||
echo -ne "${BLUE}▸${RESET} "
|
|
||||||
read -r INPUT
|
|
||||||
|
|
||||||
case "$INPUT" in
|
|
||||||
done|"")
|
|
||||||
[[ ${#SELECTED_FILES[@]} -eq 0 ]] && die "Nenhum arquivo selecionado. Operação cancelada."
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
all)
|
|
||||||
SELECTED_FILES=("${ALL_FILES[@]}")
|
|
||||||
echo -e " ${GREEN}✔${RESET} Todos os arquivos adicionados."
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Aceita múltiplos números na mesma linha (ex: "1 3 5")
|
|
||||||
for TOKEN in $INPUT; do
|
|
||||||
if [[ "$TOKEN" =~ ^[0-9]+$ ]] && (( TOKEN >= 1 && TOKEN <= ${#ALL_FILES[@]} )); then
|
|
||||||
FILE="${ALL_FILES[$((TOKEN-1))]}"
|
|
||||||
# Evita duplicatas
|
|
||||||
if printf '%s\n' "${SELECTED_FILES[@]+"${SELECTED_FILES[@]}"}" | grep -qxF "$FILE"; then
|
|
||||||
warn "$FILE já está na lista."
|
|
||||||
else
|
|
||||||
SELECTED_FILES+=("$FILE")
|
|
||||||
echo -e " ${GREEN}✔${RESET} adicionado: ${BOLD}$FILE${RESET}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Entrada inválida: '$TOKEN' — use um número entre 1 e ${#ALL_FILES[@]}, 'all' ou 'done'."
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
info "Arquivos no commit:"
|
|
||||||
for f in "${SELECTED_FILES[@]}"; do echo " $f"; done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# ── Mensagem de commit ──────────────────────────────────────────────────
|
|
||||||
echo "Tipos de commit (Conventional Commits):"
|
|
||||||
echo " feat → nova funcionalidade"
|
|
||||||
echo " fix → correção de bug"
|
|
||||||
echo " docs → só documentação"
|
|
||||||
echo " refactor → refatoração sem mudança de comportamento"
|
|
||||||
echo " test → adição/correção de testes"
|
|
||||||
echo " chore → manutenção, dependências, CI"
|
|
||||||
echo " style → formatação, whitespace"
|
|
||||||
echo ""
|
|
||||||
echo -n "Tipo: "
|
|
||||||
read -r COMMIT_TYPE
|
|
||||||
[[ "$COMMIT_TYPE" =~ ^(feat|fix|docs|refactor|test|chore|style)$ ]] \
|
|
||||||
|| die "Tipo inválido. Use um dos listados acima."
|
|
||||||
|
|
||||||
echo -n "Escopo (opcional, ex: auth, api, ui — Enter para pular): "
|
|
||||||
read -r COMMIT_SCOPE
|
|
||||||
|
|
||||||
echo -n "Descrição curta: "
|
|
||||||
read -r COMMIT_DESC
|
|
||||||
[[ -z "$COMMIT_DESC" ]] && die "Descrição não pode ser vazia."
|
|
||||||
|
|
||||||
echo -n "Há breaking changes? [s/N]: "
|
|
||||||
read -r BREAKING
|
|
||||||
BREAKING_FOOTER=""
|
|
||||||
if [[ "$BREAKING" =~ ^[sS]$ ]]; then
|
|
||||||
echo -n "Descreva o breaking change: "
|
|
||||||
read -r BREAKING_MSG
|
|
||||||
BREAKING_FOOTER=$'\n\nBREAKING CHANGE: '"$BREAKING_MSG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$COMMIT_SCOPE" ]]; then
|
|
||||||
COMMIT_MSG="${COMMIT_TYPE}(${COMMIT_SCOPE}): ${COMMIT_DESC}${BREAKING_FOOTER}"
|
|
||||||
else
|
else
|
||||||
COMMIT_MSG="${COMMIT_TYPE}: ${COMMIT_DESC}${BREAKING_FOOTER}"
|
return 1
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo ""
|
if thereschanges; then
|
||||||
info "Mensagem: ${BOLD}${COMMIT_MSG}${RESET}"
|
worktree
|
||||||
|
if thereschanges; then
|
||||||
for f in "${SELECTED_FILES[@]}"; do run git add -- "$f"; done
|
echo -n "Deseja criar outro commit? [s/N]: "
|
||||||
run git commit -m "$COMMIT_MSG"
|
read -r OTHERCOMMIT
|
||||||
success "Commit criado."
|
[[ "$OTHERCOMMIT" =~ ^[sS]$ ]] && worktree
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
success "Working tree limpa."
|
success "Working tree limpa."
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user