Skip to content

Instantly share code, notes, and snippets.

@tokhi
Last active March 29, 2026 14:08
Show Gist options
  • Select an option

  • Save tokhi/cd1a572253c344a6acd47ab7a3b81802 to your computer and use it in GitHub Desktop.

Select an option

Save tokhi/cd1a572253c344a6acd47ab7a3b81802 to your computer and use it in GitHub Desktop.
gradle
// build.gradle
plugins {
id 'java'
id 'jacoco'
id 'org.sonarqube' version '4.4.1.3373'
id 'org.owasp.dependencycheck' version '9.0.9'
}
repositories {
maven {
url 'http://nexus.intern/repository/maven-group/'
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter:3.2.0'
implementation 'ch.qos.logback:logback-classic:1.4.11'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
test {
useJUnitPlatform()
}
sonar {
properties {
property 'sonar.projectKey', 'statistik-report'
property 'sonar.host.url', 'http://sonar.intern'
property 'sonar.login', 'your-sonar-token'
property 'sonar.coverage.jacoco.xmlReportPaths',
'build/reports/jacoco/test/jacocoTestReport.xml'
}
}
######### Stack.yml ################
version: '3.8'
services:
app:
image: statistik-report-service:1.0.0
ports:
- "8080:8080"
environment:
- SONAR_HOST=http://sonarqube:9000
secrets:
- app_db_password
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
networks:
- statistik-net
sonarqube:
image: sonarqube:10-community
ports:
- "9000:9000"
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
networks:
- statistik-net
nexus:
image: sonatype/nexus3:latest
ports:
- "8081:8081"
volumes:
- nexus_data:/nexus-data
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
networks:
- statistik-net
networks:
statistik-net:
driver: overlay
volumes:
nexus_data:
secrets:
app_db_password:
external: true
########## bamboo.yml ########################
# bamboo-specs/bamboo.yml
---
version: 2
plan:
project-key: STAT # short code for your Bamboo project
key: SRS # unique key for this plan
name: statistik-report-service
# What triggers the pipeline
triggers:
- polling: # check Git every 60s for new commits
period: '60'
# Which Git repo to use
repositories:
- name: statistik-report-service
type: git
url: https://git.intern/statistik-report-service.git
branch: main
stages:
# ─────────────────────────────────────────
# Stage 1: Build — compile and package
# ─────────────────────────────────────────
- name: Build
jobs:
- name: Compile and package
key: BUILD
tasks:
- checkout: # task type: check out source code
repository: statistik-report-service
path: .
- script: # task type: run a shell command
interpreter: SHELL
scripts:
- ./gradlew clean build -x test # build but skip tests (tests run in next stage)
- script:
interpreter: SHELL
scripts:
- ./gradlew jar # produce the JAR artifact
artifacts: # save the JAR so later stages can use it
- name: app-jar
location: build/libs
pattern: '*.jar'
shared: true # shared = available to all subsequent stages
# ─────────────────────────────────────────
# Stage 2: Test — unit + integration tests
# ─────────────────────────────────────────
- name: Test
jobs:
- name: Unit tests
key: UNIT
tasks:
- checkout:
repository: statistik-report-service
path: .
- script:
interpreter: SHELL
scripts:
- ./gradlew test # runs JUnit 5 tests, produces JaCoCo report
final-tasks: # final-tasks always run, even if the job fails
- junit: # task type: parse and publish JUnit XML results
results-pattern: 'build/test-results/test/*.xml'
- name: Integration tests # runs IN PARALLEL with unit tests
key: INTEG
tasks:
- checkout:
repository: statistik-report-service
path: .
- script:
interpreter: SHELL
scripts:
- ./gradlew integrationTest
final-tasks:
- junit:
results-pattern: 'build/test-results/integrationTest/*.xml'
# ─────────────────────────────────────────
# Stage 3: Quality gate — SonarQube analysis
# ─────────────────────────────────────────
- name: Quality gate
jobs:
- name: SonarQube analysis
key: SONAR
tasks:
- checkout:
repository: statistik-report-service
path: .
- script:
interpreter: SHELL
scripts:
- ./gradlew sonar
-Dsonar.host.url=http://sonar.intern
-Dsonar.projectKey=statistik-report
-Dsonar.login=${bamboo.sonar.token} # secret variable from Bamboo
# ─────────────────────────────────────────
# Stage 3.5: Security scan — dependencyCheckAnalyze
# ─────────────────────────────────────────
- name: Security scan
jobs:
- name: dependencyCheckAnalyze # make sure to add the dependencyCheck plugin to your Gradle build file for this to work
key: DEPCHK
tasks:
- script:
interpreter: SHELL
scripts:
- ./gradlew dependencyCheckAnalyze
# ─────────────────────────────────────────
# Stage 4: Publish — push JAR to Nexus
# ─────────────────────────────────────────
- name: Publish
jobs:
- name: Publish to Nexus
key: PUB
tasks:
- checkout:
repository: statistik-report-service
path: .
- script:
interpreter: SHELL
scripts:
- ./gradlew publish # uses maven-publish plugin, pushes to Nexus
# ─────────────────────────────────────────
# Stage 5: Deploy — update the Swarm stack
# ─────────────────────────────────────────
- name: Deploy
manual: true # require a human to click "deploy" — common in public sector
jobs:
- name: Deploy to Swarm
key: DEPLOY
tasks:
- checkout:
repository: statistik-report-service
path: .
- script:
interpreter: SHELL
scripts:
- docker stack deploy
-c stack.yml
statistik-report-service
############################
Containerizing a mock service
This is the part the job spec explicitly mentions — "Erstellung von Mock Services auf Basis von OpenAPI, WSDL und Containern." So know this well.
Containerizing Prism:
###
dockerfile# Dockerfile.mock
FROM stoplight/prism:4
COPY payroll-api.yaml /app/payroll-api.yaml
CMD ["mock", "--host", "0.0.0.0", "/app/payroll-api.yaml"]
#------
bashdocker build -f Dockerfile.mock -t payroll-mock:1.0.0 .
docker run -p 4010:4010 payroll-mock:1.0.0
#------
Or in your Swarm stack — add it as a service:
yamlservices:
payroll-mock:
image: payroll-mock:1.0.0
ports:
- "4010:4010"
deploy:
replicas: 1
networks:
- statistik-net
#-----
Now every other service in the stack reaches the mock
at http://payroll-mock:4010 by service name — no hardcoded IPs, no configuration changes needed when you swap to the real API later.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment