stages: - build - test - docker - deploy variables: DOCKER_IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA} DOCKER_IMAGE_LATEST: ${CI_REGISTRY_IMAGE}:latest DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "" # Build stage - compile Java and frontend build:java: stage: build image: eclipse-temurin:21-jdk before_script: - apt-get update && apt-get install -y curl - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - - apt-get install -y nodejs script: - chmod +x ./gradlew - ./gradlew clean build -x test --build-cache artifacts: paths: - backend/build/libs/ - frontend/dist/ expire_in: 1 day cache: key: ${CI_COMMIT_REF_SLUG} paths: - .gradle/ - frontend/node_modules/ # Test stage - run unit and integration tests test:unit: stage: test image: eclipse-temurin:21-jdk needs: - build:java script: - chmod +x ./gradlew - ./gradlew test --build-cache artifacts: reports: junit: backend/build/test-results/test/**/*.xml paths: - backend/build/reports/ expire_in: 30 days cache: key: ${CI_COMMIT_REF_SLUG} paths: - .gradle/ # Integration tests with Postgres test:integration: stage: test image: eclipse-temurin:21-jdk services: - postgres:16-alpine variables: POSTGRES_DB: mtgsearch_test POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/mtgsearch_test script: - chmod +x ./gradlew - ./gradlew integrationTest --build-cache only: - main - merge_requests cache: key: ${CI_COMMIT_REF_SLUG} paths: - .gradle/ # Code quality checks test:quality: stage: test image: eclipse-temurin:21-jdk script: - chmod +x ./gradlew - ./gradlew check -x test allow_failure: true only: - merge_requests # Docker build and push docker:build: stage: docker image: docker:latest services: - docker:dind needs: - build:java before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -t $DOCKER_IMAGE . - docker push $DOCKER_IMAGE - docker tag $DOCKER_IMAGE $DOCKER_IMAGE_LATEST - docker push $DOCKER_IMAGE_LATEST only: - main - develop - tags # Deploy to staging (example - configure for your environment) deploy:staging: stage: deploy image: alpine:latest before_script: - apk add --no-cache curl jq script: - echo "Deploying to staging environment..." - | curl -X POST "${STAGING_DEPLOY_WEBHOOK}" \ -H "Content-Type: application/json" \ -d '{"image":"'"${DOCKER_IMAGE}"'"}' environment: name: staging url: https://staging-mtgsearch.example.com only: - develop when: manual # Deploy to production (example - configure for your environment) deploy:production: stage: deploy image: alpine:latest before_script: - apk add --no-cache curl jq script: - echo "Deploying to production..." - | curl -X POST "${PROD_DEPLOY_WEBHOOK}" \ -H "Content-Type: application/json" \ -d '{"image":"'"${DOCKER_IMAGE}"'"}' environment: name: production url: https://mtgsearch.example.com only: - tags - main when: manual