Skip to content
Merged
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
19 changes: 0 additions & 19 deletions .github/actions/setup-release-config/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ inputs:
description: RELEASE_KEY_PASSWORD
required: false
default: ""
firebase-service-account-json:
description: FIREBASE_SERVICE_ACCOUNT_JSON — 주어지면 ADC credential 파일을 만든다
required: false
default: ""
compose-local-properties:
description: "true 면 app/build.gradle.kts 의 signingConfigs.release 가 읽는 local.properties 를 만든다"
required: false
Expand All @@ -50,9 +46,6 @@ outputs:
keystore-path:
description: decode 된 release keystore 경로 (만들지 않았으면 빈 값)
value: ${{ steps.materialise.outputs.keystore-path }}
firebase-credentials-path:
description: Firebase service account credential 경로 (만들지 않았으면 빈 값)
value: ${{ steps.materialise.outputs.firebase-credentials-path }}

runs:
using: composite
Expand All @@ -70,7 +63,6 @@ runs:
RELEASE_STORE_PASSWORD: ${{ inputs.release-store-password }}
RELEASE_KEY_ALIAS: ${{ inputs.release-key-alias }}
RELEASE_KEY_PASSWORD: ${{ inputs.release-key-password }}
FIREBASE_SERVICE_ACCOUNT_JSON: ${{ inputs.firebase-service-account-json }}
run: |
set -euo pipefail

Expand All @@ -90,7 +82,6 @@ runs:
RELEASE_STORE_PASSWORD) value="$RELEASE_STORE_PASSWORD" ;;
RELEASE_KEY_ALIAS) value="$RELEASE_KEY_ALIAS" ;;
RELEASE_KEY_PASSWORD) value="$RELEASE_KEY_PASSWORD" ;;
FIREBASE_SERVICE_ACCOUNT_JSON) value="$FIREBASE_SERVICE_ACCOUNT_JSON" ;;
*)
echo "::error::이 action 이 모르는 secret 이름: $name"
exit 1
Expand Down Expand Up @@ -119,13 +110,11 @@ runs:
RELEASE_STORE_PASSWORD: ${{ inputs.release-store-password }}
RELEASE_KEY_ALIAS: ${{ inputs.release-key-alias }}
RELEASE_KEY_PASSWORD: ${{ inputs.release-key-password }}
FIREBASE_SERVICE_ACCOUNT_JSON: ${{ inputs.firebase-service-account-json }}
COMPOSE_LOCAL_PROPERTIES: ${{ inputs.compose-local-properties }}
run: |
set -euo pipefail

keystore_path=""
firebase_credentials_path=""

# google-services plugin 이 app/google-services.json 을 요구한다. 파일은 .gitignore 라
# CI 환경엔 없으므로 base64 secret 에서 복원한다.
Expand All @@ -138,13 +127,6 @@ runs:
printf '%s' "$RELEASE_STORE_FILE_B64" | base64 -d > "$keystore_path"
fi

# Firebase App Distribution Gradle plugin 은 GOOGLE_APPLICATION_CREDENTIALS 환경변수로
# service account JSON 경로를 인식한다. 경로만 output 으로 넘기고 export 는 호출자가 한다.
if [ -n "$FIREBASE_SERVICE_ACCOUNT_JSON" ]; then
firebase_credentials_path="$RUNNER_TEMP/firebase-service-account.json"
printf '%s' "$FIREBASE_SERVICE_ACCOUNT_JSON" > "$firebase_credentials_path"
fi

if [ "$COMPOSE_LOCAL_PROPERTIES" = "true" ]; then
{
echo "KAKAO_NATIVE_APP_KEY=$KAKAO_NATIVE_APP_KEY"
Expand All @@ -158,5 +140,4 @@ runs:

{
echo "keystore-path=$keystore_path"
echo "firebase-credentials-path=$firebase_credentials_path"
} >> "$GITHUB_OUTPUT"
9 changes: 9 additions & 0 deletions .github/scripts/firebase-wif-canary-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@ const productionWorkflow = await readFile(
new URL("../workflows/release-distribution.yml", import.meta.url),
"utf8",
);
const releaseConfigAction = await readFile(
new URL("../actions/setup-release-config/action.yml", import.meta.url),
"utf8",
);

test("no workflow carries a long-lived service account JSON", () => {
// canary 가 성공한 뒤 프로덕션도 WIF 로 전환했다 (#850). 이제 파이프라인 어디에도 장기 키가
// 없어야 한다 — 되살아나면 이 단언이 그 자리에서 막는다. 롤백이 필요하면 이 테스트를 함께
// 되돌리는 것이 «의도된 롤백» 의 표시다.
assert.doesNotMatch(canaryWorkflow, /FIREBASE_SERVICE_ACCOUNT_JSON/);
assert.doesNotMatch(productionWorkflow, /FIREBASE_SERVICE_ACCOUNT_JSON/);
// 워크플로가 안 넘겨도 composite action 이 입력을 들고 있으면 경로가 살아 있는 것이다.
// 2026-08-30 실배포 성공 후 그 롤백 경로까지 걷었다 — 입력·env·ADC 파일 생성·output 전부.
assert.doesNotMatch(releaseConfigAction, /FIREBASE_SERVICE_ACCOUNT_JSON/);
assert.doesNotMatch(releaseConfigAction, /firebase-service-account-json/);
assert.doesNotMatch(releaseConfigAction, /firebase-credentials-path/);
// 자격 파일 경로를 워크플로가 손으로 지정하면 auth 액션이 export 한 단기 credential 대신
// 낡은 경로를 물 수 있다. 경로는 액션이 정하게 둔다.
assert.doesNotMatch(productionWorkflow, /GOOGLE_APPLICATION_CREDENTIALS:/);
Expand Down
Loading