From a1e7744160781f336e50d31bf260316c6d4b7692 Mon Sep 17 00:00:00 2001 From: bhuridech Date: Mon, 18 Mar 2024 22:58:26 +0700 Subject: [PATCH] config sonarqube in ci/cd --- .github/workflows/cicd.yaml | 66 ++++++++++++++-------------------- .github/workflows/prod-cd.yaml | 47 ++++++++++++++++++++++++ infra/dev/configmap.yml | 7 ++++ infra/dev/deployment.yml | 31 ++++++++++++++++ infra/dev/namespace.yml | 4 +++ infra/dev/service.yml | 13 +++++++ infra/prod/configmap.yml | 7 ++++ infra/prod/deployment.yml | 31 ++++++++++++++++ infra/prod/namespace.yml | 4 +++ infra/prod/service.yml | 13 +++++++ kshop/build.gradle | 16 +++++++++ 11 files changed, 199 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/prod-cd.yaml create mode 100644 infra/dev/configmap.yml create mode 100644 infra/dev/deployment.yml create mode 100644 infra/dev/namespace.yml create mode 100644 infra/dev/service.yml create mode 100644 infra/prod/configmap.yml create mode 100644 infra/prod/deployment.yml create mode 100644 infra/prod/namespace.yml create mode 100644 infra/prod/service.yml diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index b13c88d..9714489 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -19,26 +19,37 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 17 uses: actions/setup-java@v1 with: java-version: 17 - - name: Cache SonarQube packages - uses: actions/cache@v3 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar + - name: Cache Gradle packages - uses: actions/cache@v3 + id: gradle-cache + uses: actions/cache@v2 with: - path: ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} - restore-keys: ${{ runner.os }}-gradle + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: download dependencies + if: ${{ steps.gradle-cache.outputs.cache-hit != 'true' }} + working-directory: ./kshop + run: ./gradlew dependencies + + - name: Run test + working-directory: ./kshop + run: ./gradlew test + - name: Build and analyze env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + working-directory: ./kshop run: ./gradlew build sonar --info build-and-push-docker-image: @@ -47,22 +58,10 @@ jobs: needs: quality-check steps: - - name: Set up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17 - - uses: actions/checkout@v4 - - - name: Run test - run: ./gradlew test - - name: Setup SHA run: echo "GITHUB_SHA=${GITHUB_SHA}" >> $GITHUB_ENV - - name: Build the Docker image - run: docker build . --file Dockerfile --tag ghcr.io/aorjoa-bootcamp/devops-java-example:${{ env.GITHUB_SHA }} - - name: Login ghcr.io uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 with: @@ -73,17 +72,9 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: - context: . - push: ${{ github.ref == 'refs/heads/main' }} - tags: ${{ env.GITHUB_SHA }} - - - name: Push to GitHub Container Registry - uses: docker/build-push-action@v2 - with: - context: . - tags: | - ghcr.io/aorjoa-bootcamp/devops-java-example:${{ env.GITHUB_SHA }} + context: ./kshop push: ${{ github.ref == 'refs/heads/main' }} + tags: ghcr.io/aorjoa/workshop-java:${{ env.GITHUB_SHA }} - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} @@ -94,23 +85,18 @@ jobs: runs-on: ubuntu-latest needs: build-and-push-docker-image steps: - - name: checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: - repository: aorjoa-bootcamp/devops-argocd - persist-credentials: false fetch-depth: 0 - name: change image tag run: | git --version git config user.name "aorjoa" git config user.email "root@aorjoa.link" - sed -i -E "s/ghcr.io\/aorjoa-bootcamp\/devops-java-example.*$/ghcr.io\/aorjoa-bootcamp\/devops-java-example:${GITHUB_SHA}/" kube-gitops/deployment.yml - git add kube-gitops/deployment.yml + sed -i -E "s/ghcr.io\/aorjoa\/workshop-java.*$/ghcr.io\/aorjoa\/workshop-java:${GITHUB_SHA}/" infra/dev/deployment.yml + git add infra/dev/deployment.yml git commit -m "🤖 change docker image version to ${GITHUB_SHA}" - name: push changes uses: ad-m/github-push-action@master with: - github_token: ${{ secrets.PAT }} - repository: aorjoa-bootcamp/devops-argocd branch: main \ No newline at end of file diff --git a/.github/workflows/prod-cd.yaml b/.github/workflows/prod-cd.yaml new file mode 100644 index 0000000..da2b236 --- /dev/null +++ b/.github/workflows/prod-cd.yaml @@ -0,0 +1,47 @@ +name: Prd environment CD + +on: + workflow_dispatch: + inputs: + test: + description: '🔦 QA lead already approved' + required: true + type: boolean + sign-off: + description: '📝 Make sure PO sign-off' + required: true + type: boolean + deploy-tag: + description: '🎯 Deploy docker tag' + required: true + type: string + default: c9f6b38c1acd0a7153e42a03b577757262075eb3 + +jobs: + # ============== + # CD Prd task + # ============== + gitops-prd-versioning: + runs-on: ubuntu-latest + steps: + - name: verify manual input + run: | + { if [ '${{ inputs.test }}' = 'false' ]; then echo "🔦 QA lead not approve yet"; exit 1; fi } + { if [ '${{ inputs.sign-off }}' = 'false' ]; then echo "📝 Need PO sign-off"; exit 1; fi } + + - name: checkout + uses: actions/checkout@v3 + + - name: config git + run: | + git --version + git config user.name "robot" + git config user.email "root@aorjoa.link" + + - name: change image tag + run: | + sed -i -E "s/ghcr.io\/aorjoa\/workshop-java.*$/ghcr.io\/aorjoa\/workshop-java:${GITHUB_SHA}/" infra/prod/deployment.yml + git add infra/prod/deployment.yml + git commit -m "[skip actions] 🤖 change prd docker image version to ${{ inputs.deploy-tag }}" + git pull --rebase + git push \ No newline at end of file diff --git a/infra/dev/configmap.yml b/infra/dev/configmap.yml new file mode 100644 index 0000000..25560b1 --- /dev/null +++ b/infra/dev/configmap.yml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: app-config + namespace: dev-workshop +data: + api.service.port: "9090" \ No newline at end of file diff --git a/infra/dev/deployment.yml b/infra/dev/deployment.yml new file mode 100644 index 0000000..fd37df5 --- /dev/null +++ b/infra/dev/deployment.yml @@ -0,0 +1,31 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api + namespace: dev-workshop +spec: + selector: + matchLabels: + app: api + replicas: 3 + template: + metadata: + labels: + app: api + spec: + containers: + - name: kshop-api + image: ghcr.io/aorjoa/workshop-java:342b25a526f325f284259db8f71d8c866b2b527d + imagePullPolicy: Always + ports: + - containerPort: 9090 + env: + - name: SERVER_PORT + valueFrom: + configMapKeyRef: + name: app-config + key: api.service.port + resources: + limits: + cpu: 2 + memory: 512Mi diff --git a/infra/dev/namespace.yml b/infra/dev/namespace.yml new file mode 100644 index 0000000..01b693a --- /dev/null +++ b/infra/dev/namespace.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: dev-workshop \ No newline at end of file diff --git a/infra/dev/service.yml b/infra/dev/service.yml new file mode 100644 index 0000000..06a15ca --- /dev/null +++ b/infra/dev/service.yml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: api + namespace: dev-workshop +spec: + ports: + - port: 80 + targetPort: 9090 + protocol: TCP + selector: + app: api + type: LoadBalancer \ No newline at end of file diff --git a/infra/prod/configmap.yml b/infra/prod/configmap.yml new file mode 100644 index 0000000..eee2929 --- /dev/null +++ b/infra/prod/configmap.yml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: app-config + namespace: workshop +data: + api.service.port: "9090" \ No newline at end of file diff --git a/infra/prod/deployment.yml b/infra/prod/deployment.yml new file mode 100644 index 0000000..94f16e0 --- /dev/null +++ b/infra/prod/deployment.yml @@ -0,0 +1,31 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api + namespace: workshop +spec: + selector: + matchLabels: + app: api + replicas: 3 + template: + metadata: + labels: + app: api + spec: + containers: + - name: kshop-api + image: ghcr.io/aorjoa/workshop-java:342b25a526f325f284259db8f71d8c866b2b527d + imagePullPolicy: Always + ports: + - containerPort: 9090 + env: + - name: SERVER_PORT + valueFrom: + configMapKeyRef: + name: app-config + key: api.service.port + resources: + limits: + cpu: 2 + memory: 512Mi diff --git a/infra/prod/namespace.yml b/infra/prod/namespace.yml new file mode 100644 index 0000000..e1d08ef --- /dev/null +++ b/infra/prod/namespace.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: workshop \ No newline at end of file diff --git a/infra/prod/service.yml b/infra/prod/service.yml new file mode 100644 index 0000000..b318812 --- /dev/null +++ b/infra/prod/service.yml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: api + namespace: workshop +spec: + ports: + - port: 80 + targetPort: 9090 + protocol: TCP + selector: + app: api + type: LoadBalancer \ No newline at end of file diff --git a/kshop/build.gradle b/kshop/build.gradle index 0510628..276bfd4 100644 --- a/kshop/build.gradle +++ b/kshop/build.gradle @@ -1,7 +1,16 @@ plugins { id 'java' + id 'jacoco' id 'org.springframework.boot' version '3.2.2' id 'io.spring.dependency-management' version '1.1.4' + id 'org.sonarqube' version '4.4.1.3373' +} + +jacocoTestReport { + reports { + xml.required = true + html.required = true + } } group = 'com.kampus' @@ -26,3 +35,10 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +sonar { + properties { + property "sonar.gradle.skipCompile", "true" + property "sonar.projectKey", "aorjoa-bootcamp" + } +}