Some checks failed
CD / Build and push images (push) Successful in 1m41s
CI / Lint, typecheck, test (push) Failing after 1m40s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 21s
CD / Smoke tests against Test (push) Successful in 1m6s
CD / Promote to Int (push) Successful in 19s
pnpm/action-setup reads the version from package.json packageManager — the explicit `version: 11` input made it fail on the mismatch. The registry login now strips whitespace from the stored token before docker login (the secret carried a trailing newline). Part of #8 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
123 lines
4.3 KiB
YAML
123 lines
4.3 KiB
YAML
# CD: every push to main builds images once, deploys them to Test, runs
|
|
# the smoke suite against the live Test stage, and promotes the identical
|
|
# images to Int on success (ADR 0014). Prod deploys are a separate,
|
|
# manually gated release workflow (issue #89).
|
|
|
|
name: CD
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
|
|
env:
|
|
IMAGE_BASE: gitea.101010.cloud/stwaidele/dorfteich
|
|
DEPLOY_HOST: 188.245.116.44
|
|
|
|
jobs:
|
|
build-push:
|
|
name: Build and push images
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Log in to the Gitea registry
|
|
run: printf '%s' "${{ secrets.REGISTRY_TOKEN }}" | tr -d '[:space:]' | docker login gitea.101010.cloud -u fable-5 --password-stdin
|
|
|
|
# Tags: the immutable SHA (promotion + rollback target) and the
|
|
# moving `test` tag that the Test stage's compose file pulls.
|
|
- name: Build and push web image
|
|
run: |
|
|
docker build -f apps/web/Dockerfile --build-arg APP_VERSION=${{ github.sha }} \
|
|
-t $IMAGE_BASE-web:${{ github.sha }} -t $IMAGE_BASE-web:test .
|
|
docker push $IMAGE_BASE-web:${{ github.sha }}
|
|
docker push $IMAGE_BASE-web:test
|
|
|
|
- name: Build and push api image
|
|
run: |
|
|
docker build -f apps/api/Dockerfile --build-arg APP_VERSION=${{ github.sha }} \
|
|
-t $IMAGE_BASE-api:${{ github.sha }} -t $IMAGE_BASE-api:test .
|
|
docker push $IMAGE_BASE-api:${{ github.sha }}
|
|
docker push $IMAGE_BASE-api:test
|
|
|
|
deploy-test:
|
|
name: Deploy to Test
|
|
needs: build-push
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Set up SSH
|
|
run: |
|
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY_TEST }}" > ~/.ssh/id_ed25519
|
|
chmod 600 ~/.ssh/id_ed25519
|
|
printf '%s\n' "${{ secrets.DEPLOY_HOST_KEY }}" > ~/.ssh/known_hosts
|
|
|
|
- name: Pull and restart the Test stack
|
|
run: |
|
|
ssh deploy@$DEPLOY_HOST 'cd /home/DOCKER/dorfteich-test \
|
|
&& docker compose pull --quiet && docker compose up -d --remove-orphans \
|
|
&& docker compose ps'
|
|
|
|
smoke-test:
|
|
name: Smoke tests against Test
|
|
needs: deploy-test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Install Playwright browser
|
|
run: pnpm --filter @dorfteich/web exec playwright install --with-deps chromium
|
|
|
|
- name: Wait for the Test stage to be ready
|
|
run: |
|
|
for i in $(seq 1 30); do
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' https://test.dorfteich.cloud/api/v1/readyz || true)
|
|
[ "$code" = "200" ] && exit 0
|
|
sleep 5
|
|
done
|
|
echo "Test stage did not become ready" >&2; exit 1
|
|
|
|
- name: Run smoke suite
|
|
run: E2E_BASE_URL=https://test.dorfteich.cloud pnpm --filter @dorfteich/web exec playwright test
|
|
|
|
promote-int:
|
|
name: Promote to Int
|
|
needs: smoke-test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Log in to the Gitea registry
|
|
run: printf '%s' "${{ secrets.REGISTRY_TOKEN }}" | tr -d '[:space:]' | docker login gitea.101010.cloud -u fable-5 --password-stdin
|
|
|
|
# Registry-side retag of the SHA images that just passed on Test —
|
|
# Int always runs bit-identical images, never a rebuild.
|
|
- name: Retag SHA images as :int
|
|
run: |
|
|
docker buildx imagetools create -t $IMAGE_BASE-web:int $IMAGE_BASE-web:${{ github.sha }}
|
|
docker buildx imagetools create -t $IMAGE_BASE-api:int $IMAGE_BASE-api:${{ github.sha }}
|
|
|
|
- name: Set up SSH
|
|
run: |
|
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY_INT }}" > ~/.ssh/id_ed25519
|
|
chmod 600 ~/.ssh/id_ed25519
|
|
printf '%s\n' "${{ secrets.DEPLOY_HOST_KEY }}" > ~/.ssh/known_hosts
|
|
|
|
- name: Pull and restart the Int stack
|
|
run: |
|
|
ssh deploy@$DEPLOY_HOST 'cd /home/DOCKER/dorfteich-int \
|
|
&& docker compose pull --quiet && docker compose up -d --remove-orphans \
|
|
&& docker compose ps'
|