# CI: Maven build + unit tests on merge requests to main/master and on push to those branches. # CD: Build Docker image and push to GitHub Container Registry (ghcr.io) on push to main/master only. # Optional: SSH deploy when CI/CD variable ENABLE_SSH_DEPLOY=true and deploy secrets are set. # # CI/CD variables (Settings → CI/CD → Variables): # GHCR_USERNAME, GHCR_TOKEN — for docker push (GitHub user + PAT with write:packages) # ENABLE_SSH_DEPLOY = true (optional; omit or false to skip deploy job) # DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_SCRIPT — optional deploy variables: MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository" workflow: rules: # Merge requests whose target branch is main or master - if: $CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master") # Direct pushes to main or master - if: $CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master") # Manual pipeline (Run pipeline in UI) - if: $CI_PIPELINE_SOURCE == "web" cache: key: ${CI_COMMIT_REF_SLUG} paths: - .m2/repository stages: - test - publish - deploy build-and-test: stage: test image: maven:3.9.9-eclipse-temurin-21 script: - mvn -B -ntp verify docker-build-push: stage: publish needs: [build-and-test] rules: - if: $CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master") image: docker:24-cli services: - docker:24-dind variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" before_script: - until docker info; do sleep 1; done - echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USERNAME" --password-stdin script: - IMG=$(echo "$CI_PROJECT_PATH" | tr '[:upper:]' '[:lower:]') - docker build -t "ghcr.io/${IMG}:latest" -t "ghcr.io/${IMG}:${CI_COMMIT_SHA}" . - docker push "ghcr.io/${IMG}:latest" - docker push "ghcr.io/${IMG}:${CI_COMMIT_SHA}" deploy: stage: deploy needs: [docker-build-push] rules: - if: $CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master") && $ENABLE_SSH_DEPLOY == "true" image: alpine:3.20 before_script: - apk add --no-cache openssh-client - mkdir -p ~/.ssh - echo "$DEPLOY_SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa script: - ssh -o StrictHostKeyChecking=no "$DEPLOY_USER@$DEPLOY_HOST" "$DEPLOY_SCRIPT"