local.properties ๋ .gitignore ์ ๋ฑ๋ก๋์ด ์์ด git ์ผ๋ก ๋ฐ์์ง์ง ์๋๋ค. clone ์งํ ๋ค์ ๋ ํค๋ฅผ ๋ฃจํธ local.properties ์ ์ง์ ์ฑ์์ผ ์นด์นด์คยท๊ตฌ๊ธ ๋ก๊ทธ์ธ์ด ์ ์ ๋์ํ๋ค.
| ํค | ์ฉ๋ | ๋ฐ๊ธ ์์น |
|---|---|---|
KAKAO_NATIVE_APP_KEY |
์นด์นด์ค SDK ์ด๊ธฐํ (KakaoSdk.init) + ์นด์นด์ค ๋ก๊ทธ์ธ ์ฝ๋ฐฑ intent-filter ์ kakao{NATIVE_APP_KEY} scheme |
Kakao Developers โ ๋ด ์ ํ๋ฆฌ์ผ์ด์ โ ์ฑ ํค โ ๋ค์ดํฐ๋ธ ์ฑ ํค |
GOOGLE_WEB_CLIENT_ID |
Google ๋ก๊ทธ์ธ ์ CredentialManager.requestGoogleIdToken(serverClientId = ...) ์ server client id (๋ฐฑ์๋๊ฐ ID Token ์ aud ๋ฅผ ๊ฒ์ฆํ ์ ์๋๋ก Web client ID ์ฌ์ฉ) |
Google Cloud Console โ APIs & Services โ Credentials โ OAuth 2.0 Client IDs โ Web application ํ์ |
ํ๋ก์ ํธ ๋ฃจํธ์ local.properties ๋์ ๋ค์ ๋ผ์ธ ์ถ๊ฐ:
KAKAO_NATIVE_APP_KEY=<์นด์นด์ค ๋ค์ดํฐ๋ธ ์ฑ ํค>
GOOGLE_WEB_CLIENT_ID=<๊ตฌ๊ธ OAuth web client id>.apps.googleusercontent.com์ ๊ท ํ์์ ์ ๋ ํค๋ฅผ Slack DM ์ผ๋ก 1hyok ์๊ฒ ์์ฒญ. (์ง์ ๋ฐ๊ธ ๊ถํ์ด ์๋ ๊ฒฝ์ฐ ์ ์ฝ์์์ ์ง์ ์กฐํ ๊ฐ๋ฅ.)
๋ ํค๊ฐ ๋น์ด ์์ผ๋ฉด ๋น๋๋ ํต๊ณผํ์ง๋ง ๋ค์์ด ๊นจ์ง๋ค:
KakaoSdk.init("")โ SDK ์ด๊ธฐํ ์คํจ (์ฑ ๋ด ์๋ด:KAKAO_NATIVE_APP_KEY๋ฅผ ํ์ธํด์ฃผ์ธ์.)AndroidManifest.xml์android:scheme="kakao${KAKAO_NATIVE_APP_KEY}"๊ฐ ๋น scheme ์ผ๋ก ๋ฑ๋ก โ ์นด์นด์ค ๋ก๊ทธ์ธ ์ฝ๋ฐฑ intent-filter ๋งค์นญ ์ ๋จrequestGoogleIdToken(serverClientId = "")โ Credential Manager ๊ฐ invalid request ๋ก ์คํจ
๋์์ด๋ยทPMยทQAยท์ธ๋ถ ๋ฒ ํํ
์คํฐ์๊ฒ release APK ๋ฅผ ์๋ ๋ฐฐํฌํ๋ ํ๋ฆ. Firebase ํ๋ก์ ํธ afternote-b4d3c + ํ
์คํฐ ๊ทธ๋ฃน afternote ์ฌ์ฉ.
-
Release keystore ์์ฑ (๋ถ์ค ์ ์ฑ ์ ๋ฐ์ดํธ ์๊ตฌ ๋ถ๊ฐ โ 1Password / iCloud ๋ฑ 2๊ณณ ์ด์ ๋ฐฑ์ ํ์)
keytool -genkeypair -v \ -keystore ~/afternote-release.jks \ -keyalg RSA -keysize 4096 -validity 10000 \ -alias afternote-release -
local.properties๋์ 4๊ฐ ํค ์ถ๊ฐ (signing config ๊ฐ ์ฝ์)RELEASE_STORE_FILE=/Users/<you>/afternote-release.jks RELEASE_STORE_PASSWORD=<keystore ๋น๋ฐ๋ฒํธ> RELEASE_KEY_ALIAS=afternote-release RELEASE_KEY_PASSWORD=<key ๋น๋ฐ๋ฒํธ>
-
google-services.json๋ฐฐ์น โ Firebase Console โ ํ๋ก์ ํธ ์ค์ โ ์ผ๋ฐ โ Android ์ฑcom.afternote.afternote_fe์นด๋์์ ๋ค์ด๋ก๋ โapp/google-services.json -
Firebase CLI ์ค์น + ์ธ์ฆ (์๋ ์ ๋ก๋์ฉ)
npm install -g firebase-tools firebase login
-
์ฝ์์ ์ ๊ท keystore SHA ๋ฑ๋ก (๋ฐฐํฌ ๋ฐ์ ์ฌ๋์ ์นด์นด์ค/๊ตฌ๊ธ ๋ก๊ทธ์ธ ๋์ ์ํด)
- Release SHA-1 ์ถ์ถ:
keytool -list -v -keystore ~/afternote-release.jks -alias afternote-release | grep SHA1 - ์นด์นด์ค ํค ํด์ ์ถ์ถ:
keytool -exportcert -alias afternote-release -keystore ~/afternote-release.jks | openssl sha1 -binary | openssl base64 - Kakao Developers โ ์ฑ โ ํ๋ซํผ ํค โ Android โ ํค ํด์ ์ถ๊ฐ
- Firebase Console โ ํ๋ก์ ํธ ์ค์ โ Android ์ฑ โ SHA ์ธ์ฆ์ ์ง๋ฌธ ์ถ๊ฐ
- Release SHA-1 ์ถ์ถ:
develop โ main ๋จธ์ง๊ฐ push ๋๋ฉด GitHub Actions ์ํฌํ๋ก release-distribution.yml ๊ฐ ์๋ ์คํ โ APK ๋น๋ โ Firebase App Distribution ์
๋ก๋ โ ํ
์คํฐ ๊ทธ๋ฃน afternote ์ ์์๊ฒ ์๋ ์ด๋ฉ์ผ ๋ฐ์ก. ์ด์ ์ ์ฑ
"main ๋จธ์ง๋ ์ํ๋ง ๋ฐฐํฌ" ์ ์ผ์น.
CI ๊ฐ ์ฌ์ฉํ๋ GitHub Secrets (Settings โ Secrets and variables โ Actions):
| ํค | ์ฉ๋ |
|---|---|
RELEASE_STORE_FILE_B64 |
release keystore ํ์ผ (~/afternote-release.jks) ์ base64 ์ธ์ฝ๋ฉ |
RELEASE_STORE_PASSWORD |
keystore ๋น๋ฐ๋ฒํธ |
RELEASE_KEY_ALIAS |
key alias (afternote-release) |
RELEASE_KEY_PASSWORD |
key ๋น๋ฐ๋ฒํธ |
FIREBASE_SERVICE_ACCOUNT_JSON |
App Distribution Admin ๊ถํ ๋ถ์ฌ๋ service account JSON ์๋ฌธ |
KAKAO_NATIVE_APP_KEY ยท GOOGLE_WEB_CLIENT_ID ยท GOOGLE_SERVICES_JSON_B64 |
local.properties ํค (lint.yml ๊ณผ ๊ณต์ ) |
base64 ์ธ์ฝ๋ฉ:
base64 -i ~/afternote-release.jks | pbcopy(macOS)
./gradlew assembleRelease appDistributionUploadReleaseโ ๋์ผํ๊ฒ APK ๋น๋ + Firebase ์ ๋ก๋. CI ์ฅ์ ์ ๋๋ main ๋จธ์ง ์์ด ์์ ๋ฐฐํฌ ํ์ํ ๋ ์ฌ์ฉ.
๊ฐ์
versionCode๋ก ์ฌ์ ๋ก๋ํ๋ฉด ๊ธฐ์กด release ๊ฐฑ์ . ์ release ๋ง๋ค๋ ค๋ฉดapp/build.gradle.kts์versionCode์ฆ๊ฐ.
- ์ถ๊ฐ/์ ๊ฑฐ: Firebase Console โ App Distribution โ ํ
์คํฐ ๋ฐ ๊ทธ๋ฃน โ
afternote๊ทธ๋ฃน ํธ์ง - ์ ๊ท ํ ์คํฐ๋ ์ฒซ ์ด๋ ์ด๋ฉ์ผ์์ App Tester ์ฑ ์ค์น ์๋ด๋ฅผ ๋ฐ์ โ ์ดํ ๋น๋๋ ์๋ ์๋ฆผ
Compose Preview Screenshot Testing ์ anti-aliasing / font hinting / scale ๋ฑ host ํ๊ฒฝ ์์กด ๋ ๋๋ง ์ฐจ์ด๋ก CI rendered PNG ๋ฅผ baseline ์ผ๋ก ๊ต์ฒดํ๋ ping-pong ์ด ๋ฐ์ํด ์๋ค (PR #302 / #322). ๋ณธ ๋ฆฌํฌ์ Dockerfile.screenshot + .github/workflows/screenshot.yml ์ container ๋จ๊ณ๊ฐ baseline ์์ฑยท๊ฒ์ฆ์ ๋์ผ ํ๊ฒฝ์์ ์ํํด ํ๊ฒฝ ์ฐจ์ด root fix.
- Docker Desktop ์ค์น (๋ก์ปฌ macOS ยท Linux ๋ชจ๋ ๋์ผ)
docker build -t afternote-screenshot:latest -f Dockerfile.screenshot .
docker run --rm -v "$PWD":/workspace -w /workspace afternote-screenshot:latest \
./gradlew :core:ui:updateScreenshotTest \
:app:updateScreenshotTest \
:feature:onboarding:presentation:updateScreenshotTest \
:feature:afternote:presentation:updateScreenshotTestโ ๋ณ๊ฒฝ๋ PNG ๊ฐ ๊ฐ ๋ชจ๋ src/screenshotTestDebug/reference/... ์ ๊ฐฑ์ . git add ํ commit.
docker run --rm -v "$PWD":/workspace -w /workspace afternote-screenshot:latest \
./gradlew :core:ui:validateScreenshotTest \
:app:validateScreenshotTest \
:feature:onboarding:presentation:validateScreenshotTest \
:feature:afternote:presentation:validateScreenshotTestโ baseline ๊ณผ docker ํ๊ฒฝ์์ ์๋ก ๊ทธ๋ฆฐ PNG ๋น๊ต. ์คํจ ์ build/outputs/screenshotTest-results/preview/debug/diffs/ ์์ diff PNG ํ์ธ.
./gradlew :<module>:updateScreenshotTest ๋ฅผ host ์์ ์ง์ ์คํํ๋ฉด macOS / Linux / JDK ๋ง์ด๋ ๋ฒ์ / ํฐํธ ์บ์ ์ฐจ์ด๋ก CI ์ baseline ์ด ์ด๊ธ๋๋ค. docker ํ๊ฒฝ ํต์ผ์ด root fix.
docs/claude/ ์ 1hyok ์ด ๋ณธ repo ์์ Claude Code ๋ฅผ ์ฐ๋ฉด์ ๋์ ํ hook ยท CLAUDE.md ์ํ ยท ๋ฉ๋ชจ๋ฆฌ ํ
ํ๋ฆฟ์ด ์๋ค. ๊ฐ์ ์๋๊ณ ์ฐธ๊ณ ์ฉ.
๋ณธ์ธ Claude Code ์ํฌํ๋ก์ ๋์ ํ๊ณ ์ถ์ผ๋ฉด:
./scripts/install-claude-hooks.shโ docs/claude/hooks/*.sh ๋ฅผ ์๊ธฐ .claude/hooks/ ๋ก symlink (๊ธฐ์กด ํ์ผ ์์ผ๋ฉด skip โ ๋ฎ์ด์ฐ๊ธฐ 0). hook ๋ฑ๋กยทCLAUDE.md ์ผ๋ถ ๊ฐ์ ธ๊ฐ๊ธฐยท๋ฉ๋ชจ๋ฆฌ ๋์
๋ฑ ์์ธํ ๊ฐ์ด๋๋ docs/claude/README.md ์ฐธ๊ณ .
๋ณธ์ธ .claude/ ๋ .gitignore ๊ทธ๋๋ก๋ผ ๋ณธ ํด๋์ ๋ฌด๊ด โ ์ด๋ ์ชฝ๋ ๋ค๋ฅธ ์ชฝ์ ๊ฐ์ ํ์ง ์๋๋ค.
๋ค์ด๋ฐ ์ปจ๋ฒค์
- ๋ค์ด๋ฐ ํญ๋ชฉ ์์๋ android-style-guide๋ฅผ ์ค์ํ๋ค.
- ๋จ, Layout์ ์ ์ธํ ๋ค์ด๋ฐ์ CamelCase๋ฅผ ์ฌ์ฉํ๋ค.
- ์์)
android:id="@+id/tvPostNovelTitle" - ์์ธํ ์ ๋ณด๋ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์๋ค.
- ์์)
- Coding Style์ ๊ฐ์ฒด์งํฅ ์ํ ์ฒด์กฐ ์์น์ ์ค์ํ๋ค.
- ์์ธํ ์ ๋ณด๋ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์๋ค.
[Java] ๊ฐ์ฒด์งํฅ ์ํ ์ฒด์กฐ ์์น 9๊ฐ์ง (from ์ํธ์์ค ์ค์๋ฌ์ง)
๋ธ๋์น ์ ๋ต
- GitHub Flow๋ฅผ ์ฌ์ฉํ๋ค.
- ์์๋ก ์ฝ๋๊ฐ ๋ณํ๋ ์ฑ์ผ์ ํน์ฑ์ ๊ณ ๋ คํ์๋ค.
- ๋ธ๋์น ์ด๋ฆ์ ๋ค์๊ณผ ๊ฐ์ด ์ธ๋๋ฐ๋ฅผ ์ฌ์ฉํ๋ค.
- ์์)
feat/post_novel
- ์์)
- ์์ธํ ์ ๋ณด๋ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์๋ค.
[GIT] ๐ ๊น ๋ธ๋์น ์ ๋ต ์ ๋ฆฌ - Github Flow / Git Flow
Commit ์ปจ๋ฒค์
- ์ฌ์ฉํ ์ปค๋ฐ ํ์
์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๐ฏ [FEAT] ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ
- โป๏ธย [REFACTOR] ์ฝ๋ ๋ฆฌํฉํ ๋ง
- ๐จย [FIX] ๋ฒ๊ทธ ์์
- ๐งย [BUILD] ๋น๋ ์ ๋ฌด ์์ , ํจํค์ง ๋งค๋์ ์์
- ์ปค๋ฐ ๋ฉ์์ง ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์์)
feat: color system ๊ตฌ์ฑ
- ์์)
- ์ปค๋ฐ ๋ฉ์์ง๋ ํ๊ธ๋ก ์์ฑํ๊ณ , ์ด์ ๋ฒํธ๋ ๋ณ๋๋ก ํ๊ธฐํ์ง ์๋๋ค.
Issue ์ปจ๋ฒค์
- ์ ๋ชฉ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์์)
feat: library view ๊ตฌํ
- ์์)
## โ๏ธ Kind (Required) <!-- ์ด์ ์ข
๋ฅ๋ฅผ ์ ํํด์ฃผ์ธ์ -->
`FEATURE` `BUG`
## ๐ Overview (Required) <!-- ์ด์์ ๋ํด ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํด์ฃผ์ธ์ -->
> **โ๏ธ To do** <!-- ์งํํ ์์
์ ๋ํด ์ ์ด์ฃผ์ธ์ -->
> - [ ] color system ๊ตฌ์ฑ _(์์)_
## ๐ Note (Optional) <!-- ํน์ด์ฌํญ์ ์ ์ด์ฃผ์ธ์ -->PR ์ปจ๋ฒค์
- ์ ๋ชฉ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์์)
feat: bottomNavigation color system ์ ์ฉ
- ์์)
## ๐๐๐ด๐ด๐ถ๐ฆ๐ด
- closed #
## ๐๐๐ฐ๐ณ๐ฌ ๐๐ฆ๐ด๐ค๐ณ๐ช๐ฑ๐ต๐ช๐ฐ๐ฏ
-
-
## ๐ท๐๐ค๐ณ๐ฆ๐ฆ๐ฏ๐ด๐ฉ๐ฐ๐ต
## ๐ฌ๐๐ฐ ๐๐ฆ๐ท๐ช๐ฆ๐ธ๐ฆ๐ณ๐ดCode Review ์ปจ๋ฒค์ ๋ฐ ์ถ๊ฐ์ ๋ณด
- Merge๋ ๋ฆฌ๋ทฐ ์ธ์ 2๋ช ์ ์น์ธ์ ๋ฐ๋๋ค.
- ๋ฆฌ๋ทฐ ์ธ์์ผ๋ก ํ ๋น๋ฐ์ ์ฌ๋์ 12์๊ฐ ์ด๋ด์ ์ฝ๋๋ฆฌ๋ทฐ๋ฅผ ์๋ฃํ๋ค.
- RCA๋ฃฐ์ ํตํด Prefix๋ฅผ ์ ๊ณ , ์ฝ๋ ๋ฆฌ๋ทฐ ๋ฐ์์ ์ฐ์ ์์๋ฅผ ํ์ํ๋ค.
- R (Request Changes) : ์ ๊ทน์ ์ผ๋ก ๋ฐ์์ ๊ณ ๋ คํด์ฃผ์ธ์.
- C (Comment) : ์ฌ๋งํ๋ฉด ๋ฐ์ํด์ฃผ์ธ์.
- A (Approve) : ๋ฐ์ํด๋ ์ข๊ณ , ๋์ด๊ฐ๋ ์ข์ต๋๋ค. ์ฌ์ํ ์๊ฒฌ์
๋๋ค.
- ์์)
R: @Data ์ด๋ ธํ ์ด์ ์ฌ์ฉ์ ์ง์ํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค. ์ฐธ๊ณ ์๋ฃ ๋ณ์ฒจํฉ๋๋ค.
- ์์)