From 80d05026088b74765afb03560373d95f6194dcc8 Mon Sep 17 00:00:00 2001 From: Dion Moustos Date: Thu, 7 May 2026 18:50:15 +0930 Subject: [PATCH] more --- .gitlab-ci.yml | 174 ------------------------------- Jenkinsfile | 271 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+), 174 deletions(-) delete mode 100644 .gitlab-ci.yml create mode 100644 Jenkinsfile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index c63cb8d..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,174 +0,0 @@ -stages: - - build - - build-sonar - - 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: "" - SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" - GIT_DEPTH: "0" - -# Build stage - compile Java and frontend -build:java: - stage: build - image: eclipse-temurin:21-jdk - services: - - postgres:17-alpine - variables: - POSTGRES_DB: mtgsearch_build - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - DB_URL: jdbc:postgresql://postgres:5432/mtgsearch_build - DB_USER: postgres - DB_PASSWORD: postgres - 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:17-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 - -build-sonar: - stage: build-sonar - image: gradle:9.4.1-jdk21-jammy - cache: - policy: pull-push - key: "sonar-cache-$CI_COMMIT_REF_SLUG" - paths: - - "${SONAR_USER_HOME}/cache" - - sonar-scanner/ - script: gradle sonar - allow_failure: true - rules: - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - - if: $CI_COMMIT_BRANCH == 'master' - - if: $CI_COMMIT_BRANCH == 'main' - - if: $CI_COMMIT_BRANCH == 'develop' - -# 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 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..a9ad70e --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,271 @@ +pipeline { + agent any + + options { + timestamps() + timeout(time: 1, unit: 'HOURS') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + parameters { + booleanParam(name: 'DEPLOY_TO_STAGING', defaultValue: false, description: 'Deploy to staging') + booleanParam(name: 'DEPLOY_TO_PRODUCTION', defaultValue: false, description: 'Deploy to production') + } + + environment { + // Docker registry configuration + REGISTRY = credentials('docker-registry-url') + REGISTRY_USER = credentials('docker-registry-user') + REGISTRY_PASSWORD = credentials('docker-registry-password') + DOCKER_IMAGE = "${REGISTRY}/${GIT_COMMIT.take(8)}" + DOCKER_IMAGE_LATEST = "${REGISTRY}:latest" + + // Database configuration for builds + DB_URL = "jdbc:postgresql://postgres:5432/mtgsearch_build" + DB_USER = "postgres" + DB_PASSWORD = "postgres" + POSTGRES_DB = "mtgsearch_build" + + // SonarQube configuration + SONAR_USER_HOME = "${WORKSPACE}/.sonar" + GIT_DEPTH = "0" + + // Build cache + GRADLE_USER_HOME = "${WORKSPACE}/.gradle" + } + + stages { + stage('Build Java & Frontend') { + agent { + docker { + image 'eclipse-temurin:21-jdk' + args '--network=host' + } + } + steps { + script { + echo "Building Java and Frontend..." + } + sh ''' + apt-get update && apt-get install -y curl + curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + apt-get install -y nodejs + chmod +x ./gradlew + ./gradlew clean build -x test --build-cache + ''' + } + post { + success { + archiveArtifacts artifacts: 'backend/build/libs/**/*.jar,frontend/dist/**/*', fingerprint: true + } + } + } + + stage('Run Unit Tests') { + agent { + docker { + image 'eclipse-temurin:21-jdk' + args '--network=host' + } + } + steps { + script { + echo "Running unit tests..." + } + sh ''' + chmod +x ./gradlew + ./gradlew test --build-cache + ''' + } + post { + always { + junit 'backend/build/test-results/test/**/*.xml' + publishHTML([ + reportDir: 'backend/build/reports', + reportFiles: 'index.html', + reportName: 'Test Report' + ]) + } + } + } + + stage('Run Integration Tests') { + agent { + docker { + image 'eclipse-temurin:21-jdk' + args '--network=host' + } + } + when { + anyOf { + branch 'main' + branch 'develop' + branch 'master' + } + } + steps { + script { + echo "Running integration tests..." + } + sh ''' + chmod +x ./gradlew + ./gradlew integrationTest --build-cache + ''' + } + post { + always { + junit 'backend/build/test-results/integrationTest/**/*.xml' + } + } + } + + stage('Code Quality Checks') { + agent { + docker { + image 'eclipse-temurin:21-jdk' + args '--network=host' + } + } + when { + changeRequest() + } + steps { + script { + echo "Running code quality checks..." + } + sh ''' + chmod +x ./gradlew + ./gradlew check -x test + ''' + } + post { + failure { + echo "Quality checks failed - continuing pipeline with warning" + } + } + } + + stage('SonarQube Analysis') { + agent { + docker { + image 'gradle:9.4.1-jdk21-jammy' + args '--network=host' + } + } + when { + anyOf { + changeRequest() + branch 'main' + branch 'master' + branch 'develop' + } + } + steps { + script { + echo "Running SonarQube analysis..." + } + withSonarQubeEnv('SonarQube') { + sh 'gradle sonar' + } + } + post { + failure { + echo "SonarQube analysis failed - continuing pipeline with warning" + } + } + } + + stage('Build Docker Image') { + agent { + docker { + image 'docker:latest' + args '-v /var/run/docker.sock:/var/run/docker.sock' + } + } + when { + anyOf { + branch 'main' + branch 'develop' + branch 'master' + tag "*" + } + } + steps { + script { + echo "Building Docker image..." + } + sh ''' + docker login -u ${REGISTRY_USER} -p ${REGISTRY_PASSWORD} ${REGISTRY} + docker build -t ${DOCKER_IMAGE} . + docker push ${DOCKER_IMAGE} + docker tag ${DOCKER_IMAGE} ${DOCKER_IMAGE_LATEST} + docker push ${DOCKER_IMAGE_LATEST} + docker logout ${REGISTRY} + ''' + } + } + + stage('Deploy to Staging') { + when { + allOf { + branch 'develop' + expression { params.DEPLOY_TO_STAGING == true } + } + } + steps { + script { + echo "Deploying to staging environment..." + input(id: 'DeployToStaging', message: 'Deploy to staging?', ok: 'Deploy') + } + sh ''' + curl -X POST "${STAGING_DEPLOY_WEBHOOK}" \ + -H "Content-Type: application/json" \ + -d '{"image":"${DOCKER_IMAGE}"}' + echo "Deployment to staging triggered" + ''' + } + } + + stage('Deploy to Production') { + when { + anyOf { + allOf { + branch 'main' + expression { params.DEPLOY_TO_PRODUCTION == true } + } + tag "*" + } + } + steps { + script { + echo "Deploying to production environment..." + input(id: 'DeployToProd', message: 'Deploy to production?', ok: 'Deploy') + } + sh ''' + curl -X POST "${PROD_DEPLOY_WEBHOOK}" \ + -H "Content-Type: application/json" \ + -d '{"image":"${DOCKER_IMAGE}"}' + echo "Deployment to production triggered" + ''' + } + } + } + + post { + always { + cleanWs() + } + failure { + script { + echo "Pipeline failed! Check logs for details." + // You can add notification logic here + } + } + success { + script { + echo "Pipeline completed successfully!" + // You can add notification logic here + } + } + } +}