Files
reactbin/.gitea/workflows/pipeline.yml
agatha e4a77fdea3 CI: Move Postgres to manual docker run with shared network namespace
Service containers bind ports to the host, not to localhost inside the
job container. Start both Postgres and MinIO manually with
--network container:$(hostname) so they share the job container's
network namespace and are reachable on localhost. Use docker exec for
pg_isready to avoid depending on postgresql-client in the runner image.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:52:14 +00:00

229 lines
6.9 KiB
YAML

name: Pipeline
on:
push:
branches: [master]
tags: ['v*']
pull_request:
branches: [master]
jobs:
# ── UI ────────────────────────────────────────────────────────────────────────
ui-test:
name: UI Tests
runs-on: ubuntu-latest
container:
image: node:22-bullseye
steps:
- uses: actions/checkout@v4
- name: Install Firefox
run: apt-get update -qq && apt-get install -y --no-install-recommends firefox-esr
- name: Cache node_modules
uses: actions/cache@v3
with:
path: ui/node_modules
key: npm-${{ hashFiles('ui/package-lock.json') }}
restore-keys: npm-
- name: Install dependencies
run: npm ci
working-directory: ui
- name: Run tests
run: FIREFOX_BIN=/usr/bin/firefox-esr npx ng test --watch=false
working-directory: ui
ui-lint:
name: UI Lint
runs-on: ubuntu-latest
container:
image: node:22-bullseye
steps:
- uses: actions/checkout@v4
- name: Cache node_modules
uses: actions/cache@v3
with:
path: ui/node_modules
key: npm-${{ hashFiles('ui/package-lock.json') }}
restore-keys: npm-
- name: Install dependencies
run: npm ci
working-directory: ui
- name: Run ESLint
run: npm run lint
working-directory: ui
# ── API ───────────────────────────────────────────────────────────────────────
api-unit:
name: API Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Cache uv store
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: uv-${{ hashFiles('api/uv.lock') }}
restore-keys: uv-
- name: Install dependencies
run: uv sync --group dev
working-directory: api
- name: Run unit tests
run: uv run pytest tests/unit/ -q
working-directory: api
env:
DATABASE_URL: postgresql+asyncpg://u:p@localhost/db
S3_ENDPOINT_URL: http://localhost:9000
S3_BUCKET_NAME: test
S3_ACCESS_KEY_ID: key
S3_SECRET_ACCESS_KEY: secret
S3_REGION: us-east-1
API_BASE_URL: http://localhost:8000
JWT_SECRET_KEY: test-secret
OWNER_USERNAME: testowner
OWNER_PASSWORD: testpass
api-lint:
name: API Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Ruff
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uvx ruff check .
working-directory: api
api-integration:
name: API Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start services
run: |
docker run -d --name ci-postgres \
--network container:$(hostname) \
-e POSTGRES_USER=reactbin \
-e POSTGRES_PASSWORD=reactbin \
-e POSTGRES_DB=reactbin_test \
postgres:16
docker run -d --name ci-minio \
--network container:$(hostname) \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
quay.io/minio/minio server /data
- name: Wait for services and create bucket
run: |
until docker exec ci-postgres pg_isready -U reactbin; do sleep 2; done
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc -o /tmp/mc
chmod +x /tmp/mc
until /tmp/mc alias set local http://localhost:9000 minioadmin minioadmin; do sleep 2; done
/tmp/mc mb local/reactbin-test
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Cache uv store
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: uv-${{ hashFiles('api/uv.lock') }}
restore-keys: uv-
- name: Install dependencies
run: uv sync --group dev
working-directory: api
- name: Run integration tests
run: uv run pytest tests/integration/ -q
working-directory: api
env:
TEST_DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@localhost/reactbin_test
DATABASE_URL: postgresql+asyncpg://reactbin:reactbin@localhost/reactbin_test
S3_ENDPOINT_URL: http://localhost:9000
S3_BUCKET_NAME: reactbin-test
S3_ACCESS_KEY_ID: minioadmin
S3_SECRET_ACCESS_KEY: minioadmin
S3_REGION: us-east-1
API_BASE_URL: http://localhost:8000
JWT_SECRET_KEY: test-secret
OWNER_USERNAME: testowner
OWNER_PASSWORD: testpass
- name: Stop services
if: always()
run: docker stop ci-postgres ci-minio || true && docker rm ci-postgres ci-minio || true
# ── Image builds (tag-only, gated on all jobs) ────────────────────────────────
build-api:
name: Build & Push API Image
runs-on: ubuntu-latest
needs: [ui-test, ui-lint, api-unit, api-lint, api-integration]
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ vars.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: ./api
file: ./api/Dockerfile.prod
push: true
tags: |
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-api:${{ github.ref_name }}
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-api:latest
build-ui:
name: Build & Push UI Image
runs-on: ubuntu-latest
needs: [ui-test, ui-lint, api-unit, api-lint, api-integration]
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ vars.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: ./ui
file: ./ui/Dockerfile.prod
push: true
tags: |
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:${{ github.ref_name }}
${{ vars.REGISTRY }}/${{ vars.REPOSITORY }}/reactbin-ui:latest