-
Notifications
You must be signed in to change notification settings - Fork 4
204 lines (181 loc) · 11.4 KB
/
kotlin.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# GitHub workflow to build and deploy Kotlin based API Backend
name: kotlin
# Controls when the action will run. Triggers the workflow on push requests only for the main branch
on:
# run on all pull requests (but note that certain steps are skipped if if: github.ref == 'refs/heads/main' )
pull_request:
paths: [ 'kotlin/**', '.github/workflows/kotlin.yml' ]
push:
# If at least one path matches a pattern in the paths filter, the workflow runs.
paths: [ 'kotlin/**','.github/workflows/kotlin.yml' ]
branches: [ main ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
# Support [skip ci] out of box with GitHub actions Workaround
# Only works for push https://github.com/actions/runner/issues/774
if: " ! contains(github.event.head_commit.message, 'skip ci') "
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout Repo
uses: actions/checkout@v4
- name: Set up Eclipse Temurin JDK
uses: actions/setup-java@v4
with:
# setup-java v2 supports temurin + various other distributions
# see https://github.com/actions/setup-java?tab=readme-ov-file#supported-version-syntax
distribution: 'temurin'
java-version: 21
- name: Configure AWS Credentials
# avoid https://github.com/aws-actions/configure-aws-credentials#notice-node12-deprecation-warning
uses: aws-actions/configure-aws-credentials@v4
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Pull Environment Config from AWS SSM ParamStore
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
run: |
echo "LATEST_REPO_TAG=$(git ls-remote --tags --sort='v:refname' | tail -n1 | sed 's/.*\///; s/\^{}//')" >> $GITHUB_ENV
echo "RELEASE_NAME=$(aws ssm get-parameter --name /angkor/prod/RELEASE_NAME --with-decryption --query 'Parameter.Value' --output text)" >> $GITHUB_ENV
echo "RELEASE_VERSION=$(aws ssm get-parameter --name /angkor/prod/RELEASE_VERSION --with-decryption --query 'Parameter.Value' --output text)" >> $GITHUB_ENV
# Cache Java / Gradle Dependencies
# https://github.com/actions/cache/blob/main/examples.md#java---gradle
# https://docs.github.com/en/actions/language-and-framework-guides/building-and-testing-java-with-gradle#caching-dependencies
# https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle-
# Cache Gradle Wrapper separately
# Inspired by: https://github.com/JetBrains/intellij-platform-plugin-template/actions/runs/242898088/workflow
- name: Setup Gradle Wrapper Cache
uses: actions/cache@v4
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
# Actual Gradle build (!= dependabot)
- name: Build and run unit tests with Gradle
working-directory: ./kotlin
# don't run the full build with integration tests for dependabot PRs, since they can't access secrets
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions#responding-to-events
if: ${{ github.actor != 'dependabot[bot]' }}
run: |
echo "Creating temporary DB $SPRING_DATASOURCE_URL"
./gradlew --console=plain test --fail-fast --stacktrace bootJar
ls -l build/libs/app.jar
env:
CI: true
# make sure to send SPRING_DATASOURCE_URL, _PASSWORD and _USERNAME as GitHub Secrets
SPRING_DATASOURCE_USERNAME: ${{ secrets.SPRING_DATASOURCE_USERNAME }}
SPRING_DATASOURCE_PASSWORD: ${{ secrets.SPRING_DATASOURCE_PASSWORD }}
SPRING_DATASOURCE_URL: ${{ secrets.SPRING_DATASOURCE_URL }}
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_COGNITO_ISSUER_URI: ${{ secrets.SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_COGNITO_ISSUER_URI }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # for Sonarcloud Needed to get PR information, if any
# Gradle build and Test for dependabot, does not require secrets
- name: Special Build and unit test with Gradle
if: ${{ github.actor == 'dependabot[bot]' }}
working-directory: ./kotlin
# don't run the full build with integration tests for dependabot PRs, since they can't access secrets
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions#responding-to-events
run: |
./gradlew --console=plain compileKotlin test --tests "*UT" --fail-fast --stacktrace
env:
CI: true
# JUnit Reporting https://github.com/EnricoMi/publish-unit-test-result-action#github-action-to-publish-unit-test-results
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
# The if: always() clause guarantees that this action always runs,
# even if earlier steps (e.g., the unit test step) in your workflow fail.
if: ${{ always() && format('refs/heads/{0}', github.event.repository.default_branch) == github.ref }}
with:
files: "./kotlin/build/test-results/**/*.xml"
# Run Hadolint Dockerfile linting tool
# https://github.com/marketplace/actions/hadolint-action
- name: Lint Dockerfile with hadolint
uses: brpaz/hadolint-action@v1.5.0
with:
dockerfile: ./kotlin/Dockerfile
# Setup Docker buildx to support multi-platform images
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
- name: Login to DockerHub
uses: docker/login-action@v3
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} # Password or personal access token used to log in to a Docker registry. If not set then no login will occur.
- name: Set LATEST_REPO_TAG env
run: echo "LATEST_REPO_TAG=$(git ls-remote --tags --sort='v:refname' | tail -n1 | sed 's/.*\///; s/\^{}//')" >> $GITHUB_ENV
# GitHub Action to build and push Docker images including multistage builds
- name: Push to DockerHub
uses: docker/build-push-action@v6 # https://github.com/docker/build-push-action
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
with:
context: ./kotlin
file: ./kotlin/Dockerfile
platforms: linux/arm64,linux/amd64 #linux/amd64,linux/386
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/angkor-api:latest
build-args: |
LATEST_REPO_TAG=${{ env.LATEST_REPO_TAG }}
- name: Publish Action Event
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
run: |
aws sns publish --topic-arn $TOPIC_ARN --message "{\"action\":\"deploy-api\",\"workflow\":\"$GITHUB_WORKFLOW\"}" \
--message-attributes "GITHUB_SHA={DataType=String,StringValue=\"$GITHUB_SHA\"}, GITHUB_RUN_ID={DataType=String,StringValue=\"$GITHUB_RUN_ID\"}"
env:
TOPIC_ARN: ${{ secrets.TOPIC_ARN }}
- name: Send Kafka Publish Event with Docker
id: send-kafka-pub-event-playground # becomes $GITHUB_ACTION
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
run: |
docker run -e KAFKA_PRODUCER_TOPIC_URL="${{secrets.KAFKA_PRODUCER_TOPIC_URL}}" -e KAFKA_PRODUCER_API_SECRET="${{secrets.KAFKA_PRODUCER_API_SECRET}}" ghcr.io/tillkuhn/rubin:latest \
-ce -key "$GITHUB_REPOSITORY/$GITHUB_WORKFLOW/$GITHUB_JOB" -header "producer=rubin/cli latest" \
-source "urn:ci:$GITHUB_REPOSITORY/$GITHUB_WORKFLOW/$GITHUB_JOB" \
-type "net.timafe.event.ci.published.v1" -subject "docker.io/${GITHUB_REPOSITORY}-api" \
-record "{\"action\":\"$GITHUB_ACTION\",\"actor\":\"$GITHUB_ACTOR\",\"commit\":\"$GITHUB_SHA\",\"run_url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"version\":\"${GITHUB_REF#refs/*/}\"}"
# Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action
# - https://github.com/aquasecurity/trivy-action
# - https://blog.aquasec.com/github-vulnerability-scanner-trivy
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
if: github.ref == 'refs/heads/main' # this is how to skip only specific steps if not main
# workaround trivy image scan suddenly timing out aka maven central issue
# @see https://github.com/aquasecurity/trivy/issues/3421
# @see https://github.com/aquasecurity/trivy-action/issues/190#issuecomment-1380433570
env:
TRIVY_OFFLINE_SCAN: true
with:
image-ref: 'docker.io/${{ secrets.DOCKER_USERNAME }}/angkor-api:latest'
format: 'sarif'
output: 'trivy-results.sarif'
# Using Trivy with GitHub Code Scanning
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
with:
sarif_file: 'trivy-results.sarif'
# Run Sonar after merge into main, run it at the end b/c of Noisy ‘Could not report issue with code highlighting’ stacktrace on every execution
# https://community.sonarsource.com/t/noisy-could-not-report-issue-with-code-highlighting-stacktrace-on-every-execution/114979
# https://community.sonarsource.com/t/unable-to-import-android-lint-report-file-s/98737
# https://sonarsource.atlassian.net/browse/SONARKT-365
# https://sonarsource.atlassian.net/browse/SONARKT-354 (duplicate of #365)
- name: Run Sonar Task and publish results
working-directory: ./kotlin
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) # run only on main
run: |
SONAR_TOKEN=$(aws ssm get-parameter --name /angkor/prod/SONAR_TOKEN --with-decryption --query 'Parameter.Value' --output text)
./gradlew --console=plain sonar -Dsonar.token=${SONAR_TOKEN} -Dsonar.projectVersion=${{env.RELEASE_VERSION}} -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=tillkuhn
# sonar is really unreliable these days, this should not stop the entire build (until it gets more stable)
continue-on-error: true
timeout-minutes: 10
env:
CI: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # for Sonarcloud Needed to get PR information, if any