fix : r2 region setting fix #435
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 ] | |
| branches: [ develop ] | |
| permissions: | |
| id-token: write | |
| contents: write | |
| pull-requests: write | |
| checks: write | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Source Code | |
| uses: actions/checkout@v4 | |
| - 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'); | |
| 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 본문을 템플릿에 맞게 작성해주세요.') | |
| - 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- | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x ./gradlew | |
| - 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 | |
| - name: Create Pull Request with formatting changes | |
| if: github.event_name == 'push' | |
| id: create_pr | |
| 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 | |
| - name: Build with Gradle | |
| run: ./gradlew build --stacktrace --info | |
| env: | |
| R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} | |
| R2_BUCKET: ${{ secrets.R2_BUCKET }} | |
| R2_ACCESS_KEY: ${{ secrets.R2_ACCESS_KEY }} | |
| R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }} | |
| R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} | |
| JWT_SECRET: ${{ secrets.JWT_SECRET }} | |
| FASTAPI_URL: ${{ secrets.FASTAPI_URL }} | |
| API_TOKEN: ${{ secrets.API_TOKEN }} | |
| check-ec2: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' | |
| 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 | |
| build-and-push-image: | |
| runs-on: ubuntu-latest | |
| needs: [build, check-ec2] | |
| if: github.event_name == 'push' && 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 --no-cache -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 | |
| 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: 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: Create Firebase Service Account Key File | |
| env: | |
| FIREBASE_KEY_JSON: ${{ secrets.FIREBASE_KEY_JSON }} | |
| run: echo "$FIREBASE_KEY_JSON" > serviceAccountKey.json | |
| - name: Create .env File | |
| run: | | |
| cat << EOF > ./.env | |
| R2_ENDPOINT=${{ secrets.R2_ENDPOINT }} | |
| R2_BUCKET=${{ secrets.R2_BUCKET }} | |
| R2_ACCESS_KEY=${{ secrets.R2_ACCESS_KEY }} | |
| R2_SECRET_KEY=${{ secrets.R2_SECRET_KEY }} | |
| R2_ACCOUNT_ID= ${{ secrets.R2_ACCOUNT_ID }} | |
| JWT_SECRET=${{ secrets.JWT_SECRET }} | |
| FASTAPI_URL=${{ secrets.FASTAPI_URL }} | |
| API_TOKEN=${{ secrets.API_TOKEN }} | |
| DB_URL=${{ secrets.DB_URL }} | |
| DB_USERNAME=${{ secrets.DB_USERNAME }} | |
| DB_PASSWORD=${{ secrets.DB_PASSWORD }} | |
| FIREBASE_KEY_JSON='${{ secrets.FIREBASE_KEY_JSON }}' | |
| EOF | |
| - name: Transfer necessary files to EC2 | |
| uses: appleboy/scp-action@master | |
| with: | |
| host: ${{ secrets.EC2_HOST }} | |
| username: ${{ secrets.EC2_USER }} | |
| key: ${{ secrets.EC2_SSH_KEY }} | |
| # 👇 전송 파일 목록에서 .json 파일 삭제 | |
| source: "docker-compose.yml,.env" | |
| target: "/home/${{ secrets.EC2_USER }}/app" | |
| - 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: | | |
| cd /home/${{ secrets.EC2_USER }}/app | |
| aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }} | |
| export ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }} | |
| # 1. 기존에 실행 중인 컨테이너를 먼저 내립니다. (중지 및 삭제) | |
| docker compose down | |
| # 2. 최신 이미지를 받아옵니다. | |
| docker compose pull | |
| # 3. 새로운 컨테이너를 실행합니다. | |
| docker compose up -d --remove-orphans | |
| 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' && '✅ 성공' || '❌ 실패/건너뜀' }} |" | |
| if [[ "${{ github.event_name }}" == "push" ]]; then | |
| echo "| EC2 상태 확인 | ${{ needs.check-ec2.result == 'success' && '✅ 성공' || (needs.check-ec2.result == 'skipped' && '⏭️ 건너뜀' || '❌ 실패') }} |" | |
| echo "| Docker 이미지 빌드/푸시 | ${{ needs.build-and-push-image.result == 'success' && '✅ 성공' || (needs.build-and-push-image.result == 'skipped' && '⏭️ 건너뜀' || '❌ 실패') }} |" | |
| echo "| EC2 배포 | ${{ needs.deploy.result == 'success' && '✅ 성공' || (needs.deploy.result == 'skipped' && '⏭️ 건너뜀' || '❌ 실패') }} |" | |
| else | |
| echo "| 배포 관련 작업 | ⏭️ 건너뜀 (PR 이벤트) |" | |
| fi |