fix(ci): deploy atomico no Forgejo (symlink)

This commit is contained in:
esdrasrenan 2025-12-17 01:44:00 -03:00
parent 2bdc5ae882
commit 380b2e44e9

View file

@ -189,48 +189,38 @@ jobs:
chown -R 1000:1000 /target chown -R 1000:1000 /target
echo "Permissoes do build corrigidas" echo "Permissoes do build corrigidas"
- name: Publish build to stable APP_DIR directory - name: Atualizar symlink do APP_DIR estavel (deploy atomico)
run: | run: |
set -e set -euo pipefail
DEST="$HOME/apps/sistema" ROOT="$HOME/apps"
PARENT_DIR="$HOME/apps" STABLE_LINK="$ROOT/sistema.current"
# SOLUCAO DEFINITIVA: Limpar completamente o destino usando Docker (root) mkdir -p "$ROOT"
# Isso evita erros de permissao de arquivos criados por Docker em deploys anteriores
if [ -d "$DEST" ]; then # Sanidade: se esses arquivos nao existirem, o container vai falhar no boot.
echo "Limpando diretorio destino: $DEST" test -f "$EFFECTIVE_APP_DIR/scripts/start-web.sh" || { echo "ERROR: scripts/start-web.sh nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; }
# Preservar apenas o .env (configuracoes de producao) test -f "$EFFECTIVE_APP_DIR/stack.yml" || { echo "ERROR: stack.yml nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; }
if [ -f "$DEST/.env" ]; then test -d "$EFFECTIVE_APP_DIR/node_modules" || { echo "ERROR: node_modules nao encontrado em $EFFECTIVE_APP_DIR (necessario para next start)" >&2; exit 1; }
docker run --rm -v "$DEST":/src -v /tmp:/backup alpine:3 \ test -d "$EFFECTIVE_APP_DIR/.next" || { echo "ERROR: .next nao encontrado em $EFFECTIVE_APP_DIR (build nao gerado)" >&2; exit 1; }
cp /src/.env /backup/.env.backup
echo ".env salvo em /tmp/.env.backup" PREV=""
fi if [ -L "$STABLE_LINK" ]; then
# Remover o diretorio COMPLETAMENTE usando Docker Alpine como root PREV="$(readlink -f "$STABLE_LINK" || true)"
docker run --rm -v "$PARENT_DIR":/parent alpine:3 \ fi
rm -rf /parent/sistema echo "PREV_APP_DIR=$PREV" >> "$GITHUB_ENV"
echo "Diretorio removido"
ln -sfn "$EFFECTIVE_APP_DIR" "$STABLE_LINK"
# Compat: mantem $HOME/apps/sistema como symlink quando possivel (nao mexe se for pasta).
if [ -L "$ROOT/sistema" ] || [ ! -e "$ROOT/sistema" ]; then
ln -sfn "$STABLE_LINK" "$ROOT/sistema"
fi fi
# Recriar o diretorio (sera criado com permissoes do usuario runner) echo "APP_DIR estavel -> $(readlink -f "$STABLE_LINK")"
mkdir -p "$DEST"
# Restaurar .env antes do rsync
if [ -f /tmp/.env.backup ]; then
cp /tmp/.env.backup "$DEST/.env"
rm /tmp/.env.backup
echo ".env restaurado"
fi
# Copiar build completo (sem conflitos de permissao agora)
rsync -a --no-owner --no-group \
--exclude '.pnpm-store' --exclude '.pnpm-store/**' \
"$EFFECTIVE_APP_DIR"/ "$DEST"/
echo "Published build to: $DEST"
- name: Swarm deploy (stack.yml) - name: Swarm deploy (stack.yml)
run: | run: |
APP_DIR_STABLE="$HOME/apps/sistema" APP_DIR_STABLE="$HOME/apps/sistema.current"
if [ ! -d "$APP_DIR_STABLE" ]; then if [ ! -d "$APP_DIR_STABLE" ]; then
echo "ERROR: Stable APP_DIR does not exist: $APP_DIR_STABLE" >&2; exit 1 echo "ERROR: Stable APP_DIR does not exist: $APP_DIR_STABLE" >&2; exit 1
fi fi
@ -261,8 +251,24 @@ jobs:
fi fi
sleep 10 sleep 10
done done
echo "AVISO: Timeout aguardando servicos. Status atual:" echo "ERRO: Timeout aguardando servicos. Status atual:"
docker service ls --filter "label=com.docker.stack.namespace=sistema" docker service ls --filter "label=com.docker.stack.namespace=sistema" || true
docker service ps sistema_web --no-trunc || true
docker service logs sistema_web --since 5m --raw 2>/dev/null | tail -n 200 || true
if [ -n "${PREV_APP_DIR:-}" ]; then
echo "Rollback: revertendo APP_DIR estavel para: $PREV_APP_DIR"
ln -sfn "$PREV_APP_DIR" "$HOME/apps/sistema.current"
cd "$HOME/apps/sistema.current"
set -o allexport
if [ -f .env ]; then
. ./.env
fi
set +o allexport
APP_DIR="$HOME/apps/sistema.current" RELEASE_SHA=${{ github.sha }} docker stack deploy --with-registry-auth -c stack.yml sistema || true
fi
exit 1
- name: Cleanup old build workdirs (keep last 2) - name: Cleanup old build workdirs (keep last 2)
run: | run: |
@ -270,7 +276,7 @@ jobs:
ROOT="$HOME/apps" ROOT="$HOME/apps"
KEEP=2 KEEP=2
PATTERN='web.build.*' PATTERN='web.build.*'
ACTIVE="$HOME/apps/sistema" ACTIVE="$(readlink -f "$HOME/apps/sistema.current" 2>/dev/null || true)"
echo "Scanning $ROOT for old $PATTERN dirs" echo "Scanning $ROOT for old $PATTERN dirs"
LIST=$(find "$ROOT" -maxdepth 1 -type d -name "$PATTERN" | sort -r || true) LIST=$(find "$ROOT" -maxdepth 1 -type d -name "$PATTERN" | sort -r || true)
echo "$LIST" | sed -n "1,${KEEP}p" | sed 's/^/Keeping: /' || true echo "$LIST" | sed -n "1,${KEEP}p" | sed 's/^/Keeping: /' || true