Skip to content

Commit cc901d0

Browse files
committed
feat: GitHub Actions 워크플로우 및 템플릿 추가
- **Android CI 워크플로우 추가 (`android-ci.yml`)** - `main` 또는 `develop` 브랜치에 대한 PR 발생 시, 전체 프로젝트에 대해 워크플로우를 실행하도록 설정했습니다. - 주요 단계: JDK 17 설정, Gradle 캐싱, `local.properties` 및 `google-services.json` 생성, 키스토어 복원, ktlint 검사, 단위 테스트 실행 및 결과 게시 - **Slack 알림 워크플로우 추가** - `common-slack-notify-opened.yml`: PR 생성 및 리뷰 준비 시 최초 리뷰 요청 알림을 보냅니다. - `common-slack-notify-rerequested.yml`: 재리뷰 요청 시 알림을 보냅니다. - `common-slack-notify-submitted.yml`: 리뷰가 제출(승인, 변경 요청)되었을 때 알림을 보냅니다. - **Release Drafter 워크플로우 추가 (`release-drafter.yml`)** - `release/*` 브랜치에 푸시될 때 릴리스 초안을 업데이트하고, `main` 브랜치에 푸시 시 릴리스를 게시합니다. - **GitHub 템플릿 추가** - 이슈 생성을 위한 `festabook-issue-template.md`를 추가했습니다. - Pull Request 생성을 위한 `PULL_REQUEST_TEMPLATE.md`를 추가했습니다. - 릴리스 노트 생성을 위한 `release-drafter.yml` 템플릿을 추가했습니다. - **프로젝트 설정 파일 추가** - `.editorconfig`: ktlint 규칙을 설정합니다. - `.coderabbit.yaml`: Code Rabbit AI 리뷰어의 설정을 추가했습니다. - `.gitignore`: `festabook-firebase-ad` 파일을 무시하도록 추가했습니다.
1 parent e342cd5 commit cc901d0

11 files changed

+531
-9
lines changed

.coderabbit.yaml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# ─────────── 전역(공통) 설정 ───────────
2+
language: ko-KR
3+
tone_instructions: "1. 리뷰 시에는 변경 사항의 문제점이나 한계점을 구체적으로 짚어주고, \n 2. 왜 해당 부분이 비효율적이거나 권장되지 않는지 명확한 근거와 함께 설명해주세요. \n 3. 대안을 제시할 땐, 선택지를 제안하면서 각각의 장단점도 논리적으로 설명해주세요. \n 4. 단순 지적보다는 개선 방향에 집중하고, 학습적인 관점에서 이해를 돕는 코멘트를 남겨주세요. \n 5. 지나치게 딱딱하지 않되, 논리의 흐름이 분명하게 전달되도록 해주세요."
4+
5+
# ─────────── 리뷰(Reviews) 전반 ───────────
6+
reviews:
7+
profile: chill
8+
high_level_summary: true
9+
high_level_summary_placeholder: "🤖 Code Rabbit PR 요약"
10+
review_status: true
11+
commit_status: true
12+
13+
# 워크스루/자동화/부가 기능
14+
collapse_walkthrough: false
15+
changed_files_summary: false
16+
sequence_diagrams: false
17+
assess_linked_issues: true
18+
related_issues: false
19+
related_prs: false
20+
suggested_labels: false
21+
auto_apply_labels: false
22+
suggested_reviewers: false
23+
auto_assign_reviewers: false
24+
poem: false
25+
26+
# 경로별 리뷰 지침 및 제외 폴더
27+
path_instructions:
28+
- path: android/**
29+
instructions: |
30+
- 1. 코틀린 공식 스타일 가이드 및 팀 컨벤션을 우선적으로 반영하여, 가독성, 안전성(Null/예외처리), 테스트/유지보수 용이성, 안드로이드 특화 사항(라이프사이클, 리소스, 권한 등)에 대해 리뷰해주세요.
31+
- 2. 최신 코틀린/안드로이드 트렌드, 주석 및 문서화, 팀 스타일 통일성도 함께 확인해 주세요.
32+
- 3. 각 리뷰 포인트별로 문제점과 대안, 장단점을 논리적으로 제시하고, 필요한 경우 예시 코드도 추가해 주세요.
33+
- 4. 리뷰가 너무 많아서 피로감을 줄 수 있으니, 꼭 필요한 부분에 집중해주고, 나머지는 캡션으로 설명해주세요.
34+
- 5. 리뷰 남겨주는 부분은 해당 라인 범위의 코멘트에 작성해주세요.
35+
- path: backend/**
36+
instructions: |
37+
- 1. 팀 및 공식 컨벤션, 가독성, 예외처리, 테스트/확장/유지보수성, 모듈화, API/DB/보안 설계 기준을 기반으로 리뷰해주세요.
38+
- 2. 최신 트렌드, 불필요한 로직, 클린코드, 리팩토링, 서비스/도메인 설계, 공통 예외 처리, 확장성도 함께 확인해주세요.
39+
- 3. 각 피드백은 문제점·대안·장단점을 짧고 논리적으로, 예시 코드가 있다면 간결히 포함해 주세요.
40+
- 4. 팀 내 스타일 통일성도 확인해주세요.
41+
- 5. 미작성한 테스트 코드 케이스가 있다면, 어떤 테스트가 필요한지 제안해주세요. (예: 컨트롤러는 인수 테스트, 나머지는 단위 테스트)
42+
- 6. 리뷰 남겨주는 부분은 해당 라인 범위의 코멘트에 작성해주세요.
43+
- path: frontend/**
44+
instructions: |
45+
- 우리는 백엔드 개발자 팀으로, 관리자 페이지 프론트엔드를 Vibe 코딩 방식으로 빠르게 구현했습니다.
46+
- React에 대한 전문적인 이해도가 부족한 상태이므로, 다음과 같은 기준으로 리뷰해 주세요:
47+
- 1. 코드 스타일이나 컴포넌트 구조 등 전반적인 구조에 대한 일반적인 피드백은 생략해 주세요.
48+
- 2. 보안상 취약점이 될 수 있는 부분 (예: XSS, CSRF, 사용자 입력 검증 부족 등) 은 반드시 알려주세요.
49+
- 3. 화면 상 명백하게 어색하거나 비정상적으로 동작할 수 있는 UI/UX 요소만 지적해 주세요.
50+
- 4. 빠른 배포를 목적으로 하기 때문에, 논리상 큰 이상이 없는 부분은 코멘트하지 않으셔도 됩니다.
51+
- 5. 실제 사용자에게 혼동을 줄 수 있는 부분(버튼 비노출, 접근 불가능 등)이 있다면 꼭 알려주세요.
52+
- 6. 해당 PR에는 테스트 코드가 포함되지 않았으며, 테스트 커버리지나 테스트 방식에 대한 피드백은 생략해 주세요.
53+
- 위 기준을 바탕으로 꼭 필요한 피드백 위주로 리뷰 부탁드립니다.
54+
55+
# 리뷰 진행/캐시/자동화
56+
abort_on_close: true
57+
disable_cache: false
58+
59+
auto_review:
60+
enabled: true
61+
auto_incremental_review: true
62+
base_branches: [ "android", "backend", "frontend" ]
63+
64+
finishing_touches:
65+
docstrings:
66+
enabled: true
67+
unit_tests:
68+
enabled: true
69+
70+
# ─────────── 채팅(Chat) 설정 ───────────
71+
chat:
72+
auto_reply: true
73+
74+
# ─────────── 지식 기반(Knowledge base) ───────────
75+
knowledge_base:
76+
opt_out: false
77+
78+
web_search:
79+
enabled: true
80+
81+
code_guidelines:
82+
enabled: true
83+
filePatterns:
84+
- backend/code-style.md
85+
- android/code-style.md
86+
87+
learnings:
88+
scope: auto
89+
issues:
90+
scope: local
91+
pull_requests:
92+
scope: local
93+
94+
# ─────────── 코드 생성(Code generation) ───────────
95+
code_generation:
96+
docstrings:
97+
language: ko-KR
98+
path_instructions:
99+
- path: backend/**
100+
instructions: |
101+
- JavaDoc 공식 형식으로, 한글로 Docstring을 작성해주세요.
102+
- 메서드 목적, 파라미터, 반환값, 예외 정보를 명확하게 기술해 주세요.
103+
- 외부 API 등 공개 메서드는 상세히, 내부용은 핵심만 요약해 주세요.
104+
105+
- path: android/**
106+
instructions: |
107+
- 모든 public 함수에 대해 KDoc 양식을 따라 한글로 간결하게 Docstring을 작성해주세요.
108+
- 함수 목적, 파라미터, 반환값, 예외를 명확하게 기술해 주세요.
109+
- 샘플 코드/사용 예시는 필요한 경우에만 포함해 주세요.
110+
111+
unit_tests:
112+
path_instructions:
113+
- path: backend/**
114+
instructions: |
115+
- Controller는 인수테스트(API 엔드포인트 통합 테스트) 나머지 영역은 함수/클래스 단위의 단위 테스트
116+
- Given-When-Then 패턴을 적용
117+
118+
# ─────────── 코드 분석 도구(Tools) ───────────
119+
tools:
120+
hadolint:
121+
enabled: true
122+
gitleaks:
123+
enabled: true
124+
sqlfluff:
125+
enabled: true
126+
oxc:
127+
enabled: true

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[*.{kt,kts}]
2+
ktlint_standard_annotation = disabled
3+
ktlint_function_naming_ignore_when_annotated_with = Composable
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: "🚀 이슈"
3+
about: "[Festabook] 프로젝트 이슈 템플릿"
4+
title: "[Tag] 이슈 제목"
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
## 📝 개요
11+
12+
이슈에 대한 간략한 설명을 작성해주세요.
13+
14+
## ✅ 할 일
15+
16+
- [ ] 첫 번째 할 일
17+
- [ ] 두 번째 할 일

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## #️⃣ 이슈 번호
2+
3+
> ex) #이슈번호, #이슈번호
4+
5+
<br>
6+
7+
## 🛠️ 작업 내용
8+
9+
- 구현한 기능을 작성해주세요.
10+
11+
<br>
12+
13+
## 🙇🏻 중점 리뷰 요청
14+
15+
- 특히 확인이 필요한 부분, 고민했던 부분 등을 적어주세요.
16+
17+
<br>
18+
19+
## 📸 이미지 첨부 (Optional)
20+
21+
<img src="파일주소" width="50%" height="50%"/>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name-template: "v$RESOLVED_VERSION"
2+
tag-template: "v$RESOLVED_VERSION"
3+
version-template: $MAJOR.$MINOR.$PATCH
4+
5+
categories:
6+
- title: "🚀 기능 추가"
7+
labels:
8+
- "Feat"
9+
- title: "⚙️ 기능 개선"
10+
labels:
11+
- "Refactor"
12+
- title: "🐛 버그 수정"
13+
labels:
14+
- "Fix"
15+
- title: "🧰 그 외"
16+
labels:
17+
- "Chore"
18+
- "CI/CD"
19+
- "Docs"
20+
- "Build"
21+
- "Common"
22+
- "Test"
23+
24+
version-resolver:
25+
major:
26+
labels:
27+
- "Major"
28+
minor:
29+
labels:
30+
- "Minor"
31+
patch:
32+
labels:
33+
- "Patch"
34+
default: minor
35+
36+
exclude-labels:
37+
- "Release"
38+
39+
change-template: "- $TITLE (#$NUMBER) - @$AUTHOR"
40+
change-title-escapes: '\<*_&'
41+
42+
template: |
43+
## ✨ 변경 사항
44+
$CHANGES
45+
46+
## 📦 전체 변경 이력
47+
[$PREVIOUS_TAG ~ v$RESOLVED_VERSION](https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION)

.github/workflows/android-ci.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Android CI
2+
3+
on:
4+
pull_request:
5+
# 'main' 또는 'android' 브랜치로 PR이 병합될 때 트리거
6+
branches:
7+
- main
8+
- develop
9+
# 'android' 디렉토리 내의 파일이 변경되었을 때만 워크플로우를 실행
10+
path:
11+
- '/**'
12+
13+
jobs:
14+
Run-PR-Test:
15+
runs-on: ubuntu-latest
16+
defaults:
17+
run:
18+
working-directory: android
19+
20+
steps:
21+
- name: Repository Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Set up JDK 17
25+
uses: actions/setup-java@v4
26+
with:
27+
java-version: '17'
28+
distribution: 'temurin'
29+
30+
- name: Gradle cache
31+
uses: actions/cache@v4
32+
with:
33+
path: |
34+
~/.gradle/caches
35+
~/.gradle/wrapper
36+
~/.android/build-cache
37+
key: ${{ runner.os }}-gradle-${{ hashFiles('android/**/build.gradle.kts', 'android/**/settings.gradle.kts', 'android/**/gradle-wrapper.properties', 'android/gradle/libs.versions.toml', 'android/**/gradle.properties') }}
38+
restore-keys: |
39+
${{ runner.os }}-gradle-
40+
41+
- name: Create local.properties with BASE_URL
42+
run: |
43+
echo BASE_URL=\"${{ secrets.BASE_URL }}\" > local.properties
44+
echo BASE_URL_DEV=\"${{ secrets.BASE_URL_DEV }}\" >> local.properties
45+
echo NAVER_MAP_CLIENT_ID=\"${{ secrets.NAVER_MAP_CLIENT_ID }}\" >> local.properties
46+
echo NAVER_MAP_STYLE_ID=\"${{ secrets.NAVER_MAP_STYLE_ID }}\" >> local.properties
47+
48+
- name: Load Google Service file
49+
env:
50+
DATA: ${{ secrets.GOOGLE_SERVICES_JSON }}
51+
run: echo "$DATA" > app/google-services.json
52+
53+
- name: Restore keystore file
54+
run: |
55+
mkdir -p app
56+
echo "$KEYSTORE_BASE64" | base64 --decode > ./app/festabook_appkey.jks
57+
echo "JKS_FILE_PATH=./app/festabook_appkey.jks" >> local.properties
58+
echo "STORE_PASSWORD=${{ secrets.STORE_PASSWORD }}" >> local.properties
59+
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> local.properties
60+
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> local.properties
61+
62+
env:
63+
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
64+
65+
- name: Clean Project
66+
run: ./gradlew clean
67+
68+
- name: Run ktlint
69+
run: ./gradlew ktlintCheck
70+
71+
- name: Run Unit Test
72+
run: ./gradlew test
73+
74+
- name: Publish Unit Test Results
75+
if: always()
76+
uses: EnricoMi/publish-unit-test-result-action@v2
77+
with:
78+
files: android/app/build/test-results/**/TEST-*.xml
79+
check_name: '테스트 결과 🛠️'
80+
check_run_annotations: 'none'
81+
comment_mode: 'off'
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Slack Notification (Opened/Ready)
2+
3+
on:
4+
pull_request:
5+
types: [opened, ready_for_review]
6+
7+
permissions: {}
8+
9+
concurrency:
10+
group: pr-${{ github.event.pull_request.number }}-slack-opened-ready
11+
cancel-in-progress: true
12+
13+
# 최초 리뷰 요청 알림
14+
jobs:
15+
notify:
16+
runs-on: ubuntu-latest
17+
steps:
18+
# JSON 파싱 도구
19+
- name: Install jq
20+
run: sudo apt-get update && sudo apt-get install -y jq
21+
22+
- name: Notify Initial Reviewers
23+
env:
24+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
25+
PR_TITLE: ${{ github.event.pull_request.title }}
26+
PR_NUMBER: ${{ github.event.pull_request.number }}
27+
PR_URL: ${{ github.event.pull_request.html_url }}
28+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
29+
REVIEWERS_JSON: ${{ toJson(github.event.pull_request.requested_reviewers) }}
30+
run: |
31+
declare -A GITHUB_TO_SLACK
32+
GITHUB_TO_SLACK["soeun2537"]="U09A0LM0CRW"
33+
GITHUB_TO_SLACK["taek2222"]="U099ARRH3D3"
34+
GITHUB_TO_SLACK["changuii"]="U099BR9RNE6"
35+
GITHUB_TO_SLACK["eoehd1ek"]="U0995NANDML"
36+
GITHUB_TO_SLACK["oungsi2000"]="U098U2R57NK"
37+
GITHUB_TO_SLACK["parkjiminnnn"]="U098U8SLXHD"
38+
GITHUB_TO_SLACK["etama123"]="U0995MPSZ62"
39+
40+
author_id=${GITHUB_TO_SLACK[$PR_AUTHOR]}
41+
if [[ -n "$author_id" ]]; then
42+
SLACK_AUTHOR_MENTION="<@$author_id>"
43+
else
44+
SLACK_AUTHOR_MENTION="@${PR_AUTHOR}"
45+
fi
46+
47+
REVIEWER_MENTIONS=""
48+
for reviewer in $(echo "$REVIEWERS_JSON" | jq -r '.[].login'); do
49+
[[ "$reviewer" == *"[bot]" ]] && continue
50+
slack_id=${GITHUB_TO_SLACK[$reviewer]}
51+
[[ -z "$slack_id" ]] && continue
52+
REVIEWER_MENTIONS+="<@$slack_id> "
53+
done
54+
55+
if [ -z "$REVIEWER_MENTIONS" ]; then
56+
echo "리뷰어가 없으므로 알림 생략"
57+
exit 0
58+
fi
59+
60+
curl -X POST -H 'Content-type: application/json' \
61+
--data "{\"text\": \"🔥 *리뷰 요청 알림*\n*PR 제목:* ${PR_TITLE} (#${PR_NUMBER})\n*작성자:* ${SLACK_AUTHOR_MENTION}\n*리뷰어:* ${REVIEWER_MENTIONS}\n*링크:* ${PR_URL}\"}" \
62+
$SLACK_WEBHOOK_URL

0 commit comments

Comments
 (0)