Skip to content

Instantly share code, notes, and snippets.

@BangDori
Last active February 24, 2025 12:10
Show Gist options
  • Select an option

  • Save BangDori/d8ce7347e3b1e5d25ffade8ff51f4b62 to your computer and use it in GitHub Desktop.

Select an option

Save BangDori/d8ce7347e3b1e5d25ffade8ff51f4b62 to your computer and use it in GitHub Desktop.
name: Code Change Detection & Deployment Trigger
on:
workflow_call:
jobs:
detect-code-changes:
runs-on: [self-hosted, macOS, x64]
outputs:
has_native_changes: ${{ steps.check_native_changes.outputs.has_native_changes }}
steps:
- name: Checkout Repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # 기준 브랜치(release-1.x.x)와 비교해야 하므로 전체 이력 가져오기
- name: Fetch Target Branch
run: git fetch origin ${{ github.base_ref }}
- name: Get Commit Hashes
id: get_hashes
run: |
BASE_COMMIT=$(git rev-parse origin/${{ github.base_ref }})
PR_COMMIT=$(git rev-parse HEAD)
BASE_COMMIT_URL="https://github.com/${{ github.repository }}/commit/$BASE_COMMIT"
PR_COMMIT_URL="https://github.com/${{ github.repository }}/commit/$PR_COMMIT"
echo "BASE_COMMIT=$BASE_COMMIT" >> $GITHUB_ENV
echo "PR_COMMIT=$PR_COMMIT" >> $GITHUB_ENV
echo "BASE_COMMIT_URL=$BASE_COMMIT_URL" >> $GITHUB_ENV
echo "PR_COMMIT_URL=$PR_COMMIT_URL" >> $GITHUB_ENV
- name: Check if iOS/Android Changed
id: check_native_changes
run: |
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- ios android)
if [ -n "$CHANGED_FILES" ]; then
echo "Native changes detected"
echo "has_native_changes=true" >> $GITHUB_ENV
echo "has_native_changes=true" >> $GITHUB_OUTPUT
else
echo "has_native_changes=false" >> $GITHUB_ENV
echo "has_native_changes=false" >> $GITHUB_OUTPUT
fi
- name: Post PR Comment for Native Changes
if: env.has_native_changes == 'true'
run: |
gh pr comment ${{ github.event.pull_request.number }} --body "### 🚀 **iOS/Android 네이티브 코드 변경 감지**
- **비교한 버전 (Base)**: [\`${{ env.BASE_COMMIT }}\`](${{ env.BASE_COMMIT_URL }})
- **현재 PR 브랜치 (Head)**: [\`${{ env.PR_COMMIT }}\`](${{ env.PR_COMMIT_URL }})"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check if src Changed
id: check_js_changes
if: env.has_native_changes == 'false'
run: |
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- src)
if [ -n "$CHANGED_FILES" ]; then
echo "has_js_changes=true" >> $GITHUB_ENV
else
echo "has_js_changes=false" >> $GITHUB_ENV
fi
- name: Post PR Comment for JS Changes
if: env.has_js_changes == 'true'
run: |
gh pr comment ${{ github.event.pull_request.number }} --body "### 🚀 **JS 코드 변경 감지**
- **비교한 버전 (Base)**: [\`${{ env.BASE_COMMIT }}\`](${{ env.BASE_COMMIT_URL }})
- **현재 PR 브랜치 (Head)**: [\`${{ env.PR_COMMIT }}\`](${{ env.PR_COMMIT_URL }})"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Post PR Comment for No Changes
if: env.has_native_changes == 'false' && env.has_js_changes == 'false'
run: |
gh pr comment ${{ github.event.pull_request.number }} --body "### ✅ **변경 사항 없음**
- **비교한 버전 (Base)**: [\`${{ env.BASE_COMMIT }}\`](${{ env.BASE_COMMIT_URL }})
- **현재 PR 브랜치 (Head)**: [\`${{ env.PR_COMMIT }}\`](${{ env.PR_COMMIT_URL }})"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
trigger-ios-deployment-staging:
needs: detect-code-changes
if: needs.detect-code-changes.outputs.has_native_changes == 'true'
uses: ./.github/workflows/ios-deployment.yml
with:
environment: staging
secrets: inherit
trigger-android-deployment-staging:
needs: detect-code-changes
if: needs.detect-code-changes.outputs.has_native_changes == 'true'
uses: ./.github/workflows/android-deployment.yml
with:
environment: staging
secrets: inherit
trigger-ota-update-staging:
needs: detect-code-changes
uses: ./.github/workflows/ota-update-staging.yml
with:
strategy: ${{ (needs.detect-code-changes.outputs.has_native_changes == 'true') && 'native' || 'script' }}
secrets: inherit
name: OTA Update on Production
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
actions: read
jobs:
ota-update-production:
runs-on: [self-hosted, macOS, x64]
steps:
- name: Checkout Repository
uses: actions/checkout@v4
# ✅ AWS Credentials 설정
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Install package modules
run: yarn install --frozen-lockfile
- name: Generate Bundles
run: yarn export:bundle
# S3에 zip 파일을 업로드
- name: Upload Bundles to S3
run: |
aws s3 cp ios/main.jsbundle.zip s3://storage/production/main.jsbundle.zip
aws s3 cp android/index.android.bundle.zip s3://storage/production/index.android.bundle.zip
# S3에서 update.json 파일을 다운로드
- name: Download update.json from S3
run: |
aws s3 cp s3://storage/production/update.json ./update.json
- name: Extract Version from Staging Branch
run: |
aws s3 cp s3://storage/staging/update.json ./update.staging.json
STAGING_APP_VERSION=$(jq '.appVersion' update.staging.json)
NATIVE_VERSION=$(jq -r '.nativeVersion' update.staging.json)
echo "RELEASE_APP_VERSION=$STAGING_APP_VERSION" >> $GITHUB_ENV
echo "RELEASE_NATIVE_VERSION=$NATIVE_VERSION" >> $GITHUB_ENV
# update.json 파일을 업데이트 (updatedAt, appVersion, bundleVersion, nativeVersion)
- name: Update `update.json`
run: |
BUNDLE_VERSION=$(jq '.bundleVersion' update.json)
NATIVE_VERSION=$(jq -r '.nativeVersion' update.json)
CURRENT_DATE=$(TZ=Asia/Seoul date +"%Y-%m-%dT%H:%M:%SZ") # 현재 날짜를 Seoul (KST, UTC+9) 기준으로 가져오기
NEW_BUNDLE_VERSION=$BUNDLE_VERSION
NEW_NATIVE_VERSION=$NATIVE_VERSION
if [ "${{ env.RELEASE_NATIVE_VERSION }}" == "$NATIVE_VERSION" ]; then
NEW_BUNDLE_VERSION=$((BUNDLE_VERSION + 1))
else
NEW_NATIVE_VERSION=${{ env.RELEASE_APP_VERSION }}
fi
jq --arg v "$NEW_BUNDLE_VERSION" \
--arg rav "${{ env.RELEASE_APP_VERSION }}" \
--arg d "$CURRENT_DATE" \
--arg uv "$NEW_NATIVE_VERSION" \
'.bundleVersion=($v | tonumber) | .appVersion=$rav | .updatedAt=$d | .nativeVersion=$uv' \
update.json > tmp.json && mv tmp.json update.json
# 업데이트된 update.json 파일을 S3에 업로드
- name: Upload Updated update.json to S3
run: |
aws s3 cp update.json s3://storage/production/update.json
# 업데이트 후 Slack 알림
- name: action-slack
if: github.event_name == 'push'
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: ${{ github.actor }}
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
if_mention: failure,cancelled
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
name: OTA Update on Staging
on:
workflow_call:
inputs:
strategy:
description: '업데이트 전략 (native 또는 script)'
required: true
type: string
permissions:
id-token: write
contents: read
actions: read
pull-requests: write
jobs:
ota-update:
runs-on: [self-hosted, macOS, x64]
steps:
- name: Checkout Repository
uses: actions/checkout@v4
# ✅ AWS Credentials 설정
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Install package modules
run: yarn install --frozen-lockfile
- name: Generate Bundles
run: yarn export:bundle
# S3에 zip 파일 업로드
- name: Upload Bundles to S3
run: |
aws s3 cp ios/main.jsbundle.zip s3://storage/staging/main.jsbundle.zip
aws s3 cp android/index.android.bundle.zip s3://storage/staging/index.android.bundle.zip
# S3에서 update.json 파일 다운로드
- name: Download update.json from S3
run: |
aws s3 cp s3://storage/staging/update.json ./update.json
# staging deployment 버전 추출
- name: Extract Version from Branch (release/hotfix)
shell: bash
run: |
BASE_BRANCH="${{ github.base_ref }}"
if [[ "$BASE_BRANCH" =~ ^(release|hotfix)-([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then
STAGING_APP_VERSION="${BASH_REMATCH[2]}"
echo "RELEASE_APP_VERSION=$STAGING_APP_VERSION" >> $GITHUB_ENV
fi
# update.json 파일을 업데이트 (date, appVersion, bundleVersion, nativeVersion)
- name: Update `update.json`
run: |
APP_VERSION=$(jq -r '.appVersion' update.json)
BUNDLE_VERSION=$(jq '.bundleVersion' update.json)
NATIVE_VERSION=$(jq -r '.nativeVersion' update.json)
CURRENT_DATE=$(TZ=Asia/Seoul date +"%Y-%m-%dT%H:%M:%SZ") # 현재 날짜를 Seoul (KST, UTC+9) 기준으로 가져오기
NEW_NATIVE_VERSION=$NATIVE_VERSION
NEW_BUNDLE_VERSION=$BUNDLE_VERSION
if [ "${{ inputs.strategy }}" == "native" ]; then
NEW_NATIVE_VERSION=${{ env.RELEASE_APP_VERSION }}
else
NEW_BUNDLE_VERSION=$((BUNDLE_VERSION + 1))
fi
jq --arg v "$NEW_BUNDLE_VERSION" \
--arg rav "${{ env.RELEASE_APP_VERSION }}" \
--arg d "$CURRENT_DATE" \
--arg uv "$NEW_NATIVE_VERSION" \
'.bundleVersion=($v | tonumber) | .appVersion=$rav | .date=$d | .nativeVersion=$uv' \
update.json > tmp.json && mv tmp.json update.json
echo "CURRENT_DATE=$CURRENT_DATE" >> $GITHUB_ENV
echo "OLD_APP_VERSION=$APP_VERSION" >> $GITHUB_ENV
echo "OLD_BUNDLE_VERSION=$BUNDLE_VERSION" >> $GITHUB_ENV
echo "NEW_BUNDLE_VERSION=$NEW_BUNDLE_VERSION" >> $GITHUB_ENV
echo "OLD_FORCE_UPDATE_VERSION=$NATIVE_VERSION" >> $GITHUB_ENV
echo "NEW_NATIVE_VERSION=$NEW_NATIVE_VERSION" >> $GITHUB_ENV
# 업데이트된 update.json 파일을 S3에 업로드
- name: Upload Updated update.json to S3
run: |
aws s3 cp update.json s3://storage/staging/update.json
# 업데이트 후 PR에 Comment를 남김
- name: Post PR Comment for OTA Update
run: |
gh pr comment ${{ github.event.pull_request.number }} --body "### ✅ OTA Update 완료
- 시간: ${{ env.CURRENT_DATE }}
- 환경: staging
- 전략: ${{ inputs.strategy }}
| 항목 | 앱 버전 | 번들 버전 | 업데이트 버전 |
| :-: | :-: | :-: | :-: |
| **기존** | ${{ env.OLD_APP_VERSION }} | ${{ env.OLD_BUNDLE_VERSION }} | ${{ env.OLD_NATIVE_VERSION || 'X' }} |
| **변경** | ${{ env.RELEASE_APP_VERSION }} | ${{ env.NEW_BUNDLE_VERSION || env.OLD_BUNDLE_VERSION }} | ${{ env.NEW_NATIVE_VERSION || env.OLD_NATIVE_VERSION || 'X' }} |"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment