Root cause: de job-container (docker mode) heeft GEEN outbound internet naar GitHub, waardoor actions/checkout@v4 faalde met 'Unable to clone ... i/o timeout'. Oplossing: zowel check als deploy draaien nu op self-hosted (host) waar Node 26.8.1 + pnpm 11.25.0 geïnstalleerd zijn en internet beschikbaar is. Dit is de enige betrouwbare setup in deze omgeving. Runner is tevens hernoemd naar 'Epic runner'.
101 lines
3.2 KiB
YAML
101 lines
3.2 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main, master]
|
|
tags: ["v*"]
|
|
pull_request:
|
|
branches: [main, master]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
# ─────────────────────────────────────────────
|
|
# Lint, typecheck & unit tests
|
|
# Draait op de host (self-hosted) waar Node 26 +
|
|
# pnpm 11 geïnstalleerd zijn en internet beschikbaar is.
|
|
# De job-container (docker mode) heeft GEEN outbound
|
|
# internet, dus we draaien alles direct op de host.
|
|
# ─────────────────────────────────────────────
|
|
check:
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: ${{ gitea.repository }}
|
|
token: ${{ gitea.token }}
|
|
|
|
- name: Toolchain check
|
|
run: node scripts/check-node-toolchain.mjs
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile --jobs 1
|
|
|
|
- name: Lint
|
|
run: pnpm biome:lint
|
|
|
|
- name: Typecheck
|
|
run: pnpm typecheck
|
|
|
|
- name: Test
|
|
env:
|
|
SKIP_ENV_VALIDATION: 1
|
|
NODE_ENV: test
|
|
DATABASE_URL: "mysql://test:test@localhost:3306/test?charset=utf8mb4"
|
|
REDIS_URL: "redis://127.0.0.1:6379?connect_timeout=2"
|
|
AUTH_SECRET: "ci-test-secret-key-that-is-long-enough"
|
|
BCRYPT_ROUNDS: 4
|
|
run: pnpm test --maxWorkers=1
|
|
|
|
# ─────────────────────────────────────────────
|
|
# Docker build & deploy
|
|
# Draait op de host (self-hosted) zodat Docker
|
|
# toegang heeft tot de daemon en volumes.
|
|
# ─────────────────────────────────────────────
|
|
deploy:
|
|
needs: check
|
|
if: gitea.event_name == 'push' && (gitea.ref_name == 'main' || gitea.ref_name == 'master')
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: ${{ gitea.repository }}
|
|
token: ${{ gitea.token }}
|
|
|
|
- name: Build image
|
|
run: |
|
|
DOCKER_BUILDKIT=1 docker build \
|
|
--build-arg NODE_OPTIONS="--max-old-space-size=1536" \
|
|
--cache-from epicnext-cms:latest \
|
|
-t epicnext-cms:latest .
|
|
|
|
- name: Deploy container
|
|
run: |
|
|
docker stop epicnext-cms-app 2>/dev/null || true
|
|
docker rm epicnext-cms-app 2>/dev/null || true
|
|
|
|
docker run -d \
|
|
--name epicnext-cms-app \
|
|
--restart always \
|
|
--net=host \
|
|
epicnext-cms:latest
|
|
|
|
docker image prune -f
|
|
|
|
- name: Health check
|
|
run: |
|
|
for i in $(seq 1 30); do
|
|
if curl -sf --max-time 5 http://127.0.0.1:3002/api/health \
|
|
| grep -q '"database":true'; then
|
|
echo "Deploy OK"
|
|
exit 0
|
|
fi
|
|
echo "Waiting... ($i/30)"
|
|
sleep 3
|
|
done
|
|
|
|
echo "ERROR: Health check failed" >&2
|
|
docker logs epicnext-cms-app --tail 50 >&2 || true
|
|
exit 1
|