ci(deploy): rewrite for build-on-droplet + local runner

This commit is contained in:
dilonne
2026-09-02 19:55:56 +02:00
parent 8ef06cb3e7
commit f5a83507a6
+17 -84
View File
@@ -1,21 +1,9 @@
# aibook-fun — CI/CD: build the Next.js marketing site, push to reg.mini.dev,
# pin the image ref in Infisical, then trigger a pull + bounce on the droplet.
#
# Runs on Gitea Actions (GitHub-compatible syntax). This repo has Actions
# enabled; the runner must be labeled `ubuntu-latest`.
# Rebuild + roll aibook.fun forward on any push to main.
# Runner: repo-registered act_runner on the aibook.fun droplet itself
# (co-located → local docker commands, no cross-host SSH needed).
#
# Repository secrets required (Settings → Actions → Secrets):
# MINIMUS_TOKEN reg.mini.dev registry token (u: minimus)
# INFISICAL_CLIENT_ID Infisical Machine Identity Client ID
# INFISICAL_CLIENT_SECRET Infisical Machine Identity Client Secret
# INFISICAL_PROJECT_ID the /AIBook-Fun project ID
# DROPLET_IP droplet reserved IP (or resolve via DNS)
# DROPLET_SSH_KEY private SSH key for root@ on the droplet
#
# NOTE: first provision is NOT done here — it's terraform + ansible converge
# (deploy/docker-compose/terraform + ansible/deploy.yml). This workflow handles
# everything after the site exists: every main-branch push to app/deploy code
# rebuilds and rolls forward idempotently.
# (none — runner is on the droplet, has local root)
name: deploy
@@ -28,78 +16,23 @@ on:
- '.gitea/workflows/**'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: aibook-fun-deploy
cancel-in-progress: false
env:
REGISTRY: reg.mini.dev
IMAGE_REPO: weownai/aibook-fun-marketing
INFISICAL_ENV: prod
INFISICAL_PATH: /AIBook-Fun
jobs:
build-and-deploy:
runs-on: ubuntu-latest
deploy:
runs-on: aibook-fun-droplet
steps:
- uses: actions/checkout@v4
- name: Build image
- name: Pull latest + rebuild + roll
run: |
docker build \
--pull \
-f deploy/docker-compose/docker/Dockerfile \
-t "${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:${{ github.sha }}" \
-t "${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:latest" \
marketing-site/
- name: Login to reg.mini.dev
run: echo "${{ secrets.MINIMUS_TOKEN }}" | docker login "${{ env.REGISTRY }}" -u minimus --password-stdin
- name: Push image
run: |
docker push "${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:${{ github.sha }}"
docker push "${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:latest"
- name: Pin AIBOOK_IMAGE in Infisical
env:
INFISICAL_UNIVERSAL_AUTH_CLIENT_ID: ${{ secrets.INFISICAL_CLIENT_ID }}
INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET: ${{ secrets.INFISICAL_CLIENT_SECRET }}
run: |
sudo curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | sudo -E bash
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq infisical >/dev/null
export INFISICAL_TOKEN="$(infisical login --method=universal-auth --plain --silent)"
infisical secrets set \
AIBOOK_IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:${{ github.sha }}" \
--projectId="${{ secrets.INFISICAL_PROJECT_ID }}" \
--env="${{ env.INFISICAL_ENV }}" \
--path="${{ env.INFISICAL_PATH }}"
- name: Deploy to droplet (pull + up)
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DROPLET_IP }}
username: root
key: ${{ secrets.DROPLET_SSH_KEY }}
command_timeout: "15m"
script: |
set -euo pipefail
cd /opt/aibook_fun
# Droplet-side Infisical auth (auth file written by cloud-init).
source .infisical-auth.env
export INFISICAL_UNIVERSAL_AUTH_CLIENT_ID="$INFISICAL_CLIENT_ID"
export INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET="$INFISICAL_CLIENT_SECRET"
export INFISICAL_TOKEN="$(infisical login --method=universal-auth --plain --silent)"
# Re-auth reg.mini.dev if the docker login from ansible has lapsed.
MINIMUS_TOKEN="$(infisical secrets get MINIMUS_TOKEN --projectId="$INFISICAL_PROJECT_ID" --env=prod --path=/AIBook-Fun --plain || true)"
if [ -n "${MINIMUS_TOKEN:-}" ]; then
printf '%s' "$MINIMUS_TOKEN" | docker login reg.mini.dev -u minimus --password-stdin
fi
# AIBOOK_IMAGE is injected by `infisical run`; also export it so the
# ${AIBOOK_IMAGE:?} compose ref resolves even without run-injection.
export AIBOOK_IMAGE="$(infisical secrets get AIBOOK_IMAGE --projectId="$INFISICAL_PROJECT_ID" --env=prod --path=/AIBook-Fun --plain)"
infisical run --projectId="$INFISICAL_PROJECT_ID" --env=prod --path=/AIBook-Fun \
-- docker compose up -d --remove-orphans
set -euo pipefail
cd /opt/aibook_fun/repo
git fetch --prune origin
git reset --hard origin/main
docker build -t aibook-fun-marketing:v1 \
-f /opt/aibook_fun/repo/deploy/docker/Dockerfile \
/opt/aibook_fun/repo/marketing-site/
cd /opt/aibook_fun
docker compose up -d --remove-orphans
docker image prune -f --filter "dangling=true"