Skip to content

Commit 5a74f6c

Browse files
authored
Merge pull request #1 from bssm-oss/feat/bootstrap-rhythm-replica-pr
feat: bootstrap Rhythm Replica macOS app scaffold
2 parents 6435531 + 9c7e670 commit 5a74f6c

64 files changed

Lines changed: 4973 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Bug Report
2+
description: Report a bug in Rhythm Replica
3+
title: "[Bug] "
4+
labels: [bug]
5+
body:
6+
- type: textarea
7+
id: summary
8+
attributes:
9+
label: Summary
10+
- type: textarea
11+
id: steps
12+
attributes:
13+
label: Steps to reproduce
14+
- type: textarea
15+
id: expected
16+
attributes:
17+
label: Expected behavior
18+
- type: textarea
19+
id: actual
20+
attributes:
21+
label: Actual behavior
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Feature Request
2+
description: Suggest an improvement for Rhythm Replica
3+
title: "[Feature] "
4+
labels: [enhancement]
5+
body:
6+
- type: textarea
7+
id: problem
8+
attributes:
9+
label: Problem or goal
10+
- type: textarea
11+
id: proposal
12+
attributes:
13+
label: Proposed solution

.github/pull_request_template.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## 배경
2+
3+
## 변경 내용
4+
5+
## 설계 판단 이유
6+
7+
## 테스트 결과
8+
9+
## 실제 사용자 시나리오 검증 결과
10+
11+
## 문서 반영 여부
12+
13+
## 영향 범위
14+
15+
## 리스크 / 남은 과제

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, feat/**, fix/**, chore/**, docs/**]
6+
pull_request:
7+
8+
jobs:
9+
build-and-test:
10+
runs-on: macos-13
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Install XcodeGen
14+
run: brew install xcodegen
15+
- name: Generate project
16+
run: xcodegen generate
17+
- name: Build
18+
run: xcodebuild -project RhythmReplica.xcodeproj -scheme RhythmReplica -destination 'platform=macOS' build
19+
- name: Test
20+
run: xcodebuild -project RhythmReplica.xcodeproj -scheme RhythmReplica -destination 'platform=macOS' test

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
release:
10+
runs-on: macos-13
11+
permissions:
12+
contents: write
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Install XcodeGen
16+
run: brew install xcodegen
17+
- name: Generate project
18+
run: xcodegen generate
19+
- name: Test
20+
run: /usr/bin/xcodebuild -project RhythmReplica.xcodeproj -scheme RhythmReplica -destination 'platform=macOS' test
21+
- name: Build release app
22+
run: ./scripts/build-release.sh
23+
- name: Import signing certificate
24+
if: ${{ secrets.CERTIFICATE_P12 != '' && secrets.CERTIFICATE_PASSWORD != '' && secrets.DEVELOPER_ID_APPLICATION != '' }}
25+
run: |
26+
echo "$CERTIFICATE_P12" | base64 --decode > build/certificate.p12
27+
security create-keychain -p runner build.keychain
28+
security default-keychain -s build.keychain
29+
security unlock-keychain -p runner build.keychain
30+
security import build/certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign
31+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k runner build.keychain
32+
env:
33+
CERTIFICATE_P12: ${{ secrets.CERTIFICATE_P12 }}
34+
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
35+
- name: Sign app bundle
36+
if: ${{ secrets.CERTIFICATE_P12 != '' && secrets.CERTIFICATE_PASSWORD != '' && secrets.DEVELOPER_ID_APPLICATION != '' }}
37+
run: |
38+
codesign --force --deep --options runtime --sign "$DEVELOPER_ID_APPLICATION" "build/Products/Rhythm Replica.app"
39+
env:
40+
DEVELOPER_ID_APPLICATION: ${{ secrets.DEVELOPER_ID_APPLICATION }}
41+
- name: Package DMG
42+
run: ./scripts/package-dmg.sh
43+
- name: Notarize app bundle
44+
if: ${{ secrets.APPLE_ID != '' && secrets.APPLE_TEAM_ID != '' && secrets.APP_SPECIFIC_PASSWORD != '' && secrets.DEVELOPER_ID_APPLICATION != '' }}
45+
run: |
46+
xcrun notarytool submit "build/RhythmReplica.dmg" --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APP_SPECIFIC_PASSWORD" --wait
47+
xcrun stapler staple "build/Products/Rhythm Replica.app"
48+
xcrun stapler staple "build/RhythmReplica.dmg"
49+
env:
50+
APPLE_ID: ${{ secrets.APPLE_ID }}
51+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
52+
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
53+
- name: SHA256
54+
run: ./scripts/sha256.sh build/RhythmReplica.dmg > build/RhythmReplica.dmg.sha256
55+
- name: Create release
56+
uses: softprops/action-gh-release@v2
57+
with:
58+
files: |
59+
build/RhythmReplica.dmg
60+
build/RhythmReplica.dmg.sha256
61+
env:
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.DS_Store
2+
DerivedData/
3+
build/
4+
.build/
5+
*.xcworkspace/xcuserdata/
6+
*.xcodeproj/xcuserdata/
7+
*.xcodeproj/project.xcworkspace/xcuserdata/
8+
*.xcuserstate
9+
xcuserdata/
10+
RhythmReplica/Resources/Cache/
11+
RhythmReplica/Resources/ImportedAudio/
12+
tmp/
13+
tmp-audio/
14+
*.m4a
15+
*.mp3
16+
*.wav
17+
*.aac
18+
*.flac
19+
.sisyphus/

AGENTS.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# AGENTS.md
2+
3+
## 프로젝트 목적
4+
5+
Rhythm Replica는 macOS용 네이티브 리듬게임 + 채보 편집기입니다. 오디오 재생 시간 기준의 정확한 플레이 경험과 키보드 중심의 에디팅 경험을 동시에 유지하는 것이 핵심입니다.
6+
7+
## 빠른 시작
8+
9+
```bash
10+
xcodegen generate
11+
open RhythmReplica.xcodeproj
12+
```
13+
14+
CLI 빌드:
15+
16+
```bash
17+
xcodebuild -project RhythmReplica.xcodeproj -scheme RhythmReplica -destination 'platform=macOS' build
18+
```
19+
20+
테스트:
21+
22+
```bash
23+
xcodebuild -project RhythmReplica.xcodeproj -scheme RhythmReplica -destination 'platform=macOS' test
24+
```
25+
26+
## 기본 작업 순서
27+
28+
1. `README.md`, `AGENTS.md`, `docs/`부터 읽기
29+
2. `project.yml` 기준으로 Xcode 프로젝트 재생성
30+
3. 수정 범위와 영향 모듈 파악
31+
4. 로직 변경 시 테스트 먼저 추가 또는 수정
32+
5. UI 변경 시 수동 검증 시나리오 기록
33+
6. 문서 갱신
34+
7. 빌드/테스트/수동 검증 후 마무리
35+
36+
## 완료 조건
37+
38+
- 수정 요청이 실제 코드에 반영됨
39+
- 관련 테스트가 추가/수정되고 실행됨
40+
- `xcodebuild build` 또는 `test`가 요구 범위에서 통과함
41+
- README/AGENTS/docs가 실제 동작과 일치함
42+
- 사용자 관점 검증 결과가 남아 있음
43+
44+
## 코드 스타일 원칙
45+
46+
- AppKit 컨트롤러는 화면 조합과 사용자 이벤트만 담당
47+
- 순수 계산 로직은 `Core` / `Game` 안에 두고 테스트 가능하게 유지
48+
- 실제 판정/점수는 오디오 시간 기준으로 계산
49+
- 타입 안정성을 깨는 우회(`as!`, 억지 캐스팅, 타입 무시) 금지
50+
- 사용자 오류 메시지는 이해 가능한 문장으로 작성
51+
52+
## 파일 구조 원칙
53+
54+
- `RhythmReplica/App`: 앱 진입, 윈도우, 내비게이션
55+
- `RhythmReplica/Core`: 모델, 포맷, 검증, 저장소
56+
- `RhythmReplica/Audio`: 재생, 파형, 시간 동기
57+
- `RhythmReplica/Game`: 판정, 점수, 입력, 플레이 상태
58+
- `RhythmReplica/Editor`: 타임라인, 렌더링, 편집 명령
59+
- `RhythmReplica/Import`: 파일/YouTube 가져오기
60+
- `RhythmReplica/Settings`: 환경설정, 키 바인딩
61+
62+
## 문서화 원칙
63+
64+
- 채보 포맷 변경 시 `docs/chart-format.md` 필수 갱신
65+
- UI/디자인 토큰 변경 시 `docs/design-system.md` 갱신
66+
- 릴리즈 절차 변경 시 `docs/release.md` 또는 `docs/packaging-dmg.md` 갱신
67+
68+
## 테스트 원칙
69+
70+
- 순수 계산 로직은 XCTest로 보호
71+
- 회귀 버그는 재현 테스트 추가
72+
- AppKit 상호작용은 자동화가 어려우면 수동 검증 절차를 문서화
73+
74+
## 브랜치 / 커밋 / PR 규칙
75+
76+
- 기본 브랜치에서 직접 작업하지 않음
77+
- 권장 브랜치: `feat/...`, `fix/...`, `docs/...`, `ci/...`
78+
- 구현, 테스트, 문서는 가능하면 분리 커밋
79+
- PR에는 배경, 변경점, 테스트, 수동 검증, 리스크를 적음
80+
81+
## 민감한 경로 / 주의 경로
82+
83+
- `RhythmReplica/Audio/`: 타이밍 정확도에 직접 영향
84+
- `RhythmReplica/Game/`: 판정, 점수, HP 규칙
85+
- `docs/chart-format.md`: 외부 호환 계약 문서
86+
- `.github/workflows/`: 배포 파이프라인
87+
88+
## 작업 전 체크리스트
89+
90+
- 프로젝트 생성 또는 갱신이 필요한가?
91+
- 변경이 채보 포맷에 영향 주는가?
92+
- 테스트 fixture 수정이 필요한가?
93+
- 사용자 설정/자동 저장에 영향이 있는가?
94+
95+
## 작업 후 체크리스트
96+
97+
- 빌드/테스트 실행
98+
- 수동 검증 결과 기록
99+
- 문서 갱신 확인
100+
- 불완전 기능은 UI에 Disabled/TODO 상태로 명시했는가?
101+
102+
## 절대 하면 안 되는 것
103+
104+
- 실행하지 않은 테스트를 통과했다고 보고하지 않기
105+
- 오디오 시간 대신 프레임 타이머만 믿고 판정하지 않기
106+
- 외부 다운로드 도구를 앱 내부 숨은 로직처럼 동작시키지 않기
107+
- 권한/약관 우회 기능 추가하지 않기
108+
- 문서와 실제 동작을 불일치 상태로 두지 않기

AppLauncher/main.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import RhythmReplicaKit
2+
3+
RhythmReplicaAppMain.run()

CONTRIBUTING.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Contributing
2+
3+
## 개발 환경 준비
4+
5+
1. Xcode 15 이상 설치
6+
2. XcodeGen 설치
7+
3. 저장소 루트에서 `xcodegen generate`
8+
4. `RhythmReplica.xcodeproj` 열기
9+
10+
## 권장 작업 흐름
11+
12+
1. 이슈 또는 작업 목적을 명확히 정리합니다.
13+
2. 기능 단위 브랜치를 만듭니다.
14+
3. 로직 변경은 테스트부터 보강합니다.
15+
4. UI 변경은 수동 검증 시나리오를 함께 남깁니다.
16+
5. 문서와 코드가 같은 사실을 말하는지 확인합니다.
17+
18+
## 커밋 메시지 예시
19+
20+
- `feat(game): add audio-time based judgement flow`
21+
- `test(core): cover chart validator overlap cases`
22+
- `docs(readme): explain local install and release flow`
23+
24+
## Pull Request 체크리스트
25+
26+
- [ ] 빌드 또는 테스트를 실제로 실행했다
27+
- [ ] 변경 이유를 설명했다
28+
- [ ] 문서 반영 여부를 적었다
29+
- [ ] 수동 검증 결과를 적었다
30+
- [ ] 남은 리스크를 숨기지 않았다

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 BSSM OSS
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)