๐จ [BOT] Apply Spotless code style (#36) #73
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: Spring Boot CI/CD with AWS | |
| # ์ํฌํ๋ก์ฐ๊ฐ ์คํ๋ ์กฐ๊ฑด ์ ์ | |
| on: | |
| push: | |
| branches: [ develop ] | |
| pull_request: | |
| types: [ opened, edited ] # PR ์์ฑ/์์ ์์๋ง ๋์ํ๋๋ก ํ์ ๋ช ์ | |
| branches: [ develop ] | |
| # PR ์์ฑ, ์ฝ๋ ์์ , AWS OIDC ํ ํฐ ์์ฒญ์ ์ํ ๊ถํ ์ค์ | |
| permissions: | |
| id-token: write | |
| contents: write | |
| pull-requests: write | |
| checks: write | |
| jobs: | |
| # ์ฝ๋ ํฌ๋งทํ , ๋น๋, ํ ์คํธ๋ฅผ ์ฒ๋ฆฌํ๋ Job | |
| build: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build-success: ${{ steps.build-status.outputs.success }} | |
| steps: | |
| # 1. ์์ค ์ฝ๋ ์ฒดํฌ์์ | |
| - name: Checkout Source Code | |
| uses: actions/checkout@v4 | |
| # 2. JDK 17 ์ค์น | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'corretto' | |
| # === [์ถ๊ฐ๋ ๋ถ๋ถ] PR ํ ํ๋ฆฟ ๊ฒ์ฌ๊ธฐ === | |
| - name: Check PR Template | |
| if: github.event_name == 'pull_request' && github.event.pull_request.body == '' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| // ํ ํ๋ฆฟ ํ์ผ์ด ์๋ ๊ฒฝ๋ก๋ฅผ ์ ํํ ์ง์ ํด์ผ ํฉ๋๋ค. | |
| // ์: .github/pr_templates/for_develop.md | |
| const template = fs.readFileSync('.github/pr_templates/for_develop.md', 'utf8'); | |
| github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `๐จ **PR ๋ณธ๋ฌธ์ด ๋น์ด์์ต๋๋ค!**\n\n์๋ ํ ํ๋ฆฟ์ ๋ณต์ฌํ์ฌ PR ๋ด์ฉ์ ์์ฑํด์ฃผ์ธ์.\n\n---\n\n${template}` | |
| }); | |
| core.setFailed('PR ๋ณธ๋ฌธ์ ํ ํ๋ฆฟ์ ๋ง๊ฒ ์์ฑํด์ฃผ์ธ์.'); | |
| # ======================================= | |
| # 3. Gradle ์บ์ ์ค์ | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| # 4. Gradle ์คํ ๊ถํ ๋ถ์ฌ | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x ./gradlew | |
| # 5. ์ฝ๋ ํฌ๋งทํ ๊ฒ์ฌ ๋๋ ์ ์ฉ | |
| - name: Check code formatting (PR) | |
| if: github.event_name == 'pull_request' | |
| run: ./gradlew spotlessCheck | |
| - name: Apply code formatting (Push) | |
| if: github.event_name == 'push' | |
| run: ./gradlew spotlessApply | |
| # 6. ํฌ๋งทํ ๋ณ๊ฒฝ์ฌํญ์ผ๋ก PR ์์ฑ (์ ๋ต 2) | |
| - name: Create Pull Request with formatting changes | |
| if: github.event_name == 'push' | |
| id: create_pr # step์ id๋ฅผ ์ง์ ํ์ฌ output์ ์ฐธ์กฐํ ์ ์๋๋ก ํจ | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| commit-message: "๐จ [BOT] Apply Spotless code style" | |
| title: "๐จ [BOT] Apply Spotless code style" | |
| body: | | |
| Spotless ๋ด์ด ์ฝ๋ ์คํ์ผ์ ์๋์ผ๋ก ์์ ํ์ต๋๋ค. | |
| ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ๊ณ ๋ณํฉํด ์ฃผ์ธ์. | |
| *This PR was auto-generated by a GitHub Action.* | |
| branch: "spotless-patches/${{ github.ref_name }}" | |
| delete-branch: true | |
| labels: bot, chore | |
| # 7. Gradle๋ก ๋น๋ ๋ฐ ๋จ์ ํ ์คํธ ์คํ | |
| # ์ค์: PR์ด ์์ฑ๋์ง ์์์ ๋๋ง(์ฝ๋ ํฌ๋งท์ด ์๋ฒฝํ ๋๋ง) ๋น๋/ํ ์คํธ๋ฅผ ์งํํฉ๋๋ค. | |
| - name: Build with Gradle | |
| if: steps.create_pr.outputs.pull-request-number == '' | |
| env: | |
| # Spring Boot๋ ์ด ํ๊ฒฝ ๋ณ์(API_TOKEN)๋ฅผ ์ธ์ํ์ฌ | |
| # application.properties์ ${API_TOKEN} ํ๋ ์ด์คํ๋๋ฅผ ์นํํฉ๋๋ค. | |
| API_TOKEN: ${{ secrets.REPLICATE_API_TOKEN }} | |
| # ๋ง์ฝ ํ ์คํธ DB ๋ฑ ๋ค๋ฅธ ํ๊ฒฝ ๋ณ์๊ฐ ํ์ํ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ถ๊ฐํ ์ ์์ต๋๋ค. | |
| # DB_URL: ${{ secrets.DB_URL_TEST }} | |
| # DB_USERNAME: ${{ secrets.DB_USERNAME_TEST }} | |
| # DB_PASSWORD: ${{ secrets.DB_PASSWORD_TEST }} | |
| run: ./gradlew build | |
| # 8. ํ ์คํธ ๊ฒฐ๊ณผ ์ ๋ก๋ | |
| - name: Publish Test Results | |
| if: (success() || failure()) && steps.create_pr.outputs.pull-request-number == '' | |
| uses: dorny/test-reporter@v1 | |
| with: | |
| name: Gradle Tests | |
| path: build/test-results/test/*.xml | |
| reporter: java-junit | |
| # 9. ๋น๋ ์ฑ๊ณต ์ํ ์ค์ | |
| - name: Set build success status | |
| id: build-status | |
| if: success() && steps.create_pr.outputs.pull-request-number == '' | |
| run: echo "success=true" >> $GITHUB_OUTPUT | |
| # ==================================================================== | |
| # ์ดํ ๋ฐฐํฌ ๊ด๋ จ Job๋ค์ 'build' Job์ ์ต์ข ์ฑ๊ณต ์ฌ๋ถ์ ๋ฐ๋ผ ์คํ๋ฉ๋๋ค. | |
| # ==================================================================== | |
| # EC2 ์ํ ํ์ธ ์์ | |
| check-ec2: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' && needs.build.outputs.build-success == 'true' | |
| outputs: | |
| ec2-available: ${{ steps.check-ec2-status.outputs.available }} | |
| steps: | |
| - name: Check EC2 instance status | |
| id: check-ec2-status | |
| run: | | |
| if timeout 10 nc -z ${{ secrets.EC2_HOST }} 22 2>/dev/null; then | |
| echo "EC2 instance is reachable" | |
| echo "available=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "EC2 instance is not reachable or stopped" | |
| echo "available=false" >> $GITHUB_OUTPUT | |
| fi | |
| continue-on-error: true | |
| # Docker ์ด๋ฏธ์ง ๋น๋ ๋ฐ ECR ํธ์ | |
| build-and-push-image: | |
| runs-on: ubuntu-latest | |
| needs: [build, check-ec2] | |
| if: github.event_name == 'push' && needs.build.outputs.build-success == 'true' && needs.check-ec2.outputs.ec2-available == 'true' | |
| outputs: | |
| image-pushed: ${{ steps.push-status.outputs.success }} | |
| steps: | |
| - name: Checkout Source Code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials using OIDC | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Build, tag, and push image to Amazon ECR | |
| id: build-image | |
| env: | |
| ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
| ECR_REPOSITORY: cp_main_be | |
| IMAGE_TAG: ${{ github.sha }} | |
| run: | | |
| docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . | |
| docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest | |
| docker push --all-tags $ECR_REGISTRY/$ECR_REPOSITORY | |
| - name: Set push success status | |
| id: push-status | |
| if: success() | |
| run: echo "success=true" >> $GITHUB_OUTPUT | |
| # EC2 ๋ฐฐํฌ ์์ | |
| deploy: | |
| runs-on: ubuntu-latest | |
| needs: [build, check-ec2, build-and-push-image] | |
| if: github.event_name == 'push' && needs.build-and-push-image.outputs.image-pushed == 'true' | |
| steps: | |
| - name: Configure AWS credentials using OIDC | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Deploy to EC2 instance | |
| uses: appleboy/ssh-action@master | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| script: | | |
| # AWS ECR ๋ก๊ทธ์ธ | |
| aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }} | |
| # ์ต์ ์ด๋ฏธ์ง pull | |
| docker pull ${{ steps.login-ecr.outputs.registry }}/cp_main_be:latest | |
| # ๊ธฐ์กด ์ปจํ ์ด๋ ์ค์ง ๋ฐ ์ญ์ | |
| if [ $(docker ps -a -q -f name=spring-app-container) ]; then | |
| docker stop spring-app-container | |
| docker rm spring-app-container | |
| fi | |
| # 1. GitHub Secret์์ Firebase ํค ํ์ผ ์์ฑ | |
| echo "${{ secrets.FIREBASE_KEY_JSON }}" > /home/${{ secrets.EC2_USER }}/serviceAccountKey.json | |
| # 2. ๋ชจ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ํฌํจํ์ฌ ์ ์ปจํ ์ด๋ ์คํ | |
| docker run -d --name spring-app-container -p 8080:8080 \ | |
| -e SPRING_PROFILES_ACTIVE=prod \ | |
| -e DB_URL="${{ secrets.DB_URL }}" \ | |
| -e DB_USERNAME="${{ secrets.DB_USERNAME }}" \ | |
| -e DB_PASSWORD="${{ secrets.DB_PASSWORD }}" \ | |
| -e R2_ENDPOINT="${{ secrets.R2_ENDPOINT }}" \ | |
| -e R2_BUCKET="${{ secrets.R2_BUCKET }}" \ | |
| -e R2_ACCESS_KEY="${{ secrets.R2_ACCESS_KEY }}" \ | |
| -e R2_SECRET_KEY="${{ secrets.R2_SECRET_KEY }}" \ | |
| -e JWT_SECRET="${{ secrets.JWT_SECRET }}" \ | |
| -e FASTAPI_URL="${{ secrets.FASTAPI_URL }}" \ | |
| -e API_TOKEN="${{ secrets.API_TOKEN }}" \ | |
| -e GOOGLE_APPLICATION_CREDENTIALS=/app/serviceAccountKey.json \ | |
| -v /home/${{ secrets.EC2_USER }}/serviceAccountKey.json:/app/serviceAccountKey.json \ | |
| ${{ steps.login-ecr.outputs.registry }}/cp_main_be:latest | |
| # ์ํฌํ๋ก์ฐ ์คํ ๊ฒฐ๊ณผ ์์ฝ | |
| summary: | |
| runs-on: ubuntu-latest | |
| needs: [build, check-ec2, build-and-push-image, deploy] | |
| if: always() | |
| steps: | |
| - name: Workflow Summary | |
| run: | | |
| echo "## ์ํฌํ๋ก์ฐ ์คํ ๊ฒฐ๊ณผ" >> $GITHUB_STEP_SUMMARY | |
| echo "| ๋จ๊ณ | ์ํ |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| ๋น๋ ๋ฐ ํ ์คํธ | ${{ needs.build.result == 'success' && 'โ ์ฑ๊ณต' || 'โ ์คํจ/๊ฑด๋๋' }} |" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ github.event_name }}" == "push" ]]; then | |
| echo "| EC2 ์ํ ํ์ธ | ${{ needs.check-ec2.result == 'success' && 'โ ์ฑ๊ณต' || (needs.check-ec2.result == 'skipped' && 'โญ๏ธ ๊ฑด๋๋' || 'โ ์คํจ') }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Docker ์ด๋ฏธ์ง ๋น๋/ํธ์ | ${{ needs.build-and-push-image.result == 'success' && 'โ ์ฑ๊ณต' || (needs.build-and-push-image.result == 'skipped' && 'โญ๏ธ ๊ฑด๋๋' || 'โ ์คํจ') }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| EC2 ๋ฐฐํฌ | ${{ needs.deploy.result == 'success' && 'โ ์ฑ๊ณต' || (needs.deploy.result == 'skipped' && 'โญ๏ธ ๊ฑด๋๋' || 'โ ์คํจ') }} |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| ๋ฐฐํฌ ๊ด๋ จ ์์ | โญ๏ธ ๊ฑด๋๋ (PR ์ด๋ฒคํธ) |" >> $GITHUB_STEP_SUMMARY | |
| fi |