Skip to content

deploy

deploy #28

Workflow file for this run

name: Build and Deploy SpringBoot to Raspberry Pi
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
RASPBERRY_PI_HOST: ${{ secrets.RASPBERRY_PI_HOST }}
RASPBERRY_PI_USER: ${{ secrets.RASPBERRY_PI_USER }}
MYSQL_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }}
MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }}
MYSQL_USER: ${{ secrets.MYSQL_USER }}
MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 🔄 Checkout code
uses: actions/checkout@v4
- name: ☕ Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: 📦 Cache Gradle packages
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
- name: 🧪 Test SpringBoot
run: |
chmod +x gradlew
./gradlew clean test
build-and-deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: 🔄 Checkout code
uses: actions/checkout@v4
- name: 🐳 Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 🔐 Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 📝 Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
flavor: |
suffix=-arm64
- name: 🏗️ Build and push SpringBoot image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: 🚀 Deploy to Raspberry Pi
uses: appleboy/[email protected]
with:
host: ${{ env.RASPBERRY_PI_HOST }}
username: ${{ env.RASPBERRY_PI_USER }}
key: ${{ secrets.RASPBERRY_PI_SSH_KEY }}
script: |
cd /home/yoon/goormthon-java
git pull origin main
export BUILD_TAG="${{ github.sha }}"
export DOCKER_REGISTRY="${{ env.REGISTRY }}"
export DOCKER_REPO="${{ env.IMAGE_NAME }}"
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64
docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}-arm64 dormung-springboot:latest
chmod +x deploy.sh
./deploy.sh deploy
- name: 🧪 Verify deployment
uses: appleboy/[email protected]
with:
host: ${{ env.RASPBERRY_PI_HOST }}
username: ${{ env.RASPBERRY_PI_USER }}
key: ${{ secrets.RASPBERRY_PI_SSH_KEY }}
script: |
cd /home/yoon/goormthon-java
sleep 30
if curl -sf http://localhost/api/actuator/health; then
echo "✅ SpringBoot health check passed"
else
echo "❌ SpringBoot health check failed"
exit 1
fi
./deploy.sh status
- name: 📢 Discord Success Notification
if: success()
uses: Ilshidur/action-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
with:
args: |
🎉 **배포 성공!**
📦 **프로젝트**: ${{ github.repository }}
🌿 **브랜치**: ${{ github.ref_name }}
📝 **커밋**: `${{ github.sha }}`
👤 **작성자**: ${{ github.actor }}
💬 **메시지**: ${{ github.event.head_commit.message }}
- name: 📢 Discord Failure Notification
if: failure()
uses: Ilshidur/action-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
with:
args: |
❌ **배포 실패!**
📦 **프로젝트**: ${{ github.repository }}
🌿 **브랜치**: ${{ github.ref_name }}
📝 **커밋**: `${{ github.sha }}`
👤 **작성자**: ${{ github.actor }}
💬 **메시지**: ${{ github.event.head_commit.message }}
🔄 **자동 롤백이 실행됩니다**
- name: 🔄 Auto Rollback on Failure
if: failure()
uses: appleboy/[email protected]
with:
host: ${{ env.RASPBERRY_PI_HOST }}
username: ${{ env.RASPBERRY_PI_USER }}
key: ${{ secrets.RASPBERRY_PI_SSH_KEY }}
script: |
cd /home/yoon/goormthon-java
echo "🔄 Auto rollback initiated"
./deploy.sh rollback || echo "Rollback failed - manual intervention required"