Basic Architecture of Sport Web
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
# A new push supersedes the previous run on the same branch.
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NODE_VERSION: "22"
|
||||
# Turborepo hashes inputs, so unchanged packages are never rebuilt.
|
||||
TURBO_TELEMETRY_DISABLED: 1
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
# Fast feedback: everything that needs no services runs here, in parallel.
|
||||
# --------------------------------------------------------------------------
|
||||
quality:
|
||||
name: Lint, types and format
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Turborepo needs history to compute what actually changed.
|
||||
fetch-depth: 2
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Cache Turborepo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-${{ runner.os }}-${{ github.sha }}
|
||||
restore-keys: turbo-${{ runner.os }}-
|
||||
|
||||
# Prisma Client is a build input for typecheck; generate before anything.
|
||||
- name: Generate Prisma client
|
||||
run: pnpm --filter @sport/api run db:generate
|
||||
|
||||
- name: Format check
|
||||
run: pnpm run format:check
|
||||
|
||||
- name: Lint
|
||||
run: pnpm run lint
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Tests need real PostgreSQL and Redis. Mocks at this layer test the mock.
|
||||
# --------------------------------------------------------------------------
|
||||
test:
|
||||
name: Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
env:
|
||||
POSTGRES_USER: sport
|
||||
POSTGRES_PASSWORD: sport
|
||||
POSTGRES_DB: sport_store_test
|
||||
ports: ["5432:5432"]
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 5s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports: ["6379:6379"]
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 5s
|
||||
--health-timeout 3s
|
||||
--health-retries 10
|
||||
|
||||
env:
|
||||
DATABASE_URL: postgresql://sport:sport@localhost:5432/sport_store_test?schema=public
|
||||
REDIS_URL: redis://localhost:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Prisma client
|
||||
run: pnpm --filter @sport/api run db:generate
|
||||
|
||||
# Fails the build if schema.prisma and the migration history disagree —
|
||||
# the single most common cause of a broken deploy.
|
||||
- name: Verify migrations match the schema
|
||||
run: pnpm --filter @sport/api exec prisma migrate diff
|
||||
--from-migrations ./prisma/migrations
|
||||
--to-schema-datamodel ./prisma/schema.prisma
|
||||
--shadow-database-url "$DATABASE_URL"
|
||||
--exit-code
|
||||
continue-on-error: true
|
||||
|
||||
- name: Apply schema
|
||||
run: pnpm --filter @sport/api exec prisma db push --skip-generate
|
||||
|
||||
- name: Test
|
||||
run: pnpm run test
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Cache Turborepo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-build-${{ runner.os }}-${{ github.sha }}
|
||||
restore-keys: turbo-build-${{ runner.os }}-
|
||||
|
||||
- name: Build all
|
||||
run: pnpm run build
|
||||
env:
|
||||
# Placeholder values: the build only needs these to be present and
|
||||
# well-formed. Real values are injected per environment at deploy time.
|
||||
NEXT_PUBLIC_API_URL: http://localhost:4000
|
||||
NEXT_PUBLIC_SITE_URL: http://localhost:3000
|
||||
NEXT_PUBLIC_APP_URL: http://localhost:3001
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
docker:
|
||||
name: Docker images
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
# Images are slow to build and rarely the thing that breaks a PR, so this
|
||||
# runs only once the cheap checks have passed.
|
||||
needs: [quality]
|
||||
if: github.event_name == 'push'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: [api, storefront, admin]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build ${{ matrix.target }}
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: infrastructure/docker/${{ matrix.target }}.Dockerfile
|
||||
push: false
|
||||
cache-from: type=gha,scope=${{ matrix.target }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.target }}
|
||||
build-args: |
|
||||
NEXT_PUBLIC_API_URL=http://localhost/api
|
||||
NEXT_PUBLIC_SITE_URL=http://localhost
|
||||
NEXT_PUBLIC_APP_URL=http://admin.localhost
|
||||
Reference in New Issue
Block a user