Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 62 additions & 16 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,36 +62,83 @@ jobs:
- name: Generate google-services.json
run: |
echo "$GOOGLE_SERVICE" > app/google-services.json.b64
base64 -d -i app/google-services.json.b64 > app/google-services.json
base64 -d app/google-services.json.b64 > app/google-services.json
env:
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE }}

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Assemble Debug APK
# - name: Assemble Debug APK
# if: >
# github.event_name == 'pull_request' &&
# startsWith(github.event.pull_request.head.ref, 'release/') &&
# (github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
# run: ./gradlew assembleDebug

# - name: Upload Debug APK artifact
# if: >
# github.event_name == 'pull_request' &&
# startsWith(github.event.pull_request.head.ref, 'release/') &&
# (github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
# uses: actions/upload-artifact@v4
# with:
# name: debug-apk
# path: app/build/outputs/apk/debug/*.apk

- name: Decode Keystore for Release Signing
if: >
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
(github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
run: ./gradlew assembleDebug
startsWith(github.event.pull_request.head.ref, 'release/')
env:
KEYSTORE_CONTENT: ${{ secrets.KEYSTORE_CONTENT }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: |
echo "$KEYSTORE_CONTENT" | base64 -d > $GITHUB_WORKSPACE/release.keystore
echo "KEYSTORE_FILE=$GITHUB_WORKSPACE/release.keystore" >> $GITHUB_ENV
echo "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> $GITHUB_ENV
echo "KEY_ALIAS=$KEY_ALIAS" >> $GITHUB_ENV
echo "KEY_PASSWORD=$KEY_PASSWORD" >> $GITHUB_ENV

- name: Upload Debug APK artifact
- name: Assemble Release APK
if: >
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
(github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
uses: actions/upload-artifact@v4
with:
name: debug-apk
path: app/build/outputs/apk/debug/*.apk
run: ./gradlew assembleRelease

- name: Assemble Release APK
- name: Inspect AndroidManifest (NAVER_MAPS_CLIENT_ID injected?)
if: >
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
(github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
run: |
APK=$(ls app/build/outputs/apk/release/*.apk | head -n 1)
echo "APK=$APK"

BUILD_TOOLS_VERSION=$(ls "$ANDROID_SDK_ROOT/build-tools" | sort -V | tail -n 1)
AAPT2="$ANDROID_SDK_ROOT/build-tools/$BUILD_TOOLS_VERSION/aapt2"
echo "AAPT2=$AAPT2"

# 네이버 meta-data 존재 여부 확인
"$AAPT2" dump xmltree --file AndroidManifest.xml "$APK" \
| sed -n '/com.naver.maps.map.NCP_KEY_ID/,+20p' || true

# placeholder가 그대로 남아있는지 확인(치환 실패 징후)
"$AAPT2" dump xmltree --file AndroidManifest.xml "$APK" \
| grep -n '\${NAVER_MAPS_CLIENT_ID}' || true

# Release APK 서명 여부 검증
- name: Verify Release APK signature
if: >
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
(github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened')
run: ./gradlew assembleRelease
run: |
BUILD_TOOLS_VERSION=$(ls "$ANDROID_SDK_ROOT/build-tools" | sort -V | tail -n 1)
"$ANDROID_SDK_ROOT/build-tools/$BUILD_TOOLS_VERSION/apksigner" verify --print-certs app/build/outputs/apk/release/*.apk

- name: Upload Release APK artifact
if: >
Expand Down Expand Up @@ -125,10 +172,9 @@ jobs:
--groups "eat-ssu-android-qa" \
--release-notes "Release | PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}" \
--token "$FIREBASE_TOKEN"


# Debug는 Artifact로만 공유 + PR 코멘트
- name: Comment PR with artifact download 안내
# Artifact로 APK 제공
- name: Comment PR with artifact download
if: >
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
Expand All @@ -141,7 +187,7 @@ jobs:
[
`✅ CI 완료`,
``,
`- Debug APK: GitHub Actions Artifacts에서 다운로드 (run 링크: ${runUrl})`,
`- Github APK : GitHub Actions Artifacts에서 다운로드 (run 링크: ${runUrl})`,
`- Release APK: Firebase App Distribution으로 배포됨 (그룹: eat-ssu-android-qa)`,
].join('\n');

Expand Down
16 changes: 16 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ android {
compose = true
}

// CI 환경에서 사용하는 서명 설정
signingConfigs {
create("ciRelease") {
val keystoreFile = System.getenv("KEYSTORE_FILE")
if (!keystoreFile.isNullOrBlank()) {
storeFile = file(keystoreFile)
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_PASSWORD")
}
}
}

buildTypes {
getByName("release") {
val p = Properties()
Expand All @@ -68,6 +81,9 @@ android {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")

if (!System.getenv("KEYSTORE_FILE").isNullOrBlank()) {
signingConfig = signingConfigs.getByName("ciRelease")
}
}

getByName("debug") {
Expand Down