diff --git a/.forgejo/workflows/deploy-prod.yml b/.forgejo/workflows/deploy-prod.yml new file mode 100644 index 0000000..de5c176 --- /dev/null +++ b/.forgejo/workflows/deploy-prod.yml @@ -0,0 +1,59 @@ +name: Deploy frontend to prod VPS + +# On a push to `release`, SSH to prod and roll ONLY the frontend service onto +# the image build-push.yml just published for this commit. This is the +# release->prod path, distinct from deploy.yml's main->beta path -- same +# shape, different branch, different target host, and a completely separate +# secret set (PROD_SSH_HOST/USER/KEY/PORT), so a beta credential leak can't +# touch prod and vice versa. Backend is deployed independently by its own +# repo's deploy-prod.yml -- that is the whole point of the FE/BE CI-CD split: +# a frontend change ships without touching backend and vice versa. +# thermograph-infra/deploy/deploy.sh persists each service's live tag +# host-side, so a single-service roll never disturbs the other. +# +# The prod SSH user (agent) has full sudo because the SOPS secrets render +# sudo-reads the age key on that box, but that's handled inside deploy.sh -- +# nothing extra is needed here. appleboy/ssh-action is referenced by full +# GitHub URL because it isn't mirrored in Forgejo's default action registry. +# +# The tag MUST match build-push.yml's `sha-${GITHUB_SHA:0:12}` (12 hex), not +# the full 40-char ${{ github.sha }} -- default Actions expressions have no +# substring function, so the compute step below truncates it. deploy.sh also +# retries the pull for ~5 min because Forgejo `needs:` can't gate across the +# separate build-push.yml, so this push's build may still be in flight. +# +# Frontend's own register() fetches the IndexNow key from backend at boot, so +# deploy.sh waits on a healthy backend before declaring the frontend roll OK +# (its compose depends_on already encodes that ordering). + +on: + push: + branches: [release] + workflow_dispatch: {} + +concurrency: + group: prod-deploy-frontend + cancel-in-progress: false + +jobs: + deploy: + runs-on: docker + steps: + - name: Compute image tag + id: tag + run: echo "tag=sha-${GITHUB_SHA:0:12}" >> "$GITHUB_OUTPUT" + + - name: Deploy frontend over SSH + uses: https://github.com/appleboy/ssh-action@v1.2.0 + with: + host: ${{ secrets.PROD_SSH_HOST }} + username: ${{ secrets.PROD_SSH_USER }} + key: ${{ secrets.PROD_SSH_KEY }} + port: ${{ secrets.PROD_SSH_PORT }} + # Forward the target service + the image tag to run. deploy.sh reads + # FRONTEND_IMAGE_TAG and rolls just `frontend`. + envs: SERVICE,FRONTEND_IMAGE_TAG + script: /opt/thermograph/deploy/deploy.sh + env: + SERVICE: frontend + FRONTEND_IMAGE_TAG: ${{ steps.tag.outputs.tag }}