spomeni/.github/workflows/ci.yml
dimitar 636e9e5eb4 chore(devops): Phase 5 — Dockerfile, .dockerignore, CI, deploy cleanup, error/loading UI
DevOps and DX consolidation pass.

Dockerfile (production):
- Replaced 'COPY . .' at the builder stage with explicit copies of
  package.json, prisma/, src/, public/, and the config files. The
  original 'COPY . .' would ship .env (with live secrets) and the
  .next/ cache into the builder context; .dockerignore also covers
  this now but keep the explicit list as a second line of defence.
- Removed the runtime stage's 'COPY --from=builder /app/node_modules
  ./node_modules'. This previously duplicated the entire node_modules
  into the runner and negated the whole benefit of
  'output: standalone'. Now we copy only the Prisma generated
  client (.prisma + @prisma). Expected image size reduction: ~1GB.
- Added a HEALTHCHECK polling GET /api/check-subdomain?slug=__health
  every 30s (the route already exists and is cheap).
- Added wget for the health probe (alpine doesn't ship wget by
  default).

.dockerignore (new):
- Excludes .next/, .next_old/, .git/, docs/, nginx/, *.md, .env *,
  coverage, *.tsbuildinfo, tt.md, and the Docker/compose files
  themselves from the build context.

CI (.github/workflows/ci.yml, new):
- Runs on push and PR to main/admin.
- Steps: install, prisma generate, typecheck, lint (continue-on-error
  since the project's eslint-config-next pulls a broken ESM resolution
  at the moment — left soft so CI doesn't block on it),
  tests, build.
- Provides a full env block of placeholder secrets so the build does
  not fail at the ADMIN_SESSION_SECRET / Clerk env presence checks
  baked into the config and middleware.

Repo cleanup:
- Untracked .next_old/ (24 stale webpack hot-update files from an old
  dev session) — the physical files remain on disk because they are
  root-owned (likely from an earlier Docker bind-mount) and cannot be
  removed without sudo, but they're now untracked and ignored.
- .gitignore: the bogus 'certbot/.next_old/' line is replaced with
  '/.next_old/' so the directory stops being tracked and any future
  artifacts there don't reappear.
- Deleted nginx/conf.d/* (Traefik is the actual deploy per project
  decision). Traefik labels in docker-compose.yaml remain.

App DX:
- layout.tsx: set metadataBase from APP_URL (was unset — affected
  Open Graph absolute-URL generation) and switched title to a
  fallback + template so per-route titles render as 'X · СпоменQR'.
- src/app/loading.tsx (new): root-level spinning loader so users get
  immediate feedback on slow server-rendered routes.
- src/app/error.tsx (new): client error boundary with a 'Обиди се
  повторно' reset button, previously missing entirely — runtime errors
  fell through to not-found.

package.json: 'typecheck' script added (for local use + CI).

.gitignore cleanups: '/.next_old/' replaces the accidental
'certbot/.next_old/' glob.
2026-08-02 13:20:10 +02:00

55 lines
1.3 KiB
YAML

name: CI
on:
push:
branches: [main, admin]
pull_request:
branches: [main, admin]
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
ADMIN_SESSION_SECRET: ${{ secrets.ADMIN_SESSION_SECRET || '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' }}
SUPER_ADMIN_USERNAME: super
SUPER_ADMIN_PASSWORD_HASH: ${{ secrets.SUPER_ADMIN_PASSWORD_HASH || '$2a$12$abcdefghijklmnopqrstuv' }}
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/ci
NEXT_PUBLIC_APP_DOMAIN: ci.test
NEXT_PUBLIC_APP_URL: https://ci.test
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: pk_test_placeholder
CLERK_SECRET_KEY: sk_test_placeholder
S3_ENDPOINT: https://s3.example.com
S3_REGION: eu-2
S3_ACCESS_KEY_ID: placeholder
S3_SECRET_ACCESS_KEY: placeholder
S3_BUCKET_NAME: ci-bucket
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Generate Prisma client
run: npx prisma generate
- name: Typecheck
run: npm run typecheck
- name: Lint
run: npm run lint
continue-on-error: true
- name: Tests
run: npm test
- name: Build
run: npm run build