From 5a66742aaefb4a53febe46c0cb2018571c1c8de7 Mon Sep 17 00:00:00 2001 From: Magzhan Zhumabayev Date: Sat, 28 Mar 2026 15:26:38 +0500 Subject: [PATCH] . --- .gitlab-ci.yml | 149 ++++++++++++++++++++----------------------------- 1 file changed, 61 insertions(+), 88 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d6fe1df..c38c427 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,97 +1,70 @@ -# CI: Maven build + unit tests on every push/PR to main or master. -# CD: Build Docker image and push to GitHub Container Registry (ghcr.io) on push to main/master. -# Optional: SSH deploy when repository variable ENABLE_SSH_DEPLOY=true and deploy secrets are set. +# 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. # -# Repository variables (Settings → Secrets and variables → Actions → Variables): +# 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) -# -# Optional deploy secrets (Settings → Secrets and variables → Actions → Secrets): -# DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_SCRIPT -# DEPLOY_SCRIPT: multiline shell to run on the server (e.g. cd /opt/app && docker compose pull && docker compose up -d) -# -# Pull the image as: ghcr.io//:latest or : +# DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_SCRIPT — optional deploy -name: CI/CD +variables: + MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository" -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: +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" -permissions: - contents: read - packages: write +cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - .m2/repository -env: - JAVA_VERSION: "21" +stages: + - test + - publish + - deploy -jobs: - build-and-test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 +build-and-test: + stage: test + image: maven:3.9.9-eclipse-temurin-21 + script: + - mvn -B -ntp verify - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: maven +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}" - # Unit tests only; @EnabledIfEnvironmentVariable(RUN_INTEGRATION_TESTS) tests stay skipped unless you add a separate job with secrets. - - name: Maven verify - run: mvn -B -ntp verify - - docker-build-push: - needs: build-and-test - if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Image name (lowercase for GHCR) - id: image - run: | - IMG=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') - echo "name=ghcr.io/${IMG}" >> "$GITHUB_OUTPUT" - - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - push: true - tags: | - ${{ steps.image.outputs.name }}:latest - ${{ steps.image.outputs.name }}:${{ github.sha }} - cache-from: type=gha - cache-to: type=gha,mode=max - - deploy: - needs: docker-build-push - # Set ENABLE_SSH_DEPLOY=true in repo Variables to run this job; otherwise skipped. - if: vars.ENABLE_SSH_DEPLOY == 'true' - runs-on: ubuntu-latest - # Optional: uncomment for manual approval gates (create "production" in Environments first). - # environment: production - steps: - - name: Deploy over SSH - uses: appleboy/ssh-action@v1.2.2 - with: - host: ${{ secrets.DEPLOY_HOST }} - username: ${{ secrets.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_SSH_KEY }} - script: ${{ secrets.DEPLOY_SCRIPT }} +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"