diff --git a/.forgejo/workflows/ci-cd-web-desktop.yml b/.forgejo/workflows/ci-cd-web-desktop.yml index ebc4edd..db80c21 100644 --- a/.forgejo/workflows/ci-cd-web-desktop.yml +++ b/.forgejo/workflows/ci-cd-web-desktop.yml @@ -189,48 +189,38 @@ jobs: chown -R 1000:1000 /target echo "Permissoes do build corrigidas" - - name: Publish build to stable APP_DIR directory + - name: Atualizar symlink do APP_DIR estavel (deploy atomico) run: | - set -e - DEST="$HOME/apps/sistema" - PARENT_DIR="$HOME/apps" + set -euo pipefail + ROOT="$HOME/apps" + STABLE_LINK="$ROOT/sistema.current" - # SOLUCAO DEFINITIVA: Limpar completamente o destino usando Docker (root) - # Isso evita erros de permissao de arquivos criados por Docker em deploys anteriores - if [ -d "$DEST" ]; then - echo "Limpando diretorio destino: $DEST" - # Preservar apenas o .env (configuracoes de producao) - if [ -f "$DEST/.env" ]; then - docker run --rm -v "$DEST":/src -v /tmp:/backup alpine:3 \ - cp /src/.env /backup/.env.backup - echo ".env salvo em /tmp/.env.backup" - fi - # Remover o diretorio COMPLETAMENTE usando Docker Alpine como root - docker run --rm -v "$PARENT_DIR":/parent alpine:3 \ - rm -rf /parent/sistema - echo "Diretorio removido" + mkdir -p "$ROOT" + + # Sanidade: se esses arquivos nao existirem, o container vai falhar no boot. + test -f "$EFFECTIVE_APP_DIR/scripts/start-web.sh" || { echo "ERROR: scripts/start-web.sh nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; } + test -f "$EFFECTIVE_APP_DIR/stack.yml" || { echo "ERROR: stack.yml nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; } + test -d "$EFFECTIVE_APP_DIR/node_modules" || { echo "ERROR: node_modules nao encontrado em $EFFECTIVE_APP_DIR (necessario para next start)" >&2; exit 1; } + test -d "$EFFECTIVE_APP_DIR/.next" || { echo "ERROR: .next nao encontrado em $EFFECTIVE_APP_DIR (build nao gerado)" >&2; exit 1; } + + PREV="" + if [ -L "$STABLE_LINK" ]; then + PREV="$(readlink -f "$STABLE_LINK" || true)" + fi + echo "PREV_APP_DIR=$PREV" >> "$GITHUB_ENV" + + 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 - # Recriar o diretorio (sera criado com permissoes do usuario runner) - 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" + echo "APP_DIR estavel -> $(readlink -f "$STABLE_LINK")" - name: Swarm deploy (stack.yml) run: | - APP_DIR_STABLE="$HOME/apps/sistema" + APP_DIR_STABLE="$HOME/apps/sistema.current" if [ ! -d "$APP_DIR_STABLE" ]; then echo "ERROR: Stable APP_DIR does not exist: $APP_DIR_STABLE" >&2; exit 1 fi @@ -261,8 +251,24 @@ jobs: fi sleep 10 done - echo "AVISO: Timeout aguardando servicos. Status atual:" - docker service ls --filter "label=com.docker.stack.namespace=sistema" + echo "ERRO: Timeout aguardando servicos. Status atual:" + 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) run: | @@ -270,7 +276,7 @@ jobs: ROOT="$HOME/apps" KEEP=2 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" LIST=$(find "$ROOT" -maxdepth 1 -type d -name "$PATTERN" | sort -r || true) echo "$LIST" | sed -n "1,${KEEP}p" | sed 's/^/Keeping: /' || true