Gate the deploy on tests. After pulling master and before building the image, run the full Go suite (incl. integration tests, against an ephemeral Postgres) and the frontend type-check + build. Everything runs inside throwaway toolchain containers, so the host still needs only docker and a red build never reaches production. Update DEPLOY.md to reflect the gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,9 @@ jobs:
|
|||||||
# existing clone in /opt/tanabata. See docs/DEPLOY.md for runner setup.
|
# existing clone in /opt/tanabata. See docs/DEPLOY.md for runner setup.
|
||||||
#
|
#
|
||||||
# Only shell steps here (no `uses:` actions), so the host needs git + docker
|
# Only shell steps here (no `uses:` actions), so the host needs git + docker
|
||||||
# and nothing else — no node, no rsync.
|
# and nothing else — no node, no go, no rsync. The test step below runs the
|
||||||
|
# Go and Node toolchains inside throwaway containers, so nothing has to be
|
||||||
|
# installed on the host.
|
||||||
runs-on: host
|
runs-on: host
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -35,6 +37,47 @@ jobs:
|
|||||||
git fetch --prune origin
|
git fetch --prune origin
|
||||||
git reset --hard origin/master
|
git reset --hard origin/master
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
working-directory: /opt/tanabata
|
||||||
|
# Everything runs INSIDE throwaway toolchain containers — the host only
|
||||||
|
# needs docker (which it already uses for `docker compose`). Nothing (Go,
|
||||||
|
# Node, Postgres, vips/ffmpeg/exiftool) has to be installed on the host.
|
||||||
|
# The orchestration below uses only bash builtins + docker. A failure here
|
||||||
|
# fails the job, so a red build never reaches production. Module/npm caches
|
||||||
|
# persist in named volumes for speed.
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
docker rm -f tfm-ci-db >/dev/null 2>&1 || true
|
||||||
|
docker network rm tfm-ci-net >/dev/null 2>&1 || true
|
||||||
|
docker network create tfm-ci-net >/dev/null
|
||||||
|
trap 'docker rm -f tfm-ci-db >/dev/null 2>&1 || true; docker network rm tfm-ci-net >/dev/null 2>&1 || true' EXIT
|
||||||
|
|
||||||
|
docker run -d --name tfm-ci-db --network tfm-ci-net \
|
||||||
|
-e POSTGRES_PASSWORD=postgres postgres:14-alpine >/dev/null
|
||||||
|
# Wait for Postgres, using pg_isready inside the DB container (no host tools).
|
||||||
|
for ((i = 0; i < 30; i++)); do
|
||||||
|
docker exec tfm-ci-db pg_isready -U postgres >/dev/null 2>&1 && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Backend: full suite, including the integration tests, against the
|
||||||
|
# ephemeral Postgres. -buildvcs=false since the .git dir isn't mounted.
|
||||||
|
docker run --rm --network tfm-ci-net \
|
||||||
|
-v /opt/tanabata/backend:/src -w /src \
|
||||||
|
-v tfm-ci-gomod:/go/pkg/mod -v tfm-ci-gocache:/root/.cache/go-build \
|
||||||
|
-e CGO_ENABLED=0 \
|
||||||
|
-e TANABATA_TEST_ADMIN_DSN="postgres://postgres:postgres@tfm-ci-db:5432/postgres?sslmode=disable" \
|
||||||
|
golang:1.26-alpine go test -buildvcs=false -count=1 ./...
|
||||||
|
|
||||||
|
# Frontend: type-check + production build (also validates openapi via
|
||||||
|
# the generate:types prestep).
|
||||||
|
docker run --rm \
|
||||||
|
-v /opt/tanabata:/repo -w /repo/frontend \
|
||||||
|
-v tfm-ci-npm:/root/.npm \
|
||||||
|
node:22-alpine sh -c "npm ci && npm run check && npm run build"
|
||||||
|
|
||||||
- name: Build image and start the stack
|
- name: Build image and start the stack
|
||||||
working-directory: /opt/tanabata
|
working-directory: /opt/tanabata
|
||||||
# .env must already exist in DEPLOY_DIR on the host (secrets + DB mode).
|
# .env must already exist in DEPLOY_DIR on the host (secrets + DB mode).
|
||||||
|
|||||||
+6
-3
@@ -3,13 +3,16 @@
|
|||||||
Tanabata is deployed by a [Gitea Actions](https://docs.gitea.com/usage/actions/overview)
|
Tanabata is deployed by a [Gitea Actions](https://docs.gitea.com/usage/actions/overview)
|
||||||
workflow ([`.gitea/workflows/deploy.yml`](../.gitea/workflows/deploy.yml)) that
|
workflow ([`.gitea/workflows/deploy.yml`](../.gitea/workflows/deploy.yml)) that
|
||||||
runs on the **production host itself**. On every push to `master` it updates the
|
runs on the **production host itself**. On every push to `master` it updates the
|
||||||
git clone in `/opt/tanabata` and runs `docker compose up -d --build` there, so the
|
git clone in `/opt/tanabata`, runs the test suite (backend + frontend, in
|
||||||
image is built from the freshly-pushed code and the stack is restarted.
|
throwaway toolchain containers), and — only if it passes — runs
|
||||||
|
`docker compose up -d --build` there, so the image is built from the
|
||||||
|
freshly-pushed code and the stack is restarted.
|
||||||
|
|
||||||
```
|
```
|
||||||
push master ──> Gitea (container) ──> act_runner (host, "host" label)
|
push master ──> Gitea (container) ──> act_runner (host, "host" label)
|
||||||
│ git fetch + reset --hard (in /opt/tanabata)
|
│ git fetch + reset --hard (in /opt/tanabata)
|
||||||
└ docker compose up -d --build
|
│ run tests (go + node in containers; ephemeral Postgres)
|
||||||
|
└ docker compose up -d --build (only if tests pass)
|
||||||
```
|
```
|
||||||
|
|
||||||
The Gitea server runs in a container, but the **runner runs directly on the host**
|
The Gitea server runs in a container, but the **runner runs directly on the host**
|
||||||
|
|||||||
Reference in New Issue
Block a user