name: CI on: push: branches: [ main, master ] pull_request: branches: [ main, master ] env: DOCKER_BUILDKIT: 1 COMPOSE_DOCKER_CLI_BUILD: 1 COMPOSE_FILE: docker-compose.yml COMPOSE_PROJECT_NAME: ci jobs: backend-tests: runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Cache buildx layers uses: actions/cache@v4 with: path: ~/.cache/buildx key: ${{ runner.os }}-buildx-${{ hashFiles('backend/package.json', 'frontend/package.json', 'package-lock.json') }} restore-keys: | ${{ runner.os }}-buildx- - name: Hydrate secrets and backend env shell: bash env: POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_CLIENT_SECRET }} GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} run: | set -euo pipefail mkdir -p .ci/secrets : "${POSTGRES_PASSWORD:=$(cat secrets/app/postgres-password.txt 2>/dev/null || echo 'localdev123')}" : "${AUTH0_CLIENT_SECRET:=$(cat secrets/app/auth0-client-secret.txt 2>/dev/null || echo 'ci-auth0-secret')}" : "${GOOGLE_MAPS_API_KEY:=$(cat secrets/app/google-maps-api-key.txt 2>/dev/null || echo 'ci-google-maps-key')}" mkdir -p secrets/app printf '%s' "$POSTGRES_PASSWORD" > secrets/app/postgres-password.txt printf '%s' "$AUTH0_CLIENT_SECRET" > secrets/app/auth0-client-secret.txt printf '%s' "$GOOGLE_MAPS_API_KEY" > secrets/app/google-maps-api-key.txt printf '%s' "$POSTGRES_PASSWORD" > .ci/secrets/postgres-password printf '%s' "$AUTH0_CLIENT_SECRET" > .ci/secrets/auth0-client-secret printf '%s' "$GOOGLE_MAPS_API_KEY" > .ci/secrets/google-maps-api-key cat < .ci/backend.env NODE_ENV=test CI=true CONFIG_PATH=/ci/config/app/ci.yml SECRETS_DIR=/ci/secrets DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@mvp-postgres:5432/motovaultpro DB_HOST=mvp-postgres DB_USER=postgres DB_PASSWORD=${POSTGRES_PASSWORD} DB_DATABASE=motovaultpro DB_PORT=5432 REDIS_HOST=mvp-redis REDIS_URL=redis://mvp-redis:6379 MINIO_ENDPOINT=http://minio:9000 GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY} AUTH0_CLIENT_SECRET=${AUTH0_CLIENT_SECRET} EOF_ENV - name: Build application images run: docker compose build mvp-backend mvp-frontend - name: Start database dependencies run: docker compose up -d mvp-postgres mvp-redis - name: Wait for dependencies shell: bash run: | set -euo pipefail for _ in $(seq 1 20); do if docker compose exec -T mvp-postgres pg_isready -U postgres >/dev/null 2>&1; then break fi sleep 3 done docker compose exec -T mvp-postgres pg_isready -U postgres docker compose exec -T mvp-redis redis-cli ping - name: Build backend builder image run: docker build --target builder -t motovaultpro-backend-builder backend - name: Lint backend run: | docker run --rm \ --network ${COMPOSE_PROJECT_NAME}_default \ --env-file .ci/backend.env \ -v ${{ github.workspace }}/config/app/ci.yml:/ci/config/app/ci.yml:ro \ -v ${{ github.workspace }}/.ci/secrets:/ci/secrets:ro \ motovaultpro-backend-builder npm run lint - name: Run backend tests env: CI: true run: | docker run --rm \ --network ${COMPOSE_PROJECT_NAME}_default \ --env-file .ci/backend.env \ -v ${{ github.workspace }}/config/app/ci.yml:/ci/config/app/ci.yml:ro \ -v ${{ github.workspace }}/.ci/secrets:/ci/secrets:ro \ motovaultpro-backend-builder npm test -- --runInBand - name: Tear down containers if: always() run: docker compose down -v frontend-tests: runs-on: ubuntu-latest timeout-minutes: 20 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Cache buildx layers uses: actions/cache@v4 with: path: ~/.cache/buildx key: ${{ runner.os }}-buildx-${{ hashFiles('frontend/package.json', 'package-lock.json') }} restore-keys: | ${{ runner.os }}-buildx- - name: Prepare frontend env shell: bash run: | set -euo pipefail mkdir -p .ci cat < .ci/frontend.env CI=true VITE_AUTH0_DOMAIN=motovaultpro.us.auth0.com VITE_AUTH0_CLIENT_ID=yspR8zdnSxmV8wFIghHynQ08iXAPoQJ3 VITE_AUTH0_AUDIENCE=https://api.motovaultpro.com VITE_API_BASE_URL=/api EOF_ENV - name: Build frontend image run: docker compose build mvp-frontend - name: Build frontend dependencies image run: docker build --target deps -t motovaultpro-frontend-deps frontend - name: Lint frontend run: | docker run --rm \ --env-file .ci/frontend.env \ motovaultpro-frontend-deps npm run lint - name: Run frontend tests env: CI: true run: | docker run --rm \ --env-file .ci/frontend.env \ motovaultpro-frontend-deps npm test -- --runInBand