change deploy.yml #50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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: 🔧 Setup image name | |
| run: echo "IMAGE_LOWER=$(echo '${{ env.IMAGE_NAME }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV | |
| - name: 📝 Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_LOWER }} | |
| 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/ssh-action@v1.0.0 | |
| with: | |
| host: ${{ env.RASPBERRY_PI_HOST }} | |
| username: ${{ env.RASPBERRY_PI_USER }} | |
| key: ${{ secrets.RASPBERRY_PI_SSH_KEY }} | |
| port: 2022 | |
| 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 }}" | |
| export MYSQL_ROOT_PASSWORD="${{ secrets.MYSQL_ROOT_PASSWORD }}" | |
| export MYSQL_DATABASE="${{ secrets.MYSQL_DATABASE }}" | |
| export MYSQL_USER="${{ secrets.MYSQL_USER }}" | |
| export MYSQL_PASSWORD="${{ secrets.MYSQL_PASSWORD }}" | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin | |
| export IMAGE_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]') | |
| docker pull ${{ env.REGISTRY }}/$IMAGE_LOWER:${{ github.sha }}-arm64 | |
| docker tag ${{ env.REGISTRY }}/$IMAGE_LOWER:${{ github.sha }}-arm64 dormung-springboot:latest | |
| chmod +x deploy.sh | |
| ./deploy.sh deploy | |
| - name: 🧪 Verify deployment | |
| uses: appleboy/ssh-action@v1.0.0 | |
| with: | |
| host: ${{ env.RASPBERRY_PI_HOST }} | |
| username: ${{ env.RASPBERRY_PI_USER }} | |
| key: ${{ secrets.RASPBERRY_PI_SSH_KEY }} | |
| port: 2022 | |
| script: | | |
| cd /home/yoon/goormthon-java | |
| sleep 120 | |
| curl -sf http://localhost/api/actuator/health && echo "✅ Passed" || echo "❌ Failed" | |
| ./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/ssh-action@v1.0.0 | |
| with: | |
| host: ${{ env.RASPBERRY_PI_HOST }} | |
| username: ${{ env.RASPBERRY_PI_USER }} | |
| key: ${{ secrets.RASPBERRY_PI_SSH_KEY }} | |
| port: 2022 | |
| script: | | |
| cd /home/yoon/goormthon-java | |
| echo "🔄 Auto rollback initiated" | |
| ./deploy.sh rollback || echo "Rollback failed - manual intervention required" |