Skip to content

Workflow file for this run

name: Spring Boot Multi-module K3s Deployment
on:
push:
branches:
- develop
env:
REGISTRY: "ghcr.io"
NAMESPACE: "depromeet"
IMAGE_NAME: "kasukabe-server"
jobs:
setup:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
deploy_target: ${{ steps.set-env.outputs.DEPLOY_TARGET }}
sha_short: ${{ steps.sha_short.outputs.sha_short }}
changed_modules: ${{ steps.detect-changes.outputs.changed_modules }}
steps:
- name: Checkout code
uses: actions/checkout@v1
- name: Setup Env
id: set-env
run: |
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
echo "DEPLOY_TARGET=production" >> $GITHUB_OUTPUT
else
echo "DEPLOY_TARGET=development" >> $GITHUB_OUTPUT
fi
- name: Get short SHA
id: sha_short
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Detect Changed Modules
id: detect-changes
run: |
CHANGED_MODULES=""
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^layer-api/ ]]; then
if [ -z "$CHANGED_MODULES" ]; then
CHANGED_MODULES="layer-api"
else
CHANGED_MODULES="$CHANGED_MODULES,layer-api"
fi
fi
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^layer-batch/ ]]; then
if [ -z "$CHANGED_MODULES" ]; then
CHANGED_MODULES="layer-batch"
else
CHANGED_MODULES="$CHANGED_MODULES,layer-batch"
fi
fi
echo "changed_modules=$CHANGED_MODULES"
echo "changed_modules=$CHANGED_MODULES" >> $GITHUB_OUTPUT
build:
name: build
needs: [ setup ]
runs-on: ubuntu-latest
if: ${{ needs.setup.outputs.changed_modules != '' }}
permissions:
contents: read
packages: write
env:
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}
APPLICATION_SECRET_PROPERTIES: ${{ secrets.APPLICATION_SECRET_PROPERTIES }}
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
SHA_SHORT: ${{ needs.setup.outputs.sha_short }}
CHANGED_MODULES: ${{ needs.setup.outputs.changed_modules }}
steps:
- name: Setup Java
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'
- name: Checkout sources
uses: actions/checkout@v4
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup Gradle
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
- name: Create application-secret.properties
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
echo "${APPLICATION_SECRET_PROPERTIES}" > ./$MODULE/src/main/resources/application-secret.properties
if [ "$MODULE" = "layer-batch" ]; then
cp -R ./layer-api/src/main/resources/tokens ./$MODULE/src/main/resources/tokens
fi
done
- name: Build Changed Modules
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
./gradlew :$MODULE:build
done
- name: Run Tests for Changed Modules
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
./gradlew :$MODULE:test
done
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE_NAME }}/$MODULE
- name: Push Docker Images for Changed Modules
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
IMAGE_TAG="${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE_NAME }}/$MODULE:${{ env.SHA_SHORT }}"
docker build --build-arg SPRING_PROFILE=dev ./$MODULE -t $IMAGE_TAG
docker push $IMAGE_TAG
done
deploy:
name: Deploy to K3s
needs: [ build, setup ]
runs-on: ubuntu-latest
if: ${{ needs.setup.outputs.changed_modules != '' }}
env:
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}
SHA_SHORT: ${{ needs.setup.outputs.sha_short }}
CHANGED_MODULES: ${{ needs.setup.outputs.changed_modules }}
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Install kubectl
uses: azure/setup-kubectl@v1
with:
version: 'v1.21.0'
- name: Set up kubeconfig
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBE_CONFIG }}" > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Delete existing deployments (if exists)
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
kubectl delete deployment $MODULE-deployment --ignore-not-found
done
- name: Create K3s deployment files
run: |
TARGET=${{ env.DEPLOY_TARGET}}
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
if [ "$MODULE" = "layer-api" ]; then
PORT=8080
elif [ "$MODULE" = "layer-batch" ]; then
PORT=8085
else
PORT=8080
fi
cat <<EOF > deployment-$MODULE.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: $MODULE-$TARGET
namespace: default
labels:
app: $MODULE-$TARGET
spec:
replicas: 1
selector:
matchLabels:
app: $MODULE-$TARGET
template:
metadata:
labels:
app: $MODULE-$TARGET
spec:
containers:
- name: $MODULE-$TARGET
image: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE_NAME }}/$MODULE:${{ env.SHA_SHORT }}
ports:
- containerPort: $PORT
env:
- name: TZ
value: "Asia/Seoul"
- name: SPRING_PROFILES_ACTIVE
value: "${{ env.DEPLOY_TARGET }}"
volumeMounts:
- name: secret-volume
mountPath: /config/application-secret.properties
subPath: application-secret.properties
- name: log-volume
mountPath: /log
- name: tokens-volume
mountPath: /config/tokens
volumes:
- name: secret-volume
secret:
secretName: app-secret-$TARGET
- name: log-volume
hostPath:
path: /${{ env.DEPLOY_TARGET }}/log/$MODULE
type: DirectoryOrCreate
- name: tokens-volume
hostPath:
path: /home/tokens
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: $MODULE-service-$TARGET
namespace: default
labels:
app: $MODULE-$TARGET
spec:
selector:
app: $MODULE-$TARGET
ports:
- protocol: TCP
port: 80
targetPort: $PORT
EOF
done
- name: Deploy to K3s
run: |
for MODULE in $(echo $CHANGED_MODULES | tr "," "\n"); do
kubectl apply -f deployment-$MODULE.yaml
done