861e14503b
## Summary - Fix `isProductionDatabase()` to allow CI database (`euchre_camp_ci`) - Add database schema reset before CI test runs - Create `global.teardown.ts` for cleanup (CI: full reset, dev/prod: selective cleanup) - Add `acceptance-tests` job to PR workflow with CI database - Create `sync-prod-to-dev.js` script for one-way prod→dev sync - Add `just` recipes: `sync-dev`, `test-prod`, `reset-ci-db` - Store credentials in `.credentials` (gitignored) with unique CI user ## Testing Verified against CI database: - Schema reset works - Migrations apply correctly - Test users created successfully - 219 tests pass (slow but working) ## Next Steps - Set `CI_DATABASE_URL` as Gitea repository variable Reviewed-on: #35 Co-authored-by: David Gwilliam <dhgwilliam@gmail.com> Co-committed-by: David Gwilliam <dhgwilliam@gmail.com>
311 lines
9.0 KiB
Makefile
311 lines
9.0 KiB
Makefile
# justfile for Euchre Camp
|
|
# Automates development, testing, and deployment tasks.
|
|
# Designed for CI/CD pipelines and local development.
|
|
|
|
# --- Configuration ---
|
|
set dotenv-load
|
|
set positional-arguments
|
|
|
|
# Project name
|
|
PROJECT := "euchre-camp"
|
|
|
|
# Docker registry
|
|
REGISTRY := "docker.notsosm.art"
|
|
IMAGE_TAG := "latest"
|
|
|
|
# Get git commit hash (short version)
|
|
GIT_COMMIT := `git rev-parse --short HEAD`
|
|
|
|
# Image tag with git commit (use same format as GIT_COMMIT)
|
|
IMAGE_TAG_COMMIT := `git rev-parse --short HEAD`
|
|
|
|
# --- Variables ---
|
|
# Database
|
|
DB_CONTAINER := "euchre-camp-postgres"
|
|
DATABASE_URL := env_var_or_default("DATABASE_URL", "")
|
|
|
|
# --- Setup & Installation ---
|
|
|
|
# Install dependencies and setup environment
|
|
setup:
|
|
@echo "Installing dependencies..."
|
|
npm install
|
|
@echo "Setting up database..."
|
|
npm run db:setup-dev
|
|
@echo "Generating Prisma client..."
|
|
npx prisma generate
|
|
|
|
# --- Development ---
|
|
|
|
# Start the development server
|
|
dev:
|
|
npm run dev
|
|
|
|
# Lint the codebase
|
|
lint:
|
|
npm run lint
|
|
|
|
# Type check the codebase
|
|
typecheck:
|
|
npx tsc --noEmit
|
|
|
|
# Format code (if prettier is available, otherwise just lint)
|
|
format:
|
|
npx prettier --write .
|
|
|
|
# --- Testing ---
|
|
|
|
# Run all tests (unit + acceptance)
|
|
test: test-unit test-acceptance
|
|
|
|
# Run unit tests
|
|
test-unit:
|
|
npm run test:run
|
|
|
|
# Run acceptance tests (Playwright)
|
|
test-acceptance:
|
|
@echo "Running acceptance tests..."
|
|
npm run test:acceptance
|
|
|
|
# Run Cucumber e2e tests
|
|
test-cucumber:
|
|
@echo "Clearing Next.js cache..."
|
|
rm -rf .next/
|
|
@echo "Running Cucumber e2e tests..."
|
|
npm run test:acceptance:cucumber
|
|
|
|
# Run Cucumber e2e tests against production build
|
|
test-cucumber-prod:
|
|
@echo "Clearing Next.js cache..."
|
|
rm -rf .next/
|
|
@echo "Building application for production..."
|
|
bun run build
|
|
@echo "Starting production server in background..."
|
|
bun run start > /tmp/next-prod.log 2>&1 &
|
|
SERVER_PID=$$!
|
|
@echo "Waiting for server to be ready..."
|
|
sleep 15
|
|
@echo "Running Cucumber e2e tests against production build..."
|
|
npm run test:acceptance:cucumber || true
|
|
@echo "Stopping production server..."
|
|
kill $$SERVER_PID 2>/dev/null || true
|
|
@echo "Tests completed."
|
|
|
|
# Run database migrations (Prisma)
|
|
migrate:
|
|
npx prisma migrate dev
|
|
|
|
# Seed the database
|
|
seed:
|
|
npm run db:seed
|
|
|
|
# --- Docker ---
|
|
|
|
# Build the Docker image (standard build)
|
|
docker-build:
|
|
@echo "Building Docker image {{PROJECT}}:{{IMAGE_TAG}}..."
|
|
docker build --build-arg GIT_COMMIT={{GIT_COMMIT}} -t {{PROJECT}}:{{IMAGE_TAG}} .
|
|
|
|
docker-build-commit:
|
|
@echo "Building Docker image {{PROJECT}}:{{IMAGE_TAG_COMMIT}}..."
|
|
docker build --build-arg GIT_COMMIT={{GIT_COMMIT}} -t {{PROJECT}}:{{IMAGE_TAG_COMMIT}} .
|
|
|
|
# Build and tag with both latest and commit hash
|
|
docker-build-full: docker-build docker-build-commit
|
|
|
|
# Fast rebuild using Docker BuildKit cache
|
|
docker-rebuild-fast:
|
|
@echo "Fast rebuilding Docker image {{PROJECT}}:{{IMAGE_TAG}}..."
|
|
DOCKER_BUILDKIT=1 docker build \
|
|
--build-arg GIT_COMMIT={{GIT_COMMIT}} \
|
|
--cache-from={{PROJECT}}:{{IMAGE_TAG}} \
|
|
-t {{PROJECT}}:{{IMAGE_TAG}} \
|
|
-t {{PROJECT}}:{{IMAGE_TAG_COMMIT}} \
|
|
.
|
|
|
|
# Run the Docker container locally
|
|
docker-run: docker-build
|
|
@echo "Running Docker container {{PROJECT}}..."
|
|
docker run -d -p 3000:3000 --name {{PROJECT}} {{PROJECT}}:{{IMAGE_TAG}}
|
|
|
|
# Stop and remove the Docker container
|
|
docker-stop:
|
|
@echo "Stopping Docker container {{PROJECT}}..."
|
|
docker stop {{PROJECT}} || true
|
|
docker rm {{PROJECT}} || true
|
|
|
|
# Clean up Docker images and containers
|
|
docker-clean: docker-stop
|
|
@echo "Removing Docker image {{PROJECT}}:{{IMAGE_TAG}}..."
|
|
docker rmi {{PROJECT}}:{{IMAGE_TAG}} || true
|
|
|
|
# --- Deployment ---
|
|
|
|
# Tag image for registry
|
|
docker-tag:
|
|
@echo "Tagging image for registry..."
|
|
docker tag {{PROJECT}}:{{IMAGE_TAG}} {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG}} || true
|
|
docker tag {{PROJECT}}:{{IMAGE_TAG_COMMIT}} {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG_COMMIT}} || true
|
|
@echo "Tagged {{PROJECT}}:{{IMAGE_TAG}} -> {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG}}"
|
|
@echo "Tagged {{PROJECT}}:{{IMAGE_TAG_COMMIT}} -> {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG_COMMIT}}"
|
|
|
|
# Push image to registry (builds, tags, and pushes)
|
|
docker-push: docker-build-full
|
|
@echo "Tagging images for registry..."
|
|
docker tag {{PROJECT}}:{{IMAGE_TAG}} {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG}} || true
|
|
docker tag {{PROJECT}}:{{IMAGE_TAG_COMMIT}} {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG_COMMIT}} || true
|
|
@echo "Pushing images to {{REGISTRY}}..."
|
|
docker push {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG}}
|
|
docker push {{REGISTRY}}/{{PROJECT}}:{{IMAGE_TAG_COMMIT}}
|
|
|
|
# --- CI/CD Pipeline Simulation ---
|
|
|
|
# Run full CI pipeline locally (lint, test, build)
|
|
ci: lint typecheck test-unit test-acceptance docker-build
|
|
@echo "CI Pipeline completed successfully!"
|
|
|
|
# PR validation (what runs on pull requests)
|
|
pr-validate: lint typecheck test-unit test-acceptance
|
|
@echo "PR validation completed successfully!"
|
|
|
|
# --- Utilities ---
|
|
|
|
# Show help information
|
|
help:
|
|
@just --list
|
|
|
|
# Clean up project (remove node_modules, build artifacts)
|
|
clean:
|
|
@echo "Cleaning project..."
|
|
rm -rf node_modules .next dist .turbo
|
|
|
|
# Generate Prisma client
|
|
prisma-generate:
|
|
npx prisma generate
|
|
|
|
# Reset development database
|
|
db-reset-dev:
|
|
npm run db:reset-dev
|
|
|
|
# Setup development database
|
|
db-setup-dev:
|
|
npm run db:setup-dev
|
|
|
|
# Clean production database (remove test records)
|
|
db-clean-prod:
|
|
npm run db:cleanup-prod
|
|
|
|
# Check production database for test records
|
|
db-check-prod:
|
|
npm run db:check-prod
|
|
|
|
# Create admin user
|
|
admin-create:
|
|
node scripts/create-admin-via-api.js
|
|
|
|
# List all users
|
|
users-list:
|
|
node scripts/list-users.js
|
|
|
|
# Update admin password
|
|
admin-update-password:
|
|
node scripts/update-admin-password.js
|
|
|
|
# Bump version
|
|
version-bump-patch:
|
|
npm run version:patch
|
|
|
|
version-bump-minor:
|
|
npm run version:minor
|
|
|
|
version-bump-major:
|
|
npm run version:major
|
|
|
|
# Docker Compose shortcuts
|
|
docker-up:
|
|
npm run docker:up
|
|
|
|
docker-down:
|
|
npm run docker:down
|
|
|
|
docker-logs:
|
|
npm run docker:logs
|
|
|
|
# View workflow status
|
|
workflow-status:
|
|
@echo "Current workflows in .gitea/workflows/:"
|
|
ls -la .gitea/workflows/
|
|
@echo ""
|
|
@echo "PR Workflow: Runs unit + acceptance tests on pull requests"
|
|
@echo "Test Workflow: Runs unit tests on all branch pushes"
|
|
@echo "Release Workflow: Runs on main branch pushes (version bump + Docker build)"
|
|
|
|
# --- Production Deployment ---
|
|
|
|
# Deploy a specific version to production (human gate)
|
|
# Usage: just deploy-prod v0.1.21
|
|
deploy-prod version:
|
|
@echo "Deploying {{version}} to production..."
|
|
@echo "This requires the image to already be pushed to the registry."
|
|
@echo ""
|
|
@read -p "Have you verified this version works in dev? (y/N) " confirm; \
|
|
if [ "$$confirm" != "y" ]; then \
|
|
echo "Cancelled. Please verify in dev first."; \
|
|
exit 1; \
|
|
fi
|
|
cd /apps/youthful_simon && \
|
|
sed -i "s|image: docker.notsosm.art/euchre-camp:[a-zA-Z0-9.-]*|image: docker.notsosm.art/euchre-camp:{{version}}|" docker-compose.yml && \
|
|
sed -i "s|image: euchre-camp/euchre-camp:[a-zA-Z0-9.-]*|image: docker.notsosm.art/euchre-camp:{{version}}|" docker-compose.yml && \
|
|
docker compose pull app && \
|
|
docker compose up -d app && \
|
|
echo "Waiting for production site to be healthy..." && \
|
|
for i in {1..30}; do \
|
|
if curl -sf https://euchre.notsosm.art/api/health > /dev/null 2>&1; then \
|
|
echo "✅ Production successfully deployed with version {{version}}"; \
|
|
exit 0; \
|
|
fi; \
|
|
sleep 0.5; \
|
|
done && \
|
|
echo "❌ Production deployment failed - health check timed out"; \
|
|
docker compose logs app; \
|
|
exit 1
|
|
|
|
# Show current deployment status across all environments
|
|
status:
|
|
@echo "=== EuchreCamp Deployment Status ==="
|
|
@echo ""
|
|
@echo "CI Site (euchre-camp-ci):"
|
|
@grep "image:" /apps/euchre_camp_ci/docker-compose.yml | head -1
|
|
@echo ""
|
|
@echo "Dev Site (euchre-camp-dev):"
|
|
@grep "image:" /apps/intelligent_silasak/docker-compose.yml | head -1
|
|
@echo ""
|
|
@echo "Prod Site (euchre-camp):"
|
|
@grep "image:" /apps/youthful_simon/docker-compose.yml | head -1
|
|
@echo ""
|
|
|
|
# --- SDLC Database Operations ---
|
|
|
|
# Sync production data to development database (manual operation)
|
|
sync-dev:
|
|
@echo "Syncing production data to development database..."
|
|
node scripts/sync-prod-to-dev.js
|
|
|
|
# Run acceptance tests against production database (opt-in, manual)
|
|
test-prod:
|
|
@echo "⚠️ WARNING: This will run tests against the PRODUCTION database!"
|
|
@echo " All test records will be cleaned up after the run."
|
|
@echo ""
|
|
@read -p "Are you sure you want to continue? (y/N) " confirm; \
|
|
if [ "$$confirm" != "y" ]; then \
|
|
echo "Cancelled."; \
|
|
else \
|
|
DATABASE_URL="$$PROD_DATABASE_URL" bun test:acceptance; \
|
|
fi
|
|
|
|
# Reset CI database (for local CI testing)
|
|
reset-ci-db:
|
|
@echo "Resetting CI database..."
|
|
psql "$CI_DATABASE_URL" -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
|
|
bunx prisma migrate deploy
|