Pipeline Flow
Build → Deploy
End-to-end automation
Quality Gates
Coverage + Sonar
Maintain standards
Security
OWASP + SpotBugs
Proactive scanning
Delivery
Kaniko + K8s
Container-native
Gambaran Umum
Pipeline CI/CD ini dirancang untuk mengotomasi proses build, test, quality assurance, security scanning, packaging, containerization, dan deployment aplikasi Spring Boot ke Kubernetes cluster.
Fitur Utama
- Automated Build & Test
- Code Quality Analysis (SonarQube)
- AI-Powered Code Review (Gemini)
- Security Scanning (OWASP, SpotBugs)
- Docker Image Building (Kaniko)
- Multi-Environment Deployment (Dev, Staging, Production)
- Database Flexibility (MySQL/PostgreSQL)
- Kubernetes Native Deployment
Tech Stack
Build & Development Tools
| Tool | Versi | Deskripsi |
|---|---|---|
| Maven | 3.9.9 | Build automation tool untuk Java |
| Java (Eclipse Temurin) | 17 & 21 | Java Development Kit (JDK) |
| Spring Boot | - | Framework aplikasi Java |
Quality & Security Tools
| Tool | Deskripsi | Stage |
|---|---|---|
| JaCoCo | Code coverage analysis tool | Test & Quality |
| SonarQube | Platform analisis kualitas kode | Quality |
| Gemini AI | AI-powered code review | Quality |
| OWASP Dependency Check | Security vulnerability scanner untuk dependencies | Security |
| SpotBugs | Static analysis tool untuk bug detection | Security |
Container & Deployment
| Tool | Deskripsi |
|---|---|
| Kaniko | Container image builder tanpa Docker daemon |
| Kubernetes (kubectl) | Container orchestration platform |
| Docker Registry | Private container registry (registry.e-gitlab.prodak.id) |
Database Support
- MySQL - Default database
- PostgreSQL - Alternative database
Arsitektur Pipeline
Pipeline ini terdiri dari 8 stages yang berjalan secara sequential:
1. Build
Compile source code
Mengubah source Java menjadi bytecode yang siap diuji.
2. Test
Unit & integration tests
Menjamin fungsionalitas lewat unit dan integration test.
3. Quality
Coverage + Sonar + AI review
Memastikan kualitas kode lewat coverage, SonarQube, dan AI.
4. Security
OWASP + SpotBugs
Mendeteksi kerentanan dependency dan bug security.
5. Package
JAR/WAR artifacts
Membuat artifact siap rilis untuk tahap berikutnya.
6. Docker
Build & push image
Membangun image dan push ke private registry.
7. Deploy
Kubernetes rollout
Mendistribusikan aplikasi ke cluster Kubernetes.
Flow vertikal konsisten di semua ukuran layar.
Variabel Global
Maven Configuration
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -XX:+TieredCompilation -XX:TieredStopAtLevel=1"
- Fungsi: Optimasi performa Maven build
-Dmaven.repo.local: Set lokasi repository Maven lokal-XX:+TieredCompilation: Enable tiered compilation JVM-XX:TieredStopAtLevel=1: Optimasi untuk build cepat
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"
--batch-mode: Jalankan Maven dalam mode non-interaktif--errors: Tampilkan error messages--fail-at-end: Build semua modul sebelum fail--show-version: Tampilkan versi Maven
SonarQube Configuration
SONAR_HOST_URL: "${SONAR_HOST_URL:-http://sonarqube:9000}"
SONAR_LOGIN: "${SONAR_LOGIN:-}"
- URL default SonarQube server
- Token autentikasi (harus di-set di CI/CD Variables)
Docker Registry Configuration
DOCKER_REGISTRY: "registry.e-gitlab.prodak.id"
DOCKER_IMAGE_NAME: "${DOCKER_REGISTRY}/${CI_PROJECT_PATH}"
DOCKER_TLS_CERTDIR: "/certs"
- Private Docker registry internal
- Automatic image naming berdasarkan project path
Database Configuration
DATABASE_TYPE: "${DATABASE_TYPE:-mysql}"
- Default: MySQL
- Alternatif: PostgreSQL
- Dapat di-override per environment
Cache Strategy
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .m2/repository/
- target/
policy: pull-push
Penjelasan
- Key: Cache per-branch (menggunakan branch name)
- Paths:
.m2/repository/: Maven dependenciestarget/: Compiled classes dan artifacts
- Policy:
pull-push= Download cache di awal, upload di akhir
Benefit
- Mempercepat build time (skip download dependencies yang sudah ada)
- Menghemat bandwidth
- Cache isolated per branch
Default Configuration
default:
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
- api_failure
timeout: 45 minutes
tags:
- ubuntu-runner
Retry Policy
- Max retries: 2 kali
- Kondisi retry: System failure, timeout, atau API failure
Timeout
Default timeout: 45 menit per job
Runner Tags
Menggunakan runner dengan tag ubuntu-runner
Stage: BUILD
Job: build
Tujuan: Compile source code Java menjadi bytecode
Docker Image
image: maven:3.9.9-eclipse-temurin-17-alpine
- Maven 3.9.9
- Java 17 (Eclipse Temurin distribution)
- Alpine Linux (lightweight)
Before Script
- Setup Maven Settings
mkdir -p ~/.m2 cat <<EOF > ~/.m2/settings.xmlMembuat file
settings.xmluntuk autentikasi ke GitLab Maven Registry menggunakan$CI_JOB_TOKEN. - Install Local JAR Dependency
mvn install:install-file \ -Dfile=lib/com/dak/molect-supra-models/1.0.0/molect-supra-models-1.0.0.jar \ -DpomFile=lib/com/dak/molect-supra-models/1.0.0/molect-supra-models-1.0.0.pomInstall dependency
molect-supra-modelsdari local lib folder karena tidak ada di Maven Central. - Display Version Info
- Maven version
- Java version
Script
mvn $MAVEN_CLI_OPTS clean compile
clean: Hapus target foldercompile: Compile source code
Artifacts
artifacts:
paths:
- target/
expire_in: 1 day
when: on_success
- Menyimpan folder
target/untuk digunakan stage berikutnya - Artifact expired dalam 1 hari
- Hanya disimpan jika build success
Cache Policy
cache:
policy: pull-push
Download dan upload cache
Stage: TEST
Job: test
Tujuan: Menjalankan unit test dan integration test, generate code coverage report
Dependencies
dependencies:
- build
Menggunakan artifact dari job build
Script Logic
if [ -d "src/test/java" ]; then
mvn $MAVEN_CLI_OPTS test
mvn $MAVEN_CLI_OPTS jacoco:report
else
echo "⚠️ No test directory found"
mkdir -p target/surefire-reports
mkdir -p target/site/jacoco
fi
Conditional Testing:
- Cek apakah folder test exists
- Jika ada: Jalankan test + generate JaCoCo report
- Jika tidak ada: Skip test, buat folder dummy untuk compatibility
Artifacts
artifacts:
when: always
reports:
junit: target/surefire-reports/TEST-*.xml
coverage_report:
coverage_format: cobertura
path: target/site/jacoco/jacoco.xml
paths:
- target/surefire-reports/
- target/site/jacoco/
expire_in: 30 days
Test Reports:
- JUnit: Test results dalam format XML
- Coverage Report: Code coverage dalam format Cobertura
- Artifact disimpan selama 30 hari
when: always= Simpan artifact meskipun test gagal
Coverage Display
coverage: '/Total.*?([0-9]{1,3})%/'
Regex untuk extract coverage percentage dan ditampilkan di GitLab MR/pipeline UI
Stage: QUALITY
Job 1: code_coverage_analysis
Tujuan: Analisis mendalam terhadap code coverage metrics
# Check if test directory exists
if [ ! -d "src/test/java" ]; then
echo "⚠️ No test directory found"
exit 0
fi
# Check if JaCoCo execution data exists
if [ -f target/jacoco.exec ]; then
mvn $MAVEN_CLI_OPTS jacoco:report
fi
# Parse coverage percentage
COVERAGE=$(sed -n 's/.*line-rate="\([^"]*\)".*/\1/p' target/site/jacoco/jacoco.xml | head -1)
COVERAGE_PERCENT=$(echo "$COVERAGE * 100" | bc | cut -d. -f1)
# Warning if below threshold
if [ "$COVERAGE_PERCENT" -lt 60 ]; then
echo "⚠️ Warning: Code coverage below 60% threshold"
fi
Coverage Threshold:
- Warning Level: < 60%
- Recommendation: Maintain coverage ≥ 60%
allow_failure: true
Job bisa gagal tanpa block pipeline (warning/monitoring)
Job 2: sonarqube_analysis
Tujuan: Static code analysis untuk detect bugs, code smells, dan security vulnerabilities
image: maven:3.9.9-eclipse-temurin-21-alpine
Menggunakan Java 21 (required by SonarQube scanner)
# Check if SONAR_LOGIN configured
if [ -z "$SONAR_LOGIN" ]; then
echo "⚠️ Skipping SonarQube - SONAR_LOGIN not configured"
exit 0
fi
# Conditional test parameter
if [ -d "src/test/java" ]; then
TEST_PARAM="-Dsonar.tests=src/test/java"
else
TEST_PARAM=""
fi
# Run SonarQube analysis
mvn $MAVEN_CLI_OPTS sonar:sonar \
-Dsonar.projectKey=$CI_PROJECT_NAME \
-Dsonar.projectName=$CI_PROJECT_NAME \
-Dsonar.sources=src/main/java \
$TEST_PARAM \
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml \
-Dsonar.host.url=$SONAR_HOST_URL \
-Dsonar.login=$SONAR_LOGIN
SonarQube Parameters
| Parameter | Deskripsi |
|---|---|
projectKey | Unique identifier untuk project |
projectName | Display name di SonarQube |
sources | Source code location |
tests | Test code location (optional) |
coverage.jacoco.xmlReportPaths | Path ke JaCoCo coverage report |
host.url | SonarQube server URL |
login | Authentication token |
Trigger Rules
only:
- merge_requests
- main
- master
- develop
Hanya berjalan pada MR dan main branches
Job 3: code_review
Tujuan: AI-powered code review menggunakan Gemini AI
image: python:3.11-slim
Python 3.11 untuk menjalankan Gemini review script
Before Script
- Install Dependencies
apt-get update && apt-get install -y git git fetch --unshallow || git fetch --depth=50 - Clone Gemini Review Tool
git clone https://oauth2:${GEMINI_REVIEW_TOKEN}@e-gitlab.prodak.id/dak-sldc/gemini-code-review.git /tmp/gemini-review - Setup Virtual Environment
python -m venv /tmp/gemini-review/venv source /tmp/gemini-review/venv/bin/activate pip install -r /tmp/gemini-review/requirements.txt - Inject API Key
export GEMINI_API_KEY="$GEMINI_API_KEY"
Script
git fetch --all
source /tmp/gemini-review/venv/bin/activate
python /tmp/gemini-review/src/main.py \
--git-changes \
--git-changes-from "$CI_COMMIT_BEFORE_SHA" \
--git-changes-to "$CI_COMMIT_SHA" \
--output-md code_review_report.md
Parameters:
--git-changes: Analyze only changed files--git-changes-from: Start commit SHA--git-changes-to: End commit SHA--output-md: Output markdown report
Artifacts
artifacts:
paths:
- code_review_report.md
expire_in: 7 days
Menyimpan code review report dalam markdown dan dapat diakses dari GitLab UI
Required Variables
GEMINI_REVIEW_TOKEN: Token untuk clone repository GeminiGEMINI_API_KEY: API key untuk Gemini AI
Stage: SECURITY
Job 1: dependency_check
Tujuan: Scan dependencies untuk known security vulnerabilities (CVEs)
Tool: OWASP Dependency Check
- Open source tool untuk detect CVEs
- Database: National Vulnerability Database (NVD)
mvn $MAVEN_CLI_OPTS org.owasp:dependency-check-maven:check \
-DassemblyAnalyzerEnabled=false \
-DnodeAuditAnalyzerEnabled=false \
-Dformat=HTML || true
Parameters:
assemblyAnalyzerEnabled=false: Disable .NET assembly analysisnodeAuditAnalyzerEnabled=false: Disable Node.js auditformat=HTML: Output dalam format HTML
|| true: Job tidak fail meskipun ada vulnerabilities (untuk monitoring)
Artifacts
artifacts:
paths:
- target/dependency-check-report.html
expire_in: 30 days
HTML report yang detail tentang vulnerabilities termasuk CVE ID, severity, dan recommended fixes
Trigger Rules
only:
- main
- master
- develop
- merge_requests
Job 2: spotbugs_analysis
Tujuan: Static analysis untuk detect bugs dan bad practices
Tool: SpotBugs
- Successor dari FindBugs
- Detect 400+ bug patterns
- Categories: Correctness, Bad Practice, Performance, Security
mvn $MAVEN_CLI_OPTS compile spotbugs:spotbugs || true
if [ -f target/spotbugsXml.xml ]; then
BUGS_COUNT=$(grep -c "BugInstance" target/spotbugsXml.xml || echo "0")
echo "✅ SpotBugs analysis completed (found: ${BUGS_COUNT} issues)"
fi
Output: XML report dengan bug details
Bug Categories
- Correctness: Logic errors
- Bad Practice: Anti-patterns
- Performance: Performance issues
- Security: Security vulnerabilities
- Dodgy Code: Confusing code
Artifacts
artifacts:
paths:
- target/spotbugsXml.xml
expire_in: 30 days
Stage: PACKAGE
Job: package
Tujuan: Create executable JAR/WAR artifacts
Dependencies
dependencies:
- build
- test
Menggunakan compiled classes dari build dan memastikan test sudah passed
Script
mvn $MAVEN_CLI_OPTS package -DskipTests
JAR_FILE=$(find target -name "*.jar" -type f ! -name "*sources.jar" | head -1)
if [ -z "$JAR_FILE" ]; then
echo "❌ Error: JAR file not found"
exit 1
fi
echo "✅ JAR file created: $(basename $JAR_FILE)"
ls -lh "$JAR_FILE"
Process:
package: Create JAR/WAR file-DskipTests: Skip test (sudah dijalankan di stage test)- Validasi JAR file created successfully
- Display file size
Artifacts
artifacts:
paths:
- target/*.jar
- target/*.war
expire_in: 7 days
when: on_success
Menyimpan JAR/WAR files sebagai artifact untuk Docker build stage
Trigger Rules
only:
- main
- master
- develop
- tags
Cache Policy
cache:
policy: pull
Hanya download cache (tidak upload)
Stage: DOCKER
Job: docker_build
Tujuan: Build dan push Docker image ke private registry
Tool: Kaniko
- Tidak perlu Docker daemon
- Build container image inside container
- Lebih secure (no privileged mode)
- Kubernetes-native
Docker Image
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
Official Kaniko executor image (debug version)
Before Script: Docker Registry Auth
mkdir -p /kaniko/.docker
cat <<EOF > /kaniko/.docker/config.json
{
"auths": {
"registry.e-gitlab.prodak.id": {
"username": "$CI_REGISTRY_USER",
"password": "$CI_REGISTRY_PASSWORD"
}
}
}
EOF
Script: Multi-Tag Strategy
TAG_SHA="registry.e-gitlab.prodak.id/${CI_PROJECT_PATH}:${CI_COMMIT_SHORT_SHA}"
TAG_LATEST="registry.e-gitlab.prodak.id/${CI_PROJECT_PATH}:latest"
TAG_VERSION=""
if [ ! -z "$CI_COMMIT_TAG" ]; then
TAG_VERSION="registry.e-gitlab.prodak.id/${CI_PROJECT_PATH}:${CI_COMMIT_TAG}"
fi
/kaniko/executor \
--context "$CI_PROJECT_DIR" \
--dockerfile "$CI_PROJECT_DIR/Dockerfile" \
--destination "$TAG_SHA" \
--destination "$TAG_LATEST" \
${TAG_VERSION:+--destination "$TAG_VERSION"} \
--skip-tls-verify \
--cache=true \
--cache-repo="registry.e-gitlab.prodak.id/${CI_PROJECT_PATH}/cache"
Tag Strategy
| Tag Type | Format | Purpose |
|---|---|---|
| SHA | :abc1234 | Unique identifier per commit |
| Latest | :latest | Always points to latest build |
| Version | :v1.0.0 | Semantic versioning (for tags only) |
Kaniko Parameters
| Parameter | Deskripsi |
|---|---|
--context | Build context (project directory) |
--dockerfile | Path ke Dockerfile |
--destination | Target registry dan tag |
--skip-tls-verify | Skip TLS verification (untuk self-signed cert) |
--cache=true | Enable layer caching |
--cache-repo | Repository untuk cache layers |
Benefits
- Layer caching mempercepat rebuild
- Multi-tag dalam satu build
- Automatic push setelah build
Stage: DEPLOY
Deploy Template
Konsep: Reusable template untuk deploy ke berbagai environment
.deploy_template: &deploy_template
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: [""]
variables:
DATABASE_TYPE: "${DATABASE_TYPE:-mysql}"
Kubernetes Image: bitnami/kubectl:latest (kubectl CLI tool)
Deploy Process Flow
1. Setup Kubeconfig
Inisialisasi akses cluster
Decode kubeconfig dan verifikasi koneksi ke cluster.
2. Create Namespace
Isolasi resource
Buat namespace molect-supra-core secara idempotent.
3. Registry Secret
Akses image private
Buat secret untuk pull image dari registry internal.
4. App Secrets
Kredensial aplikasi
Simpan username, password, dan JWT secret.
5. Deploy Database
MySQL/PostgreSQL
Deploy database sesuai konfigurasi environment.
6. Wait for Database
Readiness check
Tunggu sampai pod database berstatus Ready.
7. Deploy Application
Apply deployment
Apply manifest aplikasi ke namespace target.
8. Rollout Status
Observasi deployment
Monitor rollout hingga selesai atau timeout.
9. Display Status
Ringkasan hasil
Tampilkan pods, PVC, dan service untuk validasi.
Flow vertikal konsisten seperti UI Arsitektur Pipeline.
Before Script: Kubernetes Setup
# Set kubeconfig variable based on environment
KUBECONFIG_VAR="${KUBECONFIG_ENV}"
[ -z "$KUBECONFIG_VAR" ] && exit 0
# Decode and save kubeconfig
mkdir -p $HOME/.kube
echo "$KUBECONFIG_VAR" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
# Test connection
kubectl cluster-info
Security:
- Kubeconfig encoded dengan base64
- File permission 600 (read/write owner only)
- Test connection sebelum deploy
Script: Deployment Steps
1. Create Namespace
kubectl create namespace molect-supra-core --dry-run=client -o yaml | kubectl apply -f -
- Idempotent: Create jika belum ada
--dry-run=client: Generate YAML tanpa createkubectl apply: Apply YAML (create or update)
2. Create Registry Secret
kubectl delete secret registry-credentials -n molect-supra-core --ignore-not-found=true
kubectl create secret docker-registry registry-credentials \
--docker-server=registry.e-gitlab.prodak.id \
--docker-username=$CI_REGISTRY_USER \
--docker-password=$CI_REGISTRY_PASSWORD \
--docker-email="ci@gitlab.prodak.id" \
-n molect-supra-core
Purpose: Kubernetes perlu credentials untuk pull private images
3. Create App Secrets
kubectl get secret app-secrets -n molect-supra-core 2>/dev/null || \
kubectl create secret generic app-secrets \
--from-literal=DATASOURCE_USERNAME=spring_user \
--from-literal=DATASOURCE_PASSWORD=spring_password \
--from-literal=JWT_SECRET=MySecureJwtSecretKey12345678901234567890 \
-n molect-supra-core
Secrets:
DATASOURCE_USERNAME: Database usernameDATASOURCE_PASSWORD: Database passwordJWT_SECRET: JWT signing key
Note: Ganti dengan values yang secure di production!
4. Deploy Database
if [ "$DATABASE_TYPE" = "mysql" ]; then
echo "📦 Deploying MySQL infrastructure..."
kubectl apply -f k8s-namespace-mysql.yaml
kubectl apply -f k8s-configmap-mysql.yaml -n molect-supra-core
else
echo "📦 Deploying PostgreSQL infrastructure..."
kubectl apply -f k8s-configmap-postgres.yaml -n molect-supra-core
kubectl apply -f k8s-postgres-deployment.yaml
fi
Database Selection:
- MySQL: Default option
- PostgreSQL: Alternative option
- Determined by
DATABASE_TYPEvariable
5. Wait for Database Ready
for i in {1..30}; do
[ "$DATABASE_TYPE" = "mysql" ] && POD_LABEL="mysql" || POD_LABEL="postgres"
POD_STATUS=$(kubectl get pod -l app=$POD_LABEL -n molect-supra-core \
-o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}' \
2>/dev/null || echo "False")
echo "Attempt $i/30 - Database status=$POD_STATUS"
[ "$POD_STATUS" = "True" ] && echo "✅ Database ready!" && break
sleep 10
done
Wait Logic:
- Max 30 attempts (5 minutes)
- Check every 10 seconds
- Query pod ready condition
- Break loop when ready
6. Deploy Application
kubectl apply -f k8s-deployment.yaml -n molect-supra-core
kubectl rollout status deployment/molect-supra-core \
-n molect-supra-core \
--timeout=5m || true
Rollout Status:
- Wait up to 5 minutes for rollout complete
|| true: Don't fail if timeout (will check status anyway)
7. Display Status
kubectl get pods -n molect-supra-core -o wide
kubectl get pvc -n molect-supra-core
kubectl get svc -n molect-supra-core
Information Displayed:
- Pods: All running pods with node info
- PVC: Persistent Volume Claims
- Services: Network services and endpoints
Deploy Jobs
1. deploy_dev (Development)
deploy_dev:
<<: *deploy_template
variables:
KUBECONFIG_ENV: "$KUBECONFIG_DEV"
DATABASE_TYPE: "${DEV_DATABASE_TYPE:-mysql}"
environment:
name: development
kubernetes:
namespace: molect-supra-core
only:
- develop
allow_failure: true
- Trigger automatic pada branch
develop - Kubeconfig:
$KUBECONFIG_DEV - Database: Default MySQL, bisa override dengan
DEV_DATABASE_TYPE - Allow Failure: Yes (development environment)
2. deploy_staging (Staging)
deploy_staging:
<<: *deploy_template
variables:
KUBECONFIG_ENV: "$KUBECONFIG_STAGING"
DATABASE_TYPE: "${STAGING_DATABASE_TYPE:-mysql}"
environment:
name: staging
kubernetes:
namespace: molect-supra-core
only:
- main
- master
when: manual
allow_failure: true
- Trigger manual pada branch
main/master - Manual approval required
- Purpose: Pre-production testing
3. deploy_prod (Production)
deploy_prod:
<<: *deploy_template
variables:
KUBECONFIG_ENV: "$KUBECONFIG_PROD"
DATABASE_TYPE: "${PROD_DATABASE_TYPE:-mysql}"
before_script:
- test -z "$CI_COMMIT_TAG" && echo "❌ Requires git tag" && exit 1
# ... (standard before_script)
environment:
name: production
kubernetes:
namespace: molect-supra-core
only:
- tags
when: manual
allow_failure: true
- Trigger manual, requires Git tag
- Tag requirement ensures version control
- Manual approval prevents accidental deploy
Konfigurasi Environment
Required GitLab CI/CD Variables
Registry Credentials
| Variable | Type | Description |
|---|---|---|
CI_REGISTRY_USER | Variable | Docker registry username |
CI_REGISTRY_PASSWORD | Variable | Docker registry password |
SonarQube
| Variable | Type | Description |
|---|---|---|
SONAR_HOST_URL | Variable | SonarQube server URL |
SONAR_LOGIN | Variable | SonarQube authentication token |
Gemini Code Review
| Variable | Type | Description |
|---|---|---|
GEMINI_REVIEW_TOKEN | Variable | Token untuk clone Gemini review repo |
GEMINI_API_KEY | Variable | Gemini AI API key |
Kubernetes Credentials (Base64 Encoded)
| Variable | Type | Description |
|---|---|---|
KUBECONFIG_DEV | File | Development cluster kubeconfig |
KUBECONFIG_STAGING | File | Staging cluster kubeconfig |
KUBECONFIG_PROD | File | Production cluster kubeconfig |
Database Selection (Optional)
| Variable | Default | Description |
|---|---|---|
DATABASE_TYPE | mysql | Global database type |
DEV_DATABASE_TYPE | mysql | Development database |
STAGING_DATABASE_TYPE | mysql | Staging database |
PROD_DATABASE_TYPE | mysql | Production database |
Options: mysql atau postgresql
Cara Set Variables di GitLab
- Navigate ke Settings > CI/CD > Variables
- Click Add variable
- Set:
- Key: Variable name
- Value: Variable value
- Type: Variable atau File
- Protected: Yes (untuk production)
- Masked: Yes (untuk sensitive data)
Example: Set Kubeconfig
# Encode kubeconfig to base64
cat ~/.kube/config | base64 -w 0 > kubeconfig.base64
# Copy content dari kubeconfig.base64
# Paste ke GitLab CI variable KUBECONFIG_PROD
Run Down Perancangan & Implementasi (12–26 Januari 2026)
Timeline berikut merangkum aktivitas perancangan dan implementasi CI/CD GitLab untuk project molect, termasuk setup infrastruktur, tools quality/security, trial & error pipeline, hingga dokumentasi akhir.
12 Jan 2026
Kickoff & Scope Alignment
- Workshop kebutuhan pipeline (build, test, quality, security, deploy).
- Definisi environment target (dev, staging, prod).
- Inventarisasi dependency lokal & repository internal.
13–14 Jan 2026
Setup Infrastruktur Kubernetes
- Provisioning cluster & namespace
molect-supra-core. - Konfigurasi storage (PVC) & resource quotas.
- Uji konektivitas kubeconfig untuk CI.
15 Jan 2026
GitLab Runner & Registry
- Registrasi runner bertag
ubuntu-runner. - Validasi akses registry private.
- Uji job build sederhana untuk verifikasi runner.
16–17 Jan 2026
SonarQube & Quality Gate
- Deploy SonarQube dan konfigurasi token akses.
- Integrasi coverage JaCoCo ke Sonar.
- Trial analysis di branch
develop.
18 Jan 2026
Gemini AI Code Review
- Integrasi repo
gemini-code-reviewke pipeline. - Setup
GEMINI_REVIEW_TOKEN&GEMINI_API_KEY. - Validasi output report markdown.
19 Jan 2026
Security Scanning
- OWASP Dependency Check & SpotBugs baseline.
- Penetapan
allow_failure: trueuntuk monitoring. - Review initial findings dan exclusions.
20 Jan 2026
Packaging & Artifact Management
- Standarisasi packaging JAR/WAR.
- Artifact retention & dependency cache tuning.
- Validasi compatibility antar stage.
21 Jan 2026
Docker Build (Kaniko)
- Konfigurasi Kaniko & multi-tag image.
- Uji push ke registry private.
- Optimasi layer cache.
22–23 Jan 2026
Trial & Error Deployment (Dev/Staging)
- Debug kubeconfig, namespace, dan registry secret.
- Validasi readiness database & rollout status.
- Perbaikan manifest deployment & env vars.
24 Jan 2026
Stabilization & Pipeline Hardening
- Refactor rules/only untuk MR & tag.
- Retry policy & timeout tuning.
- Finalisasi cache strategy.
25–26 Jan 2026
Dokumentasi & Handover
- Finalisasi dokumentasi CI/CD, troubleshooting, dan best practices.
- Review lint/format HTML & asset consistency.
- Handover ke tim operasi & penjadwalan maintenance.
Catatan: Timeline bersifat ringkas untuk kebutuhan dokumentasi internal.
Best Practices
1. Branch Strategy
main/master → Staging deployment
develop → Dev deployment
tags (v*) → Production deployment
feature/* → Build + Test only
2. Security
- Semua credentials di GitLab CI variables (encrypted)
- Kubeconfig base64 encoded
- Docker registry credentials protected
- Production deployment requires git tag
- Manual approval untuk staging/production
3. Performance Optimization
- Maven cache untuk dependencies
- Docker layer caching dengan Kaniko
- Parallel jobs where possible
- Artifact expiration untuk cleanup
4. Monitoring & Debugging
- Coverage reports di GitLab UI
- Test reports dalam JUnit format
- Security scan reports (HTML)
- Deployment status di Kubernetes
5. Failure Handling
- Automatic retry untuk system failures
-
allow_failure: trueuntuk non-critical jobs - Detailed logging dengan indikator visual
- Graceful handling untuk missing test directory
6. Database Management
- Flexible database selection (MySQL/PostgreSQL)
- Per-environment database configuration
- Wait for database ready before app deployment
- Persistent storage support
Troubleshooting
Build Failed: JAR Not Found
Symptom: ❌ JAR file not found!
Solution: Check lib/com/dak/molect-supra-models/ structure
SonarQube Analysis Skipped
Symptom: ⚠️ Skipping SonarQube - SONAR_LOGIN not configured
Solution: Set SONAR_LOGIN variable di GitLab CI/CD settings
Docker Push Failed
Symptom: unauthorized: authentication required
Solution: Verify CI_REGISTRY_USER dan CI_REGISTRY_PASSWORD variables
Deployment Failed: Kubeconfig
Symptom: error: loading kubeconfig
Solution:
- Verify kubeconfig encoded correctly (base64)
- Check
KUBECONFIG_*variable exists - Test kubeconfig locally:
echo "$KUBECONFIG_DEV" | base64 -d > test-config
kubectl --kubeconfig=test-config cluster-info
Database Not Ready
Symptom: Timeout waiting for database
Solution:
- Check pod status:
kubectl get pods -n molect-supra-core - Check pod logs:
kubectl logs <pod-name> -n molect-supra-core - Verify PVC bound:
kubectl get pvc -n molect-supra-core
Maintenance
Update Maven Version
Edit image tag di semua jobs:
image: maven:3.9.9-eclipse-temurin-17-alpine
# ↑ Update version number
Update Java Version
Edit Eclipse Temurin version:
image: maven:3.9.9-eclipse-temurin-21-alpine
# ↑ Update Java version
Update Dependency
Update local JAR di before_script:
mvn install:install-file \
-Dfile=lib/com/dak/molect-supra-models/2.0.0/molect-supra-models-2.0.0.jar \
# ↑ Update version
Resources
Official Documentation
Tools Documentation
Changelog
Version 1.0.0 (Current)
- Complete CI/CD pipeline implementation
- Multi-stage build process
- Quality & security scanning
- Kubernetes deployment automation
- Multi-environment support
- Flexible database selection
Support
Untuk pertanyaan atau issue terkait pipeline ini, hubungi:
- Team: DAK SLDC
- Project: molect-supra-core
- GitLab: e-gitlab.prodak.id