d5bfba8b72
- build: fixa COMPOSE_PROJECT_NAME=scoreodontocom (imagem buildada batia com nome errado no tag/push → carimbo da Etapa 3 vazava) - novo job deploy: só em tags v*, SSH VPS4->VPS1 roda deploy-prod.sh (push na main não deploya) - deploy.md: Metade B + roadmap Etapa 6 = FEITO Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
3.6 KiB
YAML
92 lines
3.6 KiB
YAML
name: build-and-push
|
|
|
|
# Etapa 5: a cada push na main (ou tag vX.Y.Z), builda as imagens com o carimbo
|
|
# de versão e envia ao Container Registry do Gitea. NÃO faz deploy (Etapa 6 separada).
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
tags: ['v*']
|
|
|
|
jobs:
|
|
build:
|
|
# Roda direto no host VPS4 (runner registrado com label de host + acesso ao Docker).
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Calcular versão/commit/data
|
|
id: vars
|
|
run: |
|
|
echo "version=$(grep -oE 'V[0-9]+\.[0-9]+\.[0-9]+' frontend/constants.ts | head -1 | tr 'V' 'v')" >> "$GITHUB_OUTPUT"
|
|
echo "commit=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
|
|
echo "build_time=$(date -u +'%Y-%m-%d %H:%M UTC')" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Login no registry
|
|
run: |
|
|
if [ -n "${{ secrets.REGISTRY_TOKEN }}" ]; then
|
|
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.clube67.com -u ruicesar --password-stdin
|
|
else
|
|
echo "REGISTRY_TOKEN não definido — usando a credencial já presente no host (~/.docker/config.json)."
|
|
fi
|
|
|
|
- name: Build (compose, com carimbo de versão)
|
|
env:
|
|
# Fixa o nome do projeto p/ a imagem buildada bater com o passo de tag
|
|
# (em modo host o diretório do checkout muda o project name por padrão).
|
|
COMPOSE_PROJECT_NAME: scoreodontocom
|
|
APP_VERSION: ${{ steps.vars.outputs.version }}
|
|
GIT_COMMIT: ${{ steps.vars.outputs.commit }}
|
|
BUILD_TIME: ${{ steps.vars.outputs.build_time }}
|
|
APP_ENV: PROD
|
|
run: docker compose build scoreodonto-backend scoreodonto-frontend
|
|
|
|
- name: Tag + push (com retry p/ 499 transitório)
|
|
run: |
|
|
set -e
|
|
V="${{ steps.vars.outputs.version }}"
|
|
C="${{ steps.vars.outputs.commit }}"
|
|
for app in backend frontend; do
|
|
SRC="scoreodontocom-scoreodonto-${app}:latest"
|
|
DST="git.clube67.com/ruicesar/scoreodonto-${app}"
|
|
docker tag "$SRC" "$DST:$V"
|
|
docker tag "$SRC" "$DST:$C"
|
|
docker tag "$SRC" "$DST:latest"
|
|
for tag in "$V" "$C" "latest"; do
|
|
n=0
|
|
until docker push "$DST:$tag"; do
|
|
n=$((n+1)); [ $n -ge 4 ] && { echo "push falhou após 4 tentativas: $DST:$tag"; exit 1; }
|
|
echo "retry $n (499 transitório) em $DST:$tag"; sleep 3
|
|
done
|
|
done
|
|
done
|
|
|
|
- name: Resumo
|
|
run: |
|
|
echo "Imagens publicadas:"
|
|
echo " git.clube67.com/ruicesar/scoreodonto-backend:${{ steps.vars.outputs.version }}"
|
|
echo " git.clube67.com/ruicesar/scoreodonto-frontend:${{ steps.vars.outputs.version }}"
|
|
echo "Deploy só acontece em TAG (job deploy)."
|
|
|
|
# Deploy automático SÓ em tags vX.Y.Z (a tag = 'aprovado para produção').
|
|
# Push na main NÃO deploya — só builda. Etapa 6.
|
|
deploy:
|
|
needs: build
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Promover a tag para produção (VPS1)
|
|
run: |
|
|
set -e
|
|
TAG="${GITHUB_REF_NAME}"
|
|
echo "Promovendo $TAG para a produção (VPS1)..."
|
|
# Garante que o mecanismo de deploy está atualizado na VPS1
|
|
scp -o StrictHostKeyChecking=accept-new \
|
|
docker-compose.prod.yml deploy-prod.sh \
|
|
deploy@10.99.0.1:/home/deploy/stack/scoreodonto.com/
|
|
ssh -o StrictHostKeyChecking=accept-new deploy@10.99.0.1 \
|
|
"/home/deploy/stack/scoreodonto.com/deploy-prod.sh $TAG"
|