From 1dcd6bab032888dda3379a3405dc7a11f4395c56 Mon Sep 17 00:00:00 2001 From: hgkim Date: Sat, 20 Dec 2025 18:11:55 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20Admin=20API=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=201.0.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-admin-api/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-admin-api/VERSION b/bottlenote-admin-api/VERSION index b6bb49ad1..ee90284c2 100644 --- a/bottlenote-admin-api/VERSION +++ b/bottlenote-admin-api/VERSION @@ -1 +1 @@ -1.0.3-2 +1.0.4 From fabe39319bb42616fe7b92d9e9f6f984427a08a3 Mon Sep 17 00:00:00 2001 From: hgkim Date: Sat, 20 Dec 2025 18:56:28 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20ArgoCD=20=EA=B8=B0=EB=B0=98=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=20=EA=B0=9C=EB=B0=9C=20=EB=B0=B0=ED=8F=AC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy_development.yml | 138 --------- .github/workflows/deploy_v2_product_api.yml | 118 +++++++ .../deprecated/deploy_development.yml.bak | 291 +++--------------- git.environment-variables | 2 +- 4 files changed, 170 insertions(+), 379 deletions(-) delete mode 100644 .github/workflows/deploy_development.yml create mode 100644 .github/workflows/deploy_v2_product_api.yml diff --git a/.github/workflows/deploy_development.yml b/.github/workflows/deploy_development.yml deleted file mode 100644 index 205e68d3f..000000000 --- a/.github/workflows/deploy_development.yml +++ /dev/null @@ -1,138 +0,0 @@ -# act workflow_dispatch -W .github/workflows/deploy_development.yml --secret-file .secrets --container-architecture linux/arm64 -name: Deploy to Development - -on: - workflow_dispatch: - pull_request: - types: [ closed ] - branches: - - dev - -concurrency: - group: "deploy-development" - cancel-in-progress: true - -env: - ECR_REGION: ap-northeast-2 - ECR_REGISTRY: 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com - ECR_REPOSITORY: ecr-bottle-note-api - -jobs: - build-and-push: - if: | - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && github.event.pull_request.merged == true) - runs-on: ubuntu-24.04-arm - steps: - - name: checkout code with submodules - uses: actions/checkout@v4 - with: - submodules: true - token: ${{ secrets.GIT_ACCESS_TOKEN }} - - name: setup gradle cache - 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: configure aws credentials - uses: aws-actions/configure-aws-credentials@v2 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.ECR_REGION }} - - name: login to amazon ecr - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 - - name: setup docker buildx for dev (cache support) - uses: docker/setup-buildx-action@v3 - with: - driver: docker-container - - name: generate build timestamp - id: build-time - run: echo "time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT - - name: generate short commit sha - id: short-sha - run: echo "sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT - - name: build and push dev image to ecr (github actions cache) - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/arm64 - push: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:development_${{ steps.short-sha.outputs.sha }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:development_latest - build-args: | - GIT_COMMIT=${{ github.sha }} - GIT_BRANCH=${{ github.ref_name }} - BUILD_TIME=${{ steps.build-time.outputs.time }} - cache-from: type=gha,scope=development - cache-to: type=gha,scope=development,mode=max - - update-kustomize-tag: - needs: build-and-push - runs-on: ubuntu-latest - steps: - - name: checkout code with submodules - uses: actions/checkout@v4 - with: - submodules: true - token: ${{ secrets.GIT_ACCESS_TOKEN }} - - # Kustomize 설치 (GitHub Marketplace의 검증된 액션 사용) - # GitHub Actions에서는 GITHUB_TOKEN이 자동 제공됨 - - name: setup kustomize - uses: imranismail/setup-kustomize@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: update image tag with kustomize - run: | - COMMIT_SHA="${{ github.sha }}" - IMAGE_TAG="development_${COMMIT_SHA:0:7}" - - echo "📦 업데이트할 이미지 태그: $IMAGE_TAG" - - cd git.environment-variables - - # detached HEAD 해결: main 브랜치로 전환 (파일 수정 전) - git checkout main - - cd deploy/overlays/development - - # Kustomize로 이미지 태그 업데이트 - kustomize edit set image \ - 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api=536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api:${IMAGE_TAG} - - echo "✅ kustomization.yaml 업데이트 완료" - git diff kustomization.yaml - - - name: commit and push to environment-variables - run: | - cd git.environment-variables - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - git add deploy/overlays/development/kustomization.yaml - - git commit -m "chore(dev): update image tag to ${GITHUB_SHA:0:7} - - Updated by GitHub Actions - Commit: ${{ github.sha }} - Branch: ${{ github.ref_name }} - Workflow: ${{ github.workflow }}" - - git push origin main - - echo "✅ Git 커밋 및 푸시 완료" - echo "🔄 ArgoCD가 변경사항을 감지하여 자동 배포를 시작합니다" - - - - # Oracle 서버 직접 배포는 제거됨 (ArgoCD로 완전 전환) - # 이전 deploy-to-servers job은 .bak 파일 참조 diff --git a/.github/workflows/deploy_v2_product_api.yml b/.github/workflows/deploy_v2_product_api.yml new file mode 100644 index 000000000..c171fb558 --- /dev/null +++ b/.github/workflows/deploy_v2_product_api.yml @@ -0,0 +1,118 @@ +name: deploy v2 product api + +on: + workflow_dispatch: + push: + branches: + - main + +concurrency: + group: "deploy-product" + cancel-in-progress: true + +env: + IMAGE_NAME: bottlenote-product-api + +jobs: + build-and-push: + runs-on: ubuntu-24.04-arm + outputs: + version: ${{ steps.version.outputs.version }} + image-tag: ${{ steps.version.outputs.image-tag }} + image-digest: ${{ steps.build.outputs.image-digest }} + steps: + - name: checkout code with submodules + uses: actions/checkout@v4 + with: + submodules: true + token: ${{ secrets.GIT_ACCESS_TOKEN }} + + - name: read product version + id: version + run: | + VERSION=$(cat bottlenote-product-api/VERSION | tr -d '[:space:]') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "image-tag=product_${VERSION}_development" >> $GITHUB_OUTPUT + echo "Product version: $VERSION" + + - name: build and push to registry + id: build + uses: ./.github/actions/docker-build-push + with: + registry-url: ${{ secrets.REGISTRY_ADDRESS }} + registry-username: ${{ secrets.REGISTRY_USERNAME }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + image-name: ${{ env.IMAGE_NAME }} + image-tag: product_${{ steps.version.outputs.version }}_development + additional-tags: product_latest + dockerfile: Dockerfile + context: . + platforms: linux/arm64 + cache-scope: product + image-title: "BottleNote Product API" + image-description: "BottleNote Product API Server" + image-vendor: "BottleNote" + image-authors: "BottleNote Team" + sign-image: 'true' + cosign-key-path: 'git.environment-variables/storage/docker-registry/cosign.key' + cosign-password: ${{ secrets.COSIGN_PASSWORD }} + + update-development: + needs: build-and-push + runs-on: ubuntu-latest + steps: + - name: checkout code with submodules + uses: actions/checkout@v4 + with: + submodules: true + token: ${{ secrets.GIT_ACCESS_TOKEN }} + + - name: setup kustomize + uses: imranismail/setup-kustomize@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: update development image tag + run: | + IMAGE_TAG="${{ needs.build-and-push.outputs.image-tag }}" + REGISTRY="${{ secrets.REGISTRY_ADDRESS }}" + + echo "Updating development image tag: $IMAGE_TAG" + + cd git.environment-variables + git checkout main + + cd deploy/overlays/development + kustomize edit set image \ + bottlenote-product-api=${REGISTRY}/${{ env.IMAGE_NAME }}:${IMAGE_TAG} + + echo "development kustomization.yaml updated" + + - name: commit and push with retry + run: | + cd git.environment-variables + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add deploy/overlays/development/kustomization.yaml + + if git diff --staged --quiet; then + echo "No changes to commit" + exit 0 + fi + + git commit -m "chore(product): update development image tag to ${{ needs.build-and-push.outputs.image-tag }} + + Updated by GitHub Actions + Commit: ${{ github.sha }} + Branch: ${{ github.ref_name }} + Workflow: ${{ github.workflow }}" + + for i in {1..5}; do + git pull --rebase origin main && git push origin main && break + echo "Push failed, retry $i/5..." + sleep $((i * 2)) + done + + echo "Development deployment triggered" diff --git a/.github/workflows/deprecated/deploy_development.yml.bak b/.github/workflows/deprecated/deploy_development.yml.bak index 202f89520..205e68d3f 100644 --- a/.github/workflows/deprecated/deploy_development.yml.bak +++ b/.github/workflows/deprecated/deploy_development.yml.bak @@ -13,10 +13,8 @@ concurrency: cancel-in-progress: true env: - ORACLE_ENV_FILE: git.environment-variables/deploy/oracle/application-node-1.env - ORACLE_SSH_KEY_FILE: git.environment-variables/deploy/oracle/keys/node-1.pem - AWS_ECR_ENV_FILE: git.environment-variables/deploy/aws/ecr-properties.env - APP_ENV_FILE: git.environment-variables/application.springboot/dev.env + ECR_REGION: ap-northeast-2 + ECR_REGISTRY: 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com ECR_REPOSITORY: ecr-bottle-note-api jobs: @@ -25,9 +23,6 @@ jobs: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true) runs-on: ubuntu-24.04-arm - outputs: - image_tag: ${{ steps.build-image.outputs.image_tag }} - registry: ${{ steps.build-image.outputs.registry }} steps: - name: checkout code with submodules uses: actions/checkout@v4 @@ -44,55 +39,12 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: load aws ecr environment variables - env: - ENV_FILE: ${{ env.AWS_ECR_ENV_FILE }} - run: | - echo "📄 AWS ECR 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi - - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue - - # 공백 제거 - key=$(echo "$key" | xargs) - value=$(echo "$value" | xargs) - - # 마스킹 - echo "::add-mask::${value}" - - # 변수명 매핑 - case "$key" in - ECR_ACCESS_KEY) - echo "AWS_ACCESS_KEY_ID=${value}" >> $GITHUB_ENV - echo " ✅ AWS_ACCESS_KEY_ID 로드됨" - ;; - ECR_SECRET_ACCESS_KEY) - echo "AWS_SECRET_ACCESS_KEY=${value}" >> $GITHUB_ENV - echo " ✅ AWS_SECRET_ACCESS_KEY 로드됨" - ;; - ECR_REGION) - echo "AWS_REGION=${value}" >> $GITHUB_ENV - echo " ✅ AWS_REGION 로드됨" - ;; - ECR_REGISTRY) - echo "ECR_REGISTRY=${value}" >> $GITHUB_ENV - echo " ✅ ECR_REGISTRY 로드됨" - ;; - esac - done < "$ENV_FILE" - - echo "✅ AWS ECR 환경변수 로드 완료" - - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v2 with: - aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.ECR_REGION }} - name: login to amazon ecr id: login-ecr uses: aws-actions/amazon-ecr-login@v2 @@ -100,6 +52,12 @@ jobs: uses: docker/setup-buildx-action@v3 with: driver: docker-container + - name: generate build timestamp + id: build-time + run: echo "time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + - name: generate short commit sha + id: short-sha + run: echo "sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT - name: build and push dev image to ecr (github actions cache) uses: docker/build-push-action@v6 with: @@ -107,20 +65,16 @@ jobs: platforms: linux/arm64 push: true tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:development_${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:development_${{ steps.short-sha.outputs.sha }} ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:development_latest + build-args: | + GIT_COMMIT=${{ github.sha }} + GIT_BRANCH=${{ github.ref_name }} + BUILD_TIME=${{ steps.build-time.outputs.time }} cache-from: type=gha,scope=development cache-to: type=gha,scope=development,mode=max - - name: set image tag output for dev - id: build-image - run: | - IMAGE_TAG="${GITHUB_SHA:0:7}" - REGISTRY="${{ steps.login-ecr.outputs.registry }}" - echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT - echo "registry=$REGISTRY" >> $GITHUB_OUTPUT - echo "✅ 이미지가 ECR에 빌드 및 푸시되었습니다: $REGISTRY/${{ env.ECR_REPOSITORY }}:development_$IMAGE_TAG, development_latest" - deploy-to-servers: + update-kustomize-tag: needs: build-and-push runs-on: ubuntu-latest steps: @@ -129,199 +83,56 @@ jobs: with: submodules: true token: ${{ secrets.GIT_ACCESS_TOKEN }} - - name: load oracle instance environment variables - env: - ENV_FILE: ${{ env.ORACLE_ENV_FILE }} - run: | - echo "📄 Oracle 인스턴스 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi - - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue - - # 마스킹 - echo "::add-mask::${value}" - - # GitHub 환경변수로 설정 - echo "${key}=${value}" >> $GITHUB_ENV - echo " ✅ $key 로드됨" - done < "$ENV_FILE" - echo "✅ Oracle 인스턴스 환경변수 로드 완료" - - - name: load ssh private key - env: - KEY_FILE: ${{ env.ORACLE_SSH_KEY_FILE }} + # Kustomize 설치 (GitHub Marketplace의 검증된 액션 사용) + # GitHub Actions에서는 GITHUB_TOKEN이 자동 제공됨 + - name: setup kustomize + uses: imranismail/setup-kustomize@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: update image tag with kustomize run: | - echo "🔑 SSH 개인키 파일 로드 중..." + COMMIT_SHA="${{ github.sha }}" + IMAGE_TAG="development_${COMMIT_SHA:0:7}" - if [ ! -f "$KEY_FILE" ]; then - echo "❌ SSH 키 파일을 찾을 수 없습니다: $KEY_FILE" - exit 1 - fi + echo "📦 업데이트할 이미지 태그: $IMAGE_TAG" - # SSH 키 전체 내용을 환경변수로 저장 - SSH_KEY=$(cat "$KEY_FILE") + cd git.environment-variables - # SSH 키의 각 줄 마스킹 - echo "$SSH_KEY" | while IFS= read -r line; do - [ -n "$line" ] && echo "::add-mask::${line}" - done + # detached HEAD 해결: main 브랜치로 전환 (파일 수정 전) + git checkout main - # 멀티라인 환경변수로 설정 - { - echo "SSH_PRIVATE_KEY<> $GITHUB_ENV + cd deploy/overlays/development - echo "✅ SSH 개인키 로드 완료" - - - name: load aws ecr environment variables - env: - ENV_FILE: ${{ env.AWS_ECR_ENV_FILE }} - run: | - echo "📄 AWS ECR 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi + # Kustomize로 이미지 태그 업데이트 + kustomize edit set image \ + 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api=536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api:${IMAGE_TAG} - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue + echo "✅ kustomization.yaml 업데이트 완료" + git diff kustomization.yaml - # 공백 제거 - key=$(echo "$key" | xargs) - value=$(echo "$value" | xargs) - - # 마스킹 - echo "::add-mask::${value}" - - # 변수명 매핑 - case "$key" in - ECR_ACCESS_KEY) - echo "AWS_ACCESS_KEY_ID=${value}" >> $GITHUB_ENV - echo " ✅ AWS_ACCESS_KEY_ID 로드됨" - ;; - ECR_SECRET_ACCESS_KEY) - echo "AWS_SECRET_ACCESS_KEY=${value}" >> $GITHUB_ENV - echo " ✅ AWS_SECRET_ACCESS_KEY 로드됨" - ;; - ECR_REGION) - echo "AWS_REGION=${value}" >> $GITHUB_ENV - echo " ✅ AWS_REGION 로드됨" - ;; - ECR_REGISTRY) - echo "ECR_REGISTRY=${value}" >> $GITHUB_ENV - echo " ✅ ECR_REGISTRY 로드됨" - ;; - esac - done < "$ENV_FILE" - - echo "✅ AWS ECR 환경변수 로드 완료" - - - name: prepare application environment file - id: prepare-app-env + - name: commit and push to environment-variables run: | - APP_ENV_CONTENT=$(cat "${{ env.APP_ENV_FILE }}" | base64 -w 0) - echo "content=$APP_ENV_CONTENT" >> $GITHUB_OUTPUT - - - name: copy compose file to server - uses: appleboy/scp-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - source: "compose/product-api.dev.yml" - target: "~/" - - name: deploy to development server - uses: appleboy/ssh-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - script: | - aws configure set aws_access_key_id "${{ env.AWS_ACCESS_KEY_ID }}" - aws configure set aws_secret_access_key "${{ env.AWS_SECRET_ACCESS_KEY }}" - aws configure set region "${{ env.AWS_REGION }}" - - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - ECR_REGISTRY="${ACCOUNT_ID}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com" - aws ecr get-login-password --region ${{ env.AWS_REGION }} | docker login --username AWS --password-stdin $ECR_REGISTRY + cd git.environment-variables - IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}" - ECR_REPOSITORY="ecr-bottle-note-api" - FULL_IMAGE_NAME="$ECR_REGISTRY/$ECR_REPOSITORY:development_latest" - echo "다운로드할 이미지: $FULL_IMAGE_NAME (commit: $IMAGE_TAG)" - docker pull $FULL_IMAGE_NAME - docker images | grep $ECR_REPOSITORY - - echo "${{ steps.prepare-app-env.outputs.content }}" | base64 -d > ~/compose/.bottlenote.development.ENV - - export FULL_IMAGE_NAME="$FULL_IMAGE_NAME" - export GIT_BRANCH="${{ github.ref_name }}" - export GIT_COMMIT="${{ github.sha }}" - export BUILD_TIME="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" - - docker stop bottle-note-api-development 2>/dev/null || true - docker rm bottle-note-api-development 2>/dev/null || true - docker compose -f ~/compose/product-api.dev.yml down 2>/dev/null || true - - docker compose -f ~/compose/product-api.dev.yml up -d - docker compose -f ~/compose/product-api.dev.yml ps - - echo "사용하지 않는 모든 Docker 리소스 정리 중..." - docker system prune -f - docker image prune -a -f --filter "until=24h" - - - name: deployment verification - run: | - echo "⏳ 컨테이너 시작 대기 중..." - sleep 15 + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - # 재시도 로직 (최대 5회, 10초 간격) - MAX_RETRY=5 - RETRY_COUNT=0 - SUCCESS=false + git add deploy/overlays/development/kustomization.yaml - while [ $RETRY_COUNT -lt $MAX_RETRY ]; do - echo "🔍 API 상태 확인 시도 $((RETRY_COUNT + 1))/$MAX_RETRY..." + git commit -m "chore(dev): update image tag to ${GITHUB_SHA:0:7} - RESPONSE=$(curl -s -w "\n%{http_code}" https://api.development.bottle-note.com/api/v1/app-info) - HTTP_CODE=$(echo "$RESPONSE" | tail -n1) - BODY=$(echo "$RESPONSE" | sed '$d') + Updated by GitHub Actions + Commit: ${{ github.sha }} + Branch: ${{ github.ref_name }} + Workflow: ${{ github.workflow }}" - if [ "$HTTP_CODE" = "200" ]; then - echo "📋 배포된 애플리케이션 정보:" - echo "$BODY" | jq '.' + git push origin main - # 배포된 커밋 검증 - DEPLOYED_COMMIT=$(echo "$BODY" | jq -r '.data.gitCommitFullHash') - EXPECTED_COMMIT="${{ github.sha }}" + echo "✅ Git 커밋 및 푸시 완료" + echo "🔄 ArgoCD가 변경사항을 감지하여 자동 배포를 시작합니다" - if [ "$DEPLOYED_COMMIT" = "$EXPECTED_COMMIT" ]; then - echo "✅ 배포 검증 성공: 커밋 일치" - SUCCESS=true - break - else - echo "⚠️ 커밋 불일치 - 재시도 중..." - echo " 예상: $EXPECTED_COMMIT" - echo " 실제: $DEPLOYED_COMMIT" - fi - else - echo "⚠️ HTTP $HTTP_CODE - 재시도 중..." - fi - RETRY_COUNT=$((RETRY_COUNT + 1)) - [ $RETRY_COUNT -lt $MAX_RETRY ] && sleep 10 - done - if [ "$SUCCESS" = false ]; then - echo "❌ 배포 검증 실패: API 응답 없음 또는 커밋 불일치" - exit 1 - fi + # Oracle 서버 직접 배포는 제거됨 (ArgoCD로 완전 전환) + # 이전 deploy-to-servers job은 .bak 파일 참조 diff --git a/git.environment-variables b/git.environment-variables index 46c82d26d..152fc0a9a 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 46c82d26d3d6040087b75d76b388c2d2882b3038 +Subproject commit 152fc0a9a747df9406062670da9eeace01325760 From 2e2d529891e353bdec7d1c9b8193ee4e60acdb3b Mon Sep 17 00:00:00 2001 From: hgkim Date: Sat, 20 Dec 2025 18:58:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20Product=20API=20v2=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=20=EB=B0=B0=ED=8F=AC=20=EC=9B=8C=ED=81=AC=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...v2_product_api.yml => deploy_v2_development_product_api.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{deploy_v2_product_api.yml => deploy_v2_development_product_api.yml} (98%) diff --git a/.github/workflows/deploy_v2_product_api.yml b/.github/workflows/deploy_v2_development_product_api.yml similarity index 98% rename from .github/workflows/deploy_v2_product_api.yml rename to .github/workflows/deploy_v2_development_product_api.yml index c171fb558..ec2bfe518 100644 --- a/.github/workflows/deploy_v2_product_api.yml +++ b/.github/workflows/deploy_v2_development_product_api.yml @@ -1,4 +1,4 @@ -name: deploy v2 product api +name: deploy v2 development product api on: workflow_dispatch: From 0ecb885af7a4912cafd17e80b07554100594bec6 Mon Sep 17 00:00:00 2001 From: hgkim Date: Sat, 20 Dec 2025 19:22:00 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20Product=20API=20v2=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=20=EB=B0=B0=ED=8F=AC=20=EC=9B=8C=ED=81=AC=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy_production.yml | 138 -------- .../deploy_v2_development_product_api.yml | 5 + .../deploy_v2_release_product_api.yml | 122 +++++++ .../deprecated/deploy_production.yml.bak | 323 ++++-------------- 4 files changed, 186 insertions(+), 402 deletions(-) delete mode 100644 .github/workflows/deploy_production.yml create mode 100644 .github/workflows/deploy_v2_release_product_api.yml diff --git a/.github/workflows/deploy_production.yml b/.github/workflows/deploy_production.yml deleted file mode 100644 index 3df95a085..000000000 --- a/.github/workflows/deploy_production.yml +++ /dev/null @@ -1,138 +0,0 @@ -# act workflow_dispatch -W .github/workflows/deploy_production.yml --secret-file .secrets --container-architecture linux/arm64 -name: Deploy to Production - -on: - workflow_dispatch: - pull_request: - types: [ closed ] - branches: - - prod - -concurrency: - group: "deploy-production" - cancel-in-progress: true - -env: - ECR_REGION: ap-northeast-2 - ECR_REGISTRY: 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com - ECR_REPOSITORY: ecr-bottle-note-api - -jobs: - build-and-push: - if: | - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && github.event.pull_request.merged == true) - runs-on: ubuntu-24.04-arm - steps: - - name: checkout code with submodules - uses: actions/checkout@v4 - with: - submodules: true - token: ${{ secrets.GIT_ACCESS_TOKEN }} - - name: setup gradle cache - 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: configure aws credentials - uses: aws-actions/configure-aws-credentials@v2 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.ECR_REGION }} - - name: login to amazon ecr - id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 - - name: setup docker buildx for prod (cache support) - uses: docker/setup-buildx-action@v3 - with: - driver: docker-container - - name: generate build timestamp - id: build-time - run: echo "time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT - - name: generate short commit sha - id: short-sha - run: echo "sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT - - name: build and push prod image to ecr (github actions cache) - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/arm64 - push: true - tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:production_${{ steps.short-sha.outputs.sha }} - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:production_latest - build-args: | - GIT_COMMIT=${{ github.sha }} - GIT_BRANCH=${{ github.ref_name }} - BUILD_TIME=${{ steps.build-time.outputs.time }} - cache-from: type=gha,scope=production - cache-to: type=gha,scope=production,mode=max - - update-kustomize-tag: - needs: build-and-push - runs-on: ubuntu-latest - steps: - - name: checkout code with submodules - uses: actions/checkout@v4 - with: - submodules: true - token: ${{ secrets.GIT_ACCESS_TOKEN }} - - # Kustomize 설치 (GitHub Marketplace의 검증된 액션 사용) - # GitHub Actions에서는 GITHUB_TOKEN이 자동 제공됨 - - name: setup kustomize - uses: imranismail/setup-kustomize@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: update image tag with kustomize - run: | - COMMIT_SHA="${{ github.sha }}" - IMAGE_TAG="production_${COMMIT_SHA:0:7}" - - echo "📦 업데이트할 이미지 태그: $IMAGE_TAG" - - cd git.environment-variables - - # detached HEAD 해결: main 브랜치로 전환 (파일 수정 전) - git checkout main - - cd deploy/overlays/production - - # Kustomize로 이미지 태그 업데이트 - kustomize edit set image \ - 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api=536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api:${IMAGE_TAG} - - echo "✅ kustomization.yaml 업데이트 완료" - git diff kustomization.yaml - - - name: commit and push to environment-variables - run: | - cd git.environment-variables - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - git add deploy/overlays/production/kustomization.yaml - - git commit -m "chore(prod): update image tag to ${GITHUB_SHA:0:7} - - Updated by GitHub Actions - Commit: ${{ github.sha }} - Branch: ${{ github.ref_name }} - Workflow: ${{ github.workflow }}" - - git push origin main - - echo "✅ Git 커밋 및 푸시 완료" - echo "🔄 ArgoCD가 변경사항을 감지하여 자동 배포를 시작합니다" - - - - # Oracle 서버 직접 배포는 제거됨 (ArgoCD로 완전 전환) - # 이전 rolling-deploy job은 .bak 파일 참조 diff --git a/.github/workflows/deploy_v2_development_product_api.yml b/.github/workflows/deploy_v2_development_product_api.yml index ec2bfe518..7c83123e5 100644 --- a/.github/workflows/deploy_v2_development_product_api.yml +++ b/.github/workflows/deploy_v2_development_product_api.yml @@ -5,6 +5,11 @@ on: push: branches: - main + paths: + - 'bottlenote-batch/**' + - 'bottlenote-mono/**' + - 'bottlenote-observability/**' + - 'bottlenote-product-api/**' concurrency: group: "deploy-product" diff --git a/.github/workflows/deploy_v2_release_product_api.yml b/.github/workflows/deploy_v2_release_product_api.yml new file mode 100644 index 000000000..ab6f7c663 --- /dev/null +++ b/.github/workflows/deploy_v2_release_product_api.yml @@ -0,0 +1,122 @@ +name: deploy v2 product api production + +on: + workflow_dispatch: + pull_request: + types: [ closed ] + branches: + - 'release/product' + +concurrency: + group: "deploy-product-production" + cancel-in-progress: true + +env: + IMAGE_NAME: bottlenote-product-api + +jobs: + build-and-push: + if: | + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) + runs-on: ubuntu-24.04-arm + outputs: + version: ${{ steps.version.outputs.version }} + image-tag: ${{ steps.version.outputs.image-tag }} + image-digest: ${{ steps.build.outputs.image-digest }} + steps: + - name: checkout code with submodules + uses: actions/checkout@v4 + with: + submodules: true + token: ${{ secrets.GIT_ACCESS_TOKEN }} + + - name: read product version + id: version + run: | + VERSION=$(cat bottlenote-product-api/VERSION | tr -d '[:space:]') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "image-tag=product_${VERSION}" >> $GITHUB_OUTPUT + echo "Product version: $VERSION" + + - name: build and push to registry + id: build + uses: ./.github/actions/docker-build-push + with: + registry-url: ${{ secrets.REGISTRY_ADDRESS }} + registry-username: ${{ secrets.REGISTRY_USERNAME }} + registry-password: ${{ secrets.REGISTRY_PASSWORD }} + image-name: ${{ env.IMAGE_NAME }} + image-tag: product_${{ steps.version.outputs.version }} + additional-tags: product_latest + dockerfile: Dockerfile + context: . + platforms: linux/arm64 + cache-scope: product-production + image-title: "BottleNote Product API" + image-description: "BottleNote Product API Server" + image-vendor: "BottleNote" + image-authors: "BottleNote Team" + sign-image: 'true' + cosign-key-path: 'git.environment-variables/storage/docker-registry/cosign.key' + cosign-password: ${{ secrets.COSIGN_PASSWORD }} + + update-production: + needs: build-and-push + runs-on: ubuntu-latest + steps: + - name: checkout code with submodules + uses: actions/checkout@v4 + with: + submodules: true + token: ${{ secrets.GIT_ACCESS_TOKEN }} + + - name: setup kustomize + uses: imranismail/setup-kustomize@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: update production image tag + run: | + IMAGE_TAG="${{ needs.build-and-push.outputs.image-tag }}" + REGISTRY="${{ secrets.REGISTRY_ADDRESS }}" + + echo "Updating production image tag: $IMAGE_TAG" + + cd git.environment-variables + git checkout main + + cd deploy/overlays/production + kustomize edit set image \ + bottlenote-product-api=${REGISTRY}/${{ env.IMAGE_NAME }}:${IMAGE_TAG} + + echo "production kustomization.yaml updated" + + - name: commit and push with retry + run: | + cd git.environment-variables + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add deploy/overlays/production/kustomization.yaml + + if git diff --staged --quiet; then + echo "No changes to commit" + exit 0 + fi + + git commit -m "chore(product): update production image tag to ${{ needs.build-and-push.outputs.image-tag }} + + Updated by GitHub Actions + Commit: ${{ github.sha }} + Branch: ${{ github.ref_name }} + Workflow: ${{ github.workflow }}" + + for i in {1..5}; do + git pull --rebase origin main && git push origin main && break + echo "Push failed, retry $i/5..." + sleep $((i * 2)) + done + + echo "Production deployment triggered" diff --git a/.github/workflows/deprecated/deploy_production.yml.bak b/.github/workflows/deprecated/deploy_production.yml.bak index fa617ea31..3df95a085 100644 --- a/.github/workflows/deprecated/deploy_production.yml.bak +++ b/.github/workflows/deprecated/deploy_production.yml.bak @@ -1,5 +1,5 @@ -# act workflow_dispatch -W .github/workflows/deploy_production.yml --secret-file .secrets -name: Production Rolling Deployment +# act workflow_dispatch -W .github/workflows/deploy_production.yml --secret-file .secrets --container-architecture linux/arm64 +name: Deploy to Production on: workflow_dispatch: @@ -9,29 +9,26 @@ on: - prod concurrency: - group: "production-deploy" + group: "deploy-production" cancel-in-progress: true env: - ORACLE_SSH_KEY_FILE: git.environment-variables/deploy/oracle/keys/product-cluster-ssh-key.pem - AWS_ECR_ENV_FILE: git.environment-variables/deploy/aws/ecr-properties.env - APP_ENV_FILE: git.environment-variables/application.springboot/prod.env + ECR_REGION: ap-northeast-2 + ECR_REGISTRY: 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com ECR_REPOSITORY: ecr-bottle-note-api jobs: - build-and-push-ecr: - if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' + build-and-push: + if: | + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.merged == true) runs-on: ubuntu-24.04-arm - outputs: - image_tag: ${{ steps.build-image.outputs.image_tag }} - ecr_registry: ${{ steps.login-ecr.outputs.registry }} steps: - name: checkout code with submodules uses: actions/checkout@v4 with: submodules: true token: ${{ secrets.GIT_ACCESS_TOKEN }} - - name: setup gradle cache uses: actions/cache@v3 with: @@ -42,62 +39,25 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: load aws ecr environment variables - env: - ENV_FILE: ${{ env.AWS_ECR_ENV_FILE }} - run: | - echo "📄 AWS ECR 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi - - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue - - key=$(echo "$key" | xargs) - value=$(echo "$value" | xargs) - - echo "::add-mask::${value}" - - case "$key" in - ECR_ACCESS_KEY) - echo "AWS_ACCESS_KEY_ID=${value}" >> $GITHUB_ENV - echo " ✅ AWS_ACCESS_KEY_ID 로드됨" - ;; - ECR_SECRET_ACCESS_KEY) - echo "AWS_SECRET_ACCESS_KEY=${value}" >> $GITHUB_ENV - echo " ✅ AWS_SECRET_ACCESS_KEY 로드됨" - ;; - ECR_REGION) - echo "AWS_REGION=${value}" >> $GITHUB_ENV - echo " ✅ AWS_REGION 로드됨" - ;; - ECR_REGISTRY) - echo "ECR_REGISTRY=${value}" >> $GITHUB_ENV - echo " ✅ ECR_REGISTRY 로드됨" - ;; - esac - done < "$ENV_FILE" - - echo "✅ AWS ECR 환경변수 로드 완료" - - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v2 with: - aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.ECR_REGION }} - name: login to amazon ecr id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - - name: setup docker buildx for prod (cache support) uses: docker/setup-buildx-action@v3 with: driver: docker-container - + - name: generate build timestamp + id: build-time + run: echo "time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + - name: generate short commit sha + id: short-sha + run: echo "sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT - name: build and push prod image to ecr (github actions cache) uses: docker/build-push-action@v6 with: @@ -105,28 +65,18 @@ jobs: platforms: linux/arm64 push: true tags: | - ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:production_${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:production_${{ steps.short-sha.outputs.sha }} ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:production_latest + build-args: | + GIT_COMMIT=${{ github.sha }} + GIT_BRANCH=${{ github.ref_name }} + BUILD_TIME=${{ steps.build-time.outputs.time }} cache-from: type=gha,scope=production cache-to: type=gha,scope=production,mode=max - - name: set image tag output for prod - id: build-image - run: | - IMAGE_TAG="${GITHUB_SHA:0:7}" - REGISTRY="${{ steps.login-ecr.outputs.registry }}" - echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT - echo "registry=$REGISTRY" >> $GITHUB_OUTPUT - echo "✅ Image built and pushed to ECR: $REGISTRY/${{ env.ECR_REPOSITORY }}:production_$IMAGE_TAG, production_latest" - - rolling-deploy: - needs: [ build-and-push-ecr ] + update-kustomize-tag: + needs: build-and-push runs-on: ubuntu-latest - strategy: - matrix: - cluster: [ 'product-cluster-1' , 'product-cluster-2' ] - max-parallel: 1 - fail-fast: true steps: - name: checkout code with submodules uses: actions/checkout@v4 @@ -134,210 +84,55 @@ jobs: submodules: true token: ${{ secrets.GIT_ACCESS_TOKEN }} - - name: load cluster environment variables - env: - ENV_FILE: git.environment-variables/deploy/oracle/${{ matrix.cluster }}.env + # Kustomize 설치 (GitHub Marketplace의 검증된 액션 사용) + # GitHub Actions에서는 GITHUB_TOKEN이 자동 제공됨 + - name: setup kustomize + uses: imranismail/setup-kustomize@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: update image tag with kustomize run: | - echo "📄 Cluster 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi - - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue + COMMIT_SHA="${{ github.sha }}" + IMAGE_TAG="production_${COMMIT_SHA:0:7}" - echo "::add-mask::${value}" - echo "${key}=${value}" >> $GITHUB_ENV - echo " ✅ $key 로드됨" - done < "$ENV_FILE" + echo "📦 업데이트할 이미지 태그: $IMAGE_TAG" - echo "✅ Cluster 환경변수 로드 완료" + cd git.environment-variables - - name: load ssh private key - env: - KEY_FILE: ${{ env.ORACLE_SSH_KEY_FILE }} - run: | - echo "🔑 SSH 개인키 파일 로드 중..." - - if [ ! -f "$KEY_FILE" ]; then - echo "❌ SSH 키 파일을 찾을 수 없습니다: $KEY_FILE" - exit 1 - fi - - SSH_KEY=$(cat "$KEY_FILE") + # detached HEAD 해결: main 브랜치로 전환 (파일 수정 전) + git checkout main - echo "$SSH_KEY" | while IFS= read -r line; do - [ -n "$line" ] && echo "::add-mask::${line}" - done + cd deploy/overlays/production - { - echo "SSH_PRIVATE_KEY<> $GITHUB_ENV + # Kustomize로 이미지 태그 업데이트 + kustomize edit set image \ + 536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api=536697247604.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-bottle-note-api:${IMAGE_TAG} - echo "✅ SSH 개인키 로드 완료" + echo "✅ kustomization.yaml 업데이트 완료" + git diff kustomization.yaml - - name: load aws ecr environment variables - env: - ENV_FILE: ${{ env.AWS_ECR_ENV_FILE }} + - name: commit and push to environment-variables run: | - echo "📄 AWS ECR 환경변수 파일 로드 중..." - if [ ! -f "$ENV_FILE" ]; then - echo "❌ 환경변수 파일을 찾을 수 없습니다: $ENV_FILE" - exit 1 - fi - - while IFS='=' read -r key value || [ -n "$key" ]; do - [[ -z "$key" || "$key" == \#* ]] && continue - - key=$(echo "$key" | xargs) - value=$(echo "$value" | xargs) + cd git.environment-variables - echo "::add-mask::${value}" - - case "$key" in - ECR_ACCESS_KEY) - echo "AWS_ACCESS_KEY_ID=${value}" >> $GITHUB_ENV - echo " ✅ AWS_ACCESS_KEY_ID 로드됨" - ;; - ECR_SECRET_ACCESS_KEY) - echo "AWS_SECRET_ACCESS_KEY=${value}" >> $GITHUB_ENV - echo " ✅ AWS_SECRET_ACCESS_KEY 로드됨" - ;; - ECR_REGION) - echo "AWS_REGION=${value}" >> $GITHUB_ENV - echo " ✅ AWS_REGION 로드됨" - ;; - ECR_REGISTRY) - echo "ECR_REGISTRY=${value}" >> $GITHUB_ENV - echo " ✅ ECR_REGISTRY 로드됨" - ;; - esac - done < "$ENV_FILE" - - echo "✅ AWS ECR 환경변수 로드 완료" - - - name: prepare application environment file - id: prepare-app-env - run: | - APP_ENV_CONTENT=$(cat "${{ env.APP_ENV_FILE }}" | base64 -w 0) - echo "content=$APP_ENV_CONTENT" >> $GITHUB_OUTPUT - - - name: copy compose file to server - uses: appleboy/scp-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - source: "compose/product-api.prod.yml" - target: "~/" - - - name: backup current container info for rollback - id: backup-info - uses: appleboy/ssh-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - script: | - CURRENT_CONTAINER=$(docker ps --filter "name=bottle-note-api-production" --format "{{.Image}}" | head -n 1) - echo "PREVIOUS_IMAGE=$CURRENT_CONTAINER" >> backup_info.txt - echo "Current container info: $CURRENT_CONTAINER" - - - name: deploy to ${{ matrix.cluster }} - uses: appleboy/ssh-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - script: | - aws configure set aws_access_key_id "${{ env.AWS_ACCESS_KEY_ID }}" - aws configure set aws_secret_access_key "${{ env.AWS_SECRET_ACCESS_KEY }}" - aws configure set region "${{ env.AWS_REGION }}" - - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - ECR_REGISTRY="${ACCOUNT_ID}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com" - aws ecr get-login-password --region ${{ env.AWS_REGION }} | docker login --username AWS --password-stdin $ECR_REGISTRY - - IMAGE_TAG="${{ needs.build-and-push-ecr.outputs.image_tag }}" - ECR_REPOSITORY="ecr-bottle-note-api" - FULL_IMAGE_NAME="$ECR_REGISTRY/$ECR_REPOSITORY:production_latest" - echo "Image to download: $FULL_IMAGE_NAME (commit: $IMAGE_TAG)" - docker pull $FULL_IMAGE_NAME - docker images | grep $ECR_REPOSITORY - - echo "${{ steps.prepare-app-env.outputs.content }}" | base64 -d > ~/compose/.bottlenote.production.ENV - sudo rm -f /var/log/bottle-note/application-prod* 2>/dev/null || true - - export FULL_IMAGE_NAME="$FULL_IMAGE_NAME" - export SERVER_NAME="${{ matrix.cluster }}" - export GIT_BRANCH="${{ github.ref_name }}" - export GIT_COMMIT="${{ github.sha }}" - export BUILD_TIME="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" - - docker stop bottle-note-api-production 2>/dev/null || true - docker rm bottle-note-api-production 2>/dev/null || true - docker compose -f ~/compose/product-api.prod.yml down 2>/dev/null || true - - docker compose -f ~/compose/product-api.prod.yml up -d - docker compose -f ~/compose/product-api.prod.yml ps - - echo "Cleaning up unused Docker resources..." - docker system prune -f - docker image prune -a -f --filter "until=48h" - - - name: health check for ${{ matrix.cluster }} - uses: appleboy/ssh-action@master - with: - host: ${{ env.INSTANCE_NETWORK_PUBLIC_IP }} - port: ${{ env.INSTANCE_NETWORK_PORT }} - username: ${{ env.INSTANCE_HOST_USERNAME }} - key: ${{ env.SSH_PRIVATE_KEY }} - script: | - echo "⏳ 컨테이너 시작 대기 중..." - sleep 15 + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - MAX_RETRY=5 - RETRY_COUNT=0 - SUCCESS=false - EXPECTED_COMMIT="${{ github.sha }}" + git add deploy/overlays/production/kustomization.yaml - while [ $RETRY_COUNT -lt $MAX_RETRY ]; do - echo "🔍 API 상태 확인 시도 $((RETRY_COUNT + 1))/$MAX_RETRY..." + git commit -m "chore(prod): update image tag to ${GITHUB_SHA:0:7} - RESPONSE=$(curl -s -w "\n%{http_code}" http://localhost:30301/api/v1/app-info) - HTTP_CODE=$(echo "$RESPONSE" | tail -n1) - BODY=$(echo "$RESPONSE" | sed '$d') + Updated by GitHub Actions + Commit: ${{ github.sha }} + Branch: ${{ github.ref_name }} + Workflow: ${{ github.workflow }}" - if [ "$HTTP_CODE" = "200" ]; then - echo "📋 배포된 애플리케이션 정보:" - echo "$BODY" | jq '.' + git push origin main - DEPLOYED_COMMIT=$(echo "$BODY" | jq -r '.data.gitCommitFullHash') + echo "✅ Git 커밋 및 푸시 완료" + echo "🔄 ArgoCD가 변경사항을 감지하여 자동 배포를 시작합니다" - if [ "$DEPLOYED_COMMIT" = "$EXPECTED_COMMIT" ]; then - echo "✅ 배포 검증 성공: 커밋 일치" - SUCCESS=true - break - else - echo "⚠️ 커밋 불일치 - 재시도 중..." - echo " 예상: $EXPECTED_COMMIT" - echo " 실제: $DEPLOYED_COMMIT" - fi - else - echo "⚠️ HTTP $HTTP_CODE - 재시도 중..." - fi - RETRY_COUNT=$((RETRY_COUNT + 1)) - [ $RETRY_COUNT -lt $MAX_RETRY ] && sleep 10 - done - if [ "$SUCCESS" = false ]; then - echo "❌ ${{ matrix.cluster }} 배포 검증 실패" - exit 1 - fi + # Oracle 서버 직접 배포는 제거됨 (ArgoCD로 완전 전환) + # 이전 rolling-deploy job은 .bak 파일 참조