From 7d588e6862cb845764375ab00bd0e5912f51bbf3 Mon Sep 17 00:00:00 2001 From: hmmhmmhm Date: Thu, 23 Oct 2025 00:04:14 +0900 Subject: [PATCH 1/3] chore: add macOS code signing and notarization setup --- apps/browser/.gitignore | 4 + apps/browser/CODESIGN_SETUP.md | 212 +++++++++++++++++++++++++++ apps/browser/QUICK_START.md | 106 ++++++++++++++ apps/browser/package.json | 5 +- apps/browser/scripts-src/notarize.ts | 40 +++++ apps/browser/scripts/notarize.d.ts | 1 + pnpm-lock.yaml | 5 +- 7 files changed, 370 insertions(+), 3 deletions(-) create mode 100644 apps/browser/CODESIGN_SETUP.md create mode 100644 apps/browser/QUICK_START.md create mode 100644 apps/browser/scripts-src/notarize.ts create mode 100644 apps/browser/scripts/notarize.d.ts diff --git a/apps/browser/.gitignore b/apps/browser/.gitignore index 077bd14..46a4faa 100644 --- a/apps/browser/.gitignore +++ b/apps/browser/.gitignore @@ -10,3 +10,7 @@ release # Compiled scripts (TypeScript sources in scripts-src/) scripts/*.js + +# Environment variables (contains sensitive data) +.env.local +.env.*.local diff --git a/apps/browser/CODESIGN_SETUP.md b/apps/browser/CODESIGN_SETUP.md new file mode 100644 index 0000000..084fa17 --- /dev/null +++ b/apps/browser/CODESIGN_SETUP.md @@ -0,0 +1,212 @@ +# 코드 서명 및 공증 설정 가이드 + +이 문서는 macOS에서 aka-browser를 배포하기 위한 코드 서명 및 공증 설정 방법을 설명합니다. + +## 1. Developer ID Application 인증서 생성 + +### 1-1. CSR (Certificate Signing Request) 생성 + +1. **키체인 접근** 앱 실행 +2. 메뉴: **키체인 접근 > 인증서 지원 > 인증 기관에서 인증서 요청...** +3. 다음 정보 입력: + - 사용자 이메일 주소: Apple Developer 계정 이메일 + - 일반 이름: 본인 이름 + - CA 이메일 주소: 비워두기 + - **"디스크에 저장됨"** 선택 + - **"본인이 키 쌍 정보 지정"** 체크 +4. 저장 위치 선택 (예: `~/Desktop/CertificateSigningRequest.certSigningRequest`) +5. 키 크기: **2048 비트**, 알고리즘: **RSA** +6. **계속** 클릭 + +### 1-2. Apple Developer 사이트에서 인증서 발급 + +1. https://developer.apple.com/account/resources/certificates/list 접속 +2. **"+"** 버튼 클릭 +3. **"Developer ID Application"** 선택 (Mac App Store 외부 배포용) +4. **Continue** 클릭 +5. 위에서 생성한 CSR 파일 업로드 +6. **Continue** 클릭 +7. 인증서 다운로드 (`.cer` 파일) +8. 다운로드한 파일을 **더블클릭**하여 키체인에 설치 + +### 1-3. 인증서 확인 + +터미널에서 다음 명령어로 인증서가 설치되었는지 확인: + +```bash +security find-identity -v -p codesigning +``` + +다음과 같은 출력이 나와야 합니다: +``` +1) XXXXXX "Developer ID Application: Your Name (TEAM_ID)" +``` + +## 2. App-Specific Password 생성 + +공증(Notarization)을 위해 App-Specific Password가 필요합니다. + +1. https://appleid.apple.com/account/manage 접속 +2. **로그인** (2단계 인증 필요) +3. **보안** 섹션에서 **앱 암호** 클릭 +4. **"+"** 버튼 클릭 +5. 이름 입력 (예: "aka-browser notarization") +6. 생성된 암호 복사 (예: `abcd-efgh-ijkl-mnop`) +7. **안전한 곳에 저장** (다시 볼 수 없음) + +## 3. Team ID 확인 + +1. https://developer.apple.com/account 접속 +2. **Membership Details** 섹션에서 **Team ID** 확인 (예: `AB12CD34EF`) + +## 4. 환경 변수 설정 + +### 4-1. 방법 1: .env 파일 (권장) + +프로젝트 루트에 `.env.local` 파일 생성: + +```bash +# /Users/hm/Documents/GitHub/aka-browser/apps/browser/.env.local +APPLE_ID=your-apple-id@example.com +APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop +APPLE_TEAM_ID=AB12CD34EF +``` + +**주의**: `.env.local`은 `.gitignore`에 추가하여 Git에 커밋하지 마세요! + +### 4-2. 방법 2: 시스템 환경 변수 + +`~/.zshrc` 또는 `~/.bash_profile`에 추가: + +```bash +export APPLE_ID="your-apple-id@example.com" +export APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" +export APPLE_TEAM_ID="AB12CD34EF" +``` + +저장 후: +```bash +source ~/.zshrc +``` + +### 4-3. 방법 3: 빌드 시 직접 지정 + +```bash +APPLE_ID="your@email.com" \ +APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" \ +APPLE_TEAM_ID="AB12CD34EF" \ +pnpm run package +``` + +## 5. 빌드 및 공증 + +### 5-1. 의존성 설치 + +```bash +cd /Users/hm/Documents/GitHub/aka-browser/apps/browser +pnpm install +``` + +### 5-2. 빌드 스크립트 컴파일 + +```bash +pnpm run build:scripts +``` + +### 5-3. 앱 빌드 및 공증 + +```bash +pnpm run package +``` + +빌드 과정: +1. ✅ 앱 빌드 +2. ✅ EVS 서명 (Widevine CDM) +3. ✅ 코드 서명 (Developer ID Application) +4. ✅ 공증 (Apple 서버에 업로드) +5. ✅ DMG 생성 + +### 5-4. 공증 확인 + +빌드가 완료되면 다음 명령어로 공증 상태 확인: + +```bash +spctl -a -vv -t install release/mac-arm64/aka-browser.app +``` + +성공 시 출력: +``` +release/mac-arm64/aka-browser.app: accepted +source=Notarized Developer ID +``` + +## 6. 문제 해결 + +### 인증서를 찾을 수 없음 + +``` +Error: Cannot find identity matching "Developer ID Application" +``` + +**해결**: +1. 인증서가 키체인에 설치되었는지 확인 +2. 인증서가 만료되지 않았는지 확인 +3. `security find-identity -v -p codesigning` 실행하여 확인 + +### 공증 실패 + +``` +Error: Notarization failed +``` + +**해결**: +1. Apple ID, App-Specific Password, Team ID가 정확한지 확인 +2. 2단계 인증이 활성화되어 있는지 확인 +3. App-Specific Password가 유효한지 확인 (만료되었을 수 있음) + +### 공증 로그 확인 + +```bash +xcrun notarytool log --apple-id "your@email.com" \ + --password "abcd-efgh-ijkl-mnop" \ + --team-id "AB12CD34EF" \ + +``` + +## 7. 배포 + +공증이 완료된 DMG 파일은 `release/` 디렉토리에 생성됩니다: + +- `release/aka-browser-0.1.0-arm64.dmg` (Apple Silicon) +- `release/aka-browser-0.1.0-x64.dmg` (Intel) +- `release/aka-browser-0.1.0-universal.dmg` (Universal) + +이 파일들을 인터넷에 업로드하여 배포할 수 있습니다. 사용자가 다운로드하여 설치할 때 "손상되었다"는 메시지가 나타나지 않습니다. + +## 8. 보안 주의사항 + +- ❌ **절대 Git에 커밋하지 마세요**: + - App-Specific Password + - `.env.local` 파일 + - 인증서 파일 (`.p12`, `.cer`) + +- ✅ **안전하게 보관하세요**: + - 1Password, Bitwarden 등 비밀번호 관리자 사용 + - 팀원과 공유 시 암호화된 채널 사용 + +## 9. CI/CD 설정 (GitHub Actions) + +GitHub Secrets에 다음 변수 추가: + +- `APPLE_ID` +- `APPLE_APP_SPECIFIC_PASSWORD` +- `APPLE_TEAM_ID` +- `CSC_LINK` (인증서 `.p12` 파일을 base64로 인코딩) +- `CSC_KEY_PASSWORD` (인증서 비밀번호) + +자세한 설정은 electron-builder 문서 참고: +https://www.electron.build/code-signing + +--- + +**문의**: 문제가 발생하면 이슈를 생성해주세요. diff --git a/apps/browser/QUICK_START.md b/apps/browser/QUICK_START.md new file mode 100644 index 0000000..3b8749c --- /dev/null +++ b/apps/browser/QUICK_START.md @@ -0,0 +1,106 @@ +# 빠른 시작 가이드 + +## 🚀 지금 바로 시작하기 + +### 1. Developer ID Application 인증서 발급 + +**5분 소요** + +1. https://developer.apple.com/account/resources/certificates/list +2. "+" 버튼 → "Developer ID Application" 선택 +3. CSR 파일 업로드 (아래 방법으로 생성) +4. 다운로드 후 더블클릭하여 설치 + +**CSR 생성 방법:** +``` +키체인 접근 앱 → 메뉴 → 키체인 접근 → 인증서 지원 → 인증 기관에서 인증서 요청... +→ 이메일 입력 → "디스크에 저장됨" 선택 → 저장 +``` + +### 2. App-Specific Password 생성 + +**2분 소요** + +1. https://appleid.apple.com/account/manage +2. 보안 → 앱 암호 → "+" 버튼 +3. 이름 입력 (예: "aka-browser") → 생성 +4. **암호 복사** (다시 볼 수 없음!) + +### 3. Team ID 확인 + +**1분 소요** + +1. https://developer.apple.com/account +2. Membership Details → Team ID 복사 (예: `AB12CD34EF`) + +### 4. 환경 변수 설정 + +프로젝트 루트에 `.env.local` 파일 생성: + +```bash +# /Users/hm/Documents/GitHub/aka-browser/apps/browser/.env.local +APPLE_ID=your-apple-id@example.com +APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop +APPLE_TEAM_ID=AB12CD34EF +``` + +**또는** 터미널에서 직접 실행: + +```bash +export APPLE_ID="your-apple-id@example.com" +export APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" +export APPLE_TEAM_ID="AB12CD34EF" +``` + +### 5. 빌드 및 공증 + +```bash +cd /Users/hm/Documents/GitHub/aka-browser/apps/browser +pnpm run package +``` + +**빌드 과정 (약 5-10분):** +1. ✅ 앱 빌드 +2. ✅ EVS 서명 (Widevine) +3. ✅ 코드 서명 +4. ✅ 공증 (Apple 서버 업로드) +5. ✅ DMG 생성 + +### 6. 완료! + +생성된 파일: `release/aka-browser-0.1.0-arm64.dmg` + +이제 이 파일을 인터넷에 업로드하여 배포할 수 있습니다. +사용자가 다운로드해도 **"손상되었다"는 메시지가 나타나지 않습니다!** ✨ + +--- + +## 🔍 공증 확인 + +```bash +spctl -a -vv -t install release/mac-arm64/aka-browser.app +``` + +성공 시: +``` +accepted +source=Notarized Developer ID +``` + +--- + +## ❓ 문제 해결 + +### 인증서를 찾을 수 없음 +```bash +security find-identity -v -p codesigning +``` +→ "Developer ID Application" 인증서가 있는지 확인 + +### 공증 실패 +- Apple ID, Password, Team ID가 정확한지 확인 +- 2단계 인증이 활성화되어 있는지 확인 + +--- + +**자세한 설명**: `CODESIGN_SETUP.md` 참고 diff --git a/apps/browser/package.json b/apps/browser/package.json index 9ca6384..f0d4470 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -32,6 +32,7 @@ "author": "hmmhmmhm", "license": "MIT", "devDependencies": { + "@electron/notarize": "^2.5.0", "@tailwindcss/vite": "^4.1.14", "@types/node": "^20.11.0", "@types/react": "^19.2.2", @@ -66,6 +67,7 @@ "!node_modules/**/*" ], "afterPack": "scripts/evs-sign.js", + "afterSign": "scripts/notarize.js", "mac": { "target": [ { @@ -78,8 +80,7 @@ "hardenedRuntime": true, "gatekeeperAssess": false, "entitlements": "build/entitlements.mac.plist", - "entitlementsInherit": "build/entitlements.mac.plist", - "identity": null + "entitlementsInherit": "build/entitlements.mac.plist" }, "win": { "target": "nsis", diff --git a/apps/browser/scripts-src/notarize.ts b/apps/browser/scripts-src/notarize.ts new file mode 100644 index 0000000..e899dba --- /dev/null +++ b/apps/browser/scripts-src/notarize.ts @@ -0,0 +1,40 @@ +import { notarize } from '@electron/notarize'; +import * as path from 'path'; + +export default async function notarizing(context: any) { + const { electronPlatformName, appOutDir } = context; + + // macOS만 공증 + if (electronPlatformName !== 'darwin') { + return; + } + + // 환경 변수 확인 + const appleId = process.env.APPLE_ID; + const appleIdPassword = process.env.APPLE_APP_SPECIFIC_PASSWORD; + const teamId = process.env.APPLE_TEAM_ID; + + if (!appleId || !appleIdPassword || !teamId) { + console.warn('⚠️ 공증을 건너뜁니다. 환경 변수를 설정하세요:'); + console.warn(' APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID'); + return; + } + + const appName = context.packager.appInfo.productFilename; + const appPath = path.join(appOutDir, `${appName}.app`); + + console.log(`🔐 공증 시작: ${appPath}`); + + try { + await notarize({ + appPath, + appleId, + appleIdPassword, + teamId, + }); + console.log('✅ 공증 완료!'); + } catch (error) { + console.error('❌ 공증 실패:', error); + throw error; + } +} diff --git a/apps/browser/scripts/notarize.d.ts b/apps/browser/scripts/notarize.d.ts new file mode 100644 index 0000000..c04f366 --- /dev/null +++ b/apps/browser/scripts/notarize.d.ts @@ -0,0 +1 @@ +export default function notarizing(context: any): Promise; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55d8485..a7d5616 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,6 +30,9 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) devDependencies: + '@electron/notarize': + specifier: ^2.5.0 + version: 2.5.0 '@tailwindcss/vite': specifier: ^4.1.14 version: 4.1.14(vite@7.1.11(@types/node@20.19.21)(jiti@2.6.1)(lightningcss@1.30.2)) @@ -2455,7 +2458,7 @@ snapshots: '@babel/parser': 7.28.4 '@babel/template': 7.27.2 '@babel/types': 7.28.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color From 7cf0511b09c4696b6f4c0d1e6bbea94135b4cc48 Mon Sep 17 00:00:00 2001 From: hmmhmmhm Date: Thu, 23 Oct 2025 02:00:42 +0900 Subject: [PATCH 2/3] docs: translate code signing and notarization guide from Korean to English --- apps/browser/CODESIGN_SETUP.md | 176 ++++++++++++++++----------------- apps/browser/CODESIGN_START.md | 106 ++++++++++++++++++++ apps/browser/QUICK_START.md | 106 -------------------- 3 files changed, 194 insertions(+), 194 deletions(-) create mode 100644 apps/browser/CODESIGN_START.md delete mode 100644 apps/browser/QUICK_START.md diff --git a/apps/browser/CODESIGN_SETUP.md b/apps/browser/CODESIGN_SETUP.md index 084fa17..772bf08 100644 --- a/apps/browser/CODESIGN_SETUP.md +++ b/apps/browser/CODESIGN_SETUP.md @@ -1,69 +1,69 @@ -# 코드 서명 및 공증 설정 가이드 +# Code Signing and Notarization Setup Guide -이 문서는 macOS에서 aka-browser를 배포하기 위한 코드 서명 및 공증 설정 방법을 설명합니다. +This document explains how to set up code signing and notarization for distributing aka-browser on macOS. -## 1. Developer ID Application 인증서 생성 +## 1. Create Developer ID Application Certificate -### 1-1. CSR (Certificate Signing Request) 생성 +### 1-1. Generate CSR (Certificate Signing Request) -1. **키체인 접근** 앱 실행 -2. 메뉴: **키체인 접근 > 인증서 지원 > 인증 기관에서 인증서 요청...** -3. 다음 정보 입력: - - 사용자 이메일 주소: Apple Developer 계정 이메일 - - 일반 이름: 본인 이름 - - CA 이메일 주소: 비워두기 - - **"디스크에 저장됨"** 선택 - - **"본인이 키 쌍 정보 지정"** 체크 -4. 저장 위치 선택 (예: `~/Desktop/CertificateSigningRequest.certSigningRequest`) -5. 키 크기: **2048 비트**, 알고리즘: **RSA** -6. **계속** 클릭 +1. Open **Keychain Access** app +2. Menu: **Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority...** +3. Enter the following information: + - User Email Address: Your Apple Developer account email + - Common Name: Your name + - CA Email Address: Leave empty + - Select **"Saved to disk"** + - Check **"Let me specify key pair information"** +4. Choose save location (e.g., `~/Desktop/CertificateSigningRequest.certSigningRequest`) +5. Key Size: **2048 bits**, Algorithm: **RSA** +6. Click **Continue** -### 1-2. Apple Developer 사이트에서 인증서 발급 +### 1-2. Issue Certificate from Apple Developer Website -1. https://developer.apple.com/account/resources/certificates/list 접속 -2. **"+"** 버튼 클릭 -3. **"Developer ID Application"** 선택 (Mac App Store 외부 배포용) -4. **Continue** 클릭 -5. 위에서 생성한 CSR 파일 업로드 -6. **Continue** 클릭 -7. 인증서 다운로드 (`.cer` 파일) -8. 다운로드한 파일을 **더블클릭**하여 키체인에 설치 +1. Visit https://developer.apple.com/account/resources/certificates/list +2. Click **"+"** button +3. Select **"Developer ID Application"** (for distribution outside Mac App Store) +4. Click **Continue** +5. Upload the CSR file created above +6. Click **Continue** +7. Download certificate (`.cer` file) +8. **Double-click** the downloaded file to install it in Keychain -### 1-3. 인증서 확인 +### 1-3. Verify Certificate -터미널에서 다음 명령어로 인증서가 설치되었는지 확인: +Verify the certificate is installed by running this command in Terminal: ```bash security find-identity -v -p codesigning ``` -다음과 같은 출력이 나와야 합니다: +You should see output like: ``` 1) XXXXXX "Developer ID Application: Your Name (TEAM_ID)" ``` -## 2. App-Specific Password 생성 +## 2. Generate App-Specific Password -공증(Notarization)을 위해 App-Specific Password가 필요합니다. +An App-Specific Password is required for notarization. -1. https://appleid.apple.com/account/manage 접속 -2. **로그인** (2단계 인증 필요) -3. **보안** 섹션에서 **앱 암호** 클릭 -4. **"+"** 버튼 클릭 -5. 이름 입력 (예: "aka-browser notarization") -6. 생성된 암호 복사 (예: `abcd-efgh-ijkl-mnop`) -7. **안전한 곳에 저장** (다시 볼 수 없음) +1. Visit https://appleid.apple.com/account/manage +2. **Sign in** (Two-factor authentication required) +3. Click **App-Specific Passwords** in the **Security** section +4. Click **"+"** button +5. Enter a name (e.g., "aka-browser notarization") +6. Copy the generated password (e.g., `abcd-efgh-ijkl-mnop`) +7. **Save it securely** (you won't be able to see it again) -## 3. Team ID 확인 +## 3. Find Your Team ID -1. https://developer.apple.com/account 접속 -2. **Membership Details** 섹션에서 **Team ID** 확인 (예: `AB12CD34EF`) +1. Visit https://developer.apple.com/account +2. Find your **Team ID** in the **Membership Details** section (e.g., `AB12CD34EF`) -## 4. 환경 변수 설정 +## 4. Set Environment Variables -### 4-1. 방법 1: .env 파일 (권장) +### 4-1. Method 1: .env File (Recommended) -프로젝트 루트에 `.env.local` 파일 생성: +Create a `.env.local` file in the project root: ```bash # /Users/hm/Documents/GitHub/aka-browser/apps/browser/.env.local @@ -72,11 +72,11 @@ APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop APPLE_TEAM_ID=AB12CD34EF ``` -**주의**: `.env.local`은 `.gitignore`에 추가하여 Git에 커밋하지 마세요! +**Warning**: Add `.env.local` to `.gitignore` to prevent committing it to Git! -### 4-2. 방법 2: 시스템 환경 변수 +### 4-2. Method 2: System Environment Variables -`~/.zshrc` 또는 `~/.bash_profile`에 추가: +Add to `~/.zshrc` or `~/.bash_profile`: ```bash export APPLE_ID="your-apple-id@example.com" @@ -84,12 +84,12 @@ export APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" export APPLE_TEAM_ID="AB12CD34EF" ``` -저장 후: +After saving: ```bash source ~/.zshrc ``` -### 4-3. 방법 3: 빌드 시 직접 지정 +### 4-3. Method 3: Specify During Build ```bash APPLE_ID="your@email.com" \ @@ -98,73 +98,73 @@ APPLE_TEAM_ID="AB12CD34EF" \ pnpm run package ``` -## 5. 빌드 및 공증 +## 5. Build and Notarize -### 5-1. 의존성 설치 +### 5-1. Install Dependencies ```bash cd /Users/hm/Documents/GitHub/aka-browser/apps/browser pnpm install ``` -### 5-2. 빌드 스크립트 컴파일 +### 5-2. Compile Build Scripts ```bash pnpm run build:scripts ``` -### 5-3. 앱 빌드 및 공증 +### 5-3. Build and Notarize App ```bash pnpm run package ``` -빌드 과정: -1. ✅ 앱 빌드 -2. ✅ EVS 서명 (Widevine CDM) -3. ✅ 코드 서명 (Developer ID Application) -4. ✅ 공증 (Apple 서버에 업로드) -5. ✅ DMG 생성 +Build process: +1. ✅ Build app +2. ✅ EVS signing (Widevine CDM) +3. ✅ Code signing (Developer ID Application) +4. ✅ Notarization (upload to Apple servers) +5. ✅ DMG creation -### 5-4. 공증 확인 +### 5-4. Verify Notarization -빌드가 완료되면 다음 명령어로 공증 상태 확인: +After the build completes, verify notarization status with: ```bash spctl -a -vv -t install release/mac-arm64/aka-browser.app ``` -성공 시 출력: +Successful output: ``` release/mac-arm64/aka-browser.app: accepted source=Notarized Developer ID ``` -## 6. 문제 해결 +## 6. Troubleshooting -### 인증서를 찾을 수 없음 +### Cannot Find Certificate ``` Error: Cannot find identity matching "Developer ID Application" ``` -**해결**: -1. 인증서가 키체인에 설치되었는지 확인 -2. 인증서가 만료되지 않았는지 확인 -3. `security find-identity -v -p codesigning` 실행하여 확인 +**Solution**: +1. Verify the certificate is installed in Keychain +2. Check if the certificate has expired +3. Run `security find-identity -v -p codesigning` to verify -### 공증 실패 +### Notarization Failed ``` Error: Notarization failed ``` -**해결**: -1. Apple ID, App-Specific Password, Team ID가 정확한지 확인 -2. 2단계 인증이 활성화되어 있는지 확인 -3. App-Specific Password가 유효한지 확인 (만료되었을 수 있음) +**Solution**: +1. Verify Apple ID, App-Specific Password, and Team ID are correct +2. Ensure two-factor authentication is enabled +3. Check if App-Specific Password is valid (it may have expired) -### 공증 로그 확인 +### Check Notarization Logs ```bash xcrun notarytool log --apple-id "your@email.com" \ @@ -173,40 +173,40 @@ xcrun notarytool log --apple-id "your@email.com" \ ``` -## 7. 배포 +## 7. Distribution -공증이 완료된 DMG 파일은 `release/` 디렉토리에 생성됩니다: +Notarized DMG files are created in the `release/` directory: - `release/aka-browser-0.1.0-arm64.dmg` (Apple Silicon) - `release/aka-browser-0.1.0-x64.dmg` (Intel) - `release/aka-browser-0.1.0-universal.dmg` (Universal) -이 파일들을 인터넷에 업로드하여 배포할 수 있습니다. 사용자가 다운로드하여 설치할 때 "손상되었다"는 메시지가 나타나지 않습니다. +You can upload these files to the internet for distribution. Users won't see the "damaged" message when downloading and installing. -## 8. 보안 주의사항 +## 8. Security Precautions -- ❌ **절대 Git에 커밋하지 마세요**: +- ❌ **NEVER commit to Git**: - App-Specific Password - - `.env.local` 파일 - - 인증서 파일 (`.p12`, `.cer`) + - `.env.local` file + - Certificate files (`.p12`, `.cer`) -- ✅ **안전하게 보관하세요**: - - 1Password, Bitwarden 등 비밀번호 관리자 사용 - - 팀원과 공유 시 암호화된 채널 사용 +- ✅ **Store securely**: + - Use password managers like 1Password or Bitwarden + - Use encrypted channels when sharing with team members -## 9. CI/CD 설정 (GitHub Actions) +## 9. CI/CD Setup (GitHub Actions) -GitHub Secrets에 다음 변수 추가: +Add the following variables to GitHub Secrets: - `APPLE_ID` - `APPLE_APP_SPECIFIC_PASSWORD` - `APPLE_TEAM_ID` -- `CSC_LINK` (인증서 `.p12` 파일을 base64로 인코딩) -- `CSC_KEY_PASSWORD` (인증서 비밀번호) +- `CSC_LINK` (certificate `.p12` file encoded in base64) +- `CSC_KEY_PASSWORD` (certificate password) -자세한 설정은 electron-builder 문서 참고: +For detailed setup, refer to the electron-builder documentation: https://www.electron.build/code-signing --- -**문의**: 문제가 발생하면 이슈를 생성해주세요. +**Questions**: Please create an issue if you encounter any problems. diff --git a/apps/browser/CODESIGN_START.md b/apps/browser/CODESIGN_START.md new file mode 100644 index 0000000..48eae34 --- /dev/null +++ b/apps/browser/CODESIGN_START.md @@ -0,0 +1,106 @@ +# Quick Start Guide + +## 🚀 Get Started Now + +### 1. Issue Developer ID Application Certificate + +**Takes 5 minutes** + +1. https://developer.apple.com/account/resources/certificates/list +2. Click "+" button → Select "Developer ID Application" +3. Upload CSR file (generate using method below) +4. Download and double-click to install + +**How to generate CSR:** +``` +Keychain Access app → Menu → Keychain Access → Certificate Assistant → Request a Certificate from a Certificate Authority... +→ Enter email → Select "Saved to disk" → Save +``` + +### 2. Generate App-Specific Password + +**Takes 2 minutes** + +1. https://appleid.apple.com/account/manage +2. Security → App-Specific Passwords → "+" button +3. Enter name (e.g., "aka-browser") → Generate +4. **Copy password** (you won't be able to see it again!) + +### 3. Find Your Team ID + +**Takes 1 minute** + +1. https://developer.apple.com/account +2. Membership Details → Copy Team ID (e.g., `AB12CD34EF`) + +### 4. Set Environment Variables + +Create a `.env.local` file in the project root: + +```bash +# /Users/hm/Documents/GitHub/aka-browser/apps/browser/.env.local +APPLE_ID=your-apple-id@example.com +APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop +APPLE_TEAM_ID=AB12CD34EF +``` + +**Or** run directly in terminal: + +```bash +export APPLE_ID="your-apple-id@example.com" +export APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" +export APPLE_TEAM_ID="AB12CD34EF" +``` + +### 5. Build and Notarize + +```bash +cd /Users/hm/Documents/GitHub/aka-browser/apps/browser +pnpm run package +``` + +**Build process (approx. 5-10 minutes):** +1. ✅ Build app +2. ✅ EVS signing (Widevine) +3. ✅ Code signing +4. ✅ Notarization (upload to Apple servers) +5. ✅ DMG creation + +### 6. Done! + +Generated file: `release/aka-browser-0.1.0-arm64.dmg` + +You can now upload this file to the internet for distribution. +Users won't see the **"damaged"** message when downloading! ✨ + +--- + +## 🔍 Verify Notarization + +```bash +spctl -a -vv -t install release/mac-arm64/aka-browser.app +``` + +On success: +``` +accepted +source=Notarized Developer ID +``` + +--- + +## ❓ Troubleshooting + +### Cannot Find Certificate +```bash +security find-identity -v -p codesigning +``` +→ Check if "Developer ID Application" certificate exists + +### Notarization Failed +- Verify Apple ID, Password, and Team ID are correct +- Ensure two-factor authentication is enabled + +--- + +**For detailed instructions**: See `CODESIGN_SETUP.md` diff --git a/apps/browser/QUICK_START.md b/apps/browser/QUICK_START.md deleted file mode 100644 index 3b8749c..0000000 --- a/apps/browser/QUICK_START.md +++ /dev/null @@ -1,106 +0,0 @@ -# 빠른 시작 가이드 - -## 🚀 지금 바로 시작하기 - -### 1. Developer ID Application 인증서 발급 - -**5분 소요** - -1. https://developer.apple.com/account/resources/certificates/list -2. "+" 버튼 → "Developer ID Application" 선택 -3. CSR 파일 업로드 (아래 방법으로 생성) -4. 다운로드 후 더블클릭하여 설치 - -**CSR 생성 방법:** -``` -키체인 접근 앱 → 메뉴 → 키체인 접근 → 인증서 지원 → 인증 기관에서 인증서 요청... -→ 이메일 입력 → "디스크에 저장됨" 선택 → 저장 -``` - -### 2. App-Specific Password 생성 - -**2분 소요** - -1. https://appleid.apple.com/account/manage -2. 보안 → 앱 암호 → "+" 버튼 -3. 이름 입력 (예: "aka-browser") → 생성 -4. **암호 복사** (다시 볼 수 없음!) - -### 3. Team ID 확인 - -**1분 소요** - -1. https://developer.apple.com/account -2. Membership Details → Team ID 복사 (예: `AB12CD34EF`) - -### 4. 환경 변수 설정 - -프로젝트 루트에 `.env.local` 파일 생성: - -```bash -# /Users/hm/Documents/GitHub/aka-browser/apps/browser/.env.local -APPLE_ID=your-apple-id@example.com -APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop -APPLE_TEAM_ID=AB12CD34EF -``` - -**또는** 터미널에서 직접 실행: - -```bash -export APPLE_ID="your-apple-id@example.com" -export APPLE_APP_SPECIFIC_PASSWORD="abcd-efgh-ijkl-mnop" -export APPLE_TEAM_ID="AB12CD34EF" -``` - -### 5. 빌드 및 공증 - -```bash -cd /Users/hm/Documents/GitHub/aka-browser/apps/browser -pnpm run package -``` - -**빌드 과정 (약 5-10분):** -1. ✅ 앱 빌드 -2. ✅ EVS 서명 (Widevine) -3. ✅ 코드 서명 -4. ✅ 공증 (Apple 서버 업로드) -5. ✅ DMG 생성 - -### 6. 완료! - -생성된 파일: `release/aka-browser-0.1.0-arm64.dmg` - -이제 이 파일을 인터넷에 업로드하여 배포할 수 있습니다. -사용자가 다운로드해도 **"손상되었다"는 메시지가 나타나지 않습니다!** ✨ - ---- - -## 🔍 공증 확인 - -```bash -spctl -a -vv -t install release/mac-arm64/aka-browser.app -``` - -성공 시: -``` -accepted -source=Notarized Developer ID -``` - ---- - -## ❓ 문제 해결 - -### 인증서를 찾을 수 없음 -```bash -security find-identity -v -p codesigning -``` -→ "Developer ID Application" 인증서가 있는지 확인 - -### 공증 실패 -- Apple ID, Password, Team ID가 정확한지 확인 -- 2단계 인증이 활성화되어 있는지 확인 - ---- - -**자세한 설명**: `CODESIGN_SETUP.md` 참고 From 144decdc0e83bdebe73ed08e5103f95685607396 Mon Sep 17 00:00:00 2001 From: hmmhmmhm Date: Thu, 23 Oct 2025 02:03:26 +0900 Subject: [PATCH 3/3] feat: add dotenv support for app notarization process --- apps/browser/package.json | 6 +++++- apps/browser/scripts-src/notarize.ts | 18 +++++++++++------- pnpm-lock.yaml | 9 +++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/apps/browser/package.json b/apps/browser/package.json index f0d4470..2179953 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -40,6 +40,7 @@ "@vitejs/plugin-react": "^5.0.4", "concurrently": "^8.2.2", "cross-env": "^10.1.0", + "dotenv": "^17.2.3", "electron": "github:castlabs/electron-releases#v38.0.0+wvcus", "electron-builder": "^26.0.12", "tailwindcss": "^4.1.14", @@ -72,7 +73,10 @@ "target": [ { "target": "dmg", - "arch": ["x64", "arm64"] + "arch": [ + "x64", + "arm64" + ] } ], "category": "public.app-category.developer-tools", diff --git a/apps/browser/scripts-src/notarize.ts b/apps/browser/scripts-src/notarize.ts index e899dba..eaa5fa9 100644 --- a/apps/browser/scripts-src/notarize.ts +++ b/apps/browser/scripts-src/notarize.ts @@ -1,21 +1,25 @@ import { notarize } from '@electron/notarize'; import * as path from 'path'; +import * as dotenv from 'dotenv'; + +// Load .env.local file +dotenv.config({ path: path.join(__dirname, '..', '.env.local') }); export default async function notarizing(context: any) { const { electronPlatformName, appOutDir } = context; - - // macOS만 공증 + + // Only notarize on macOS if (electronPlatformName !== 'darwin') { return; } - // 환경 변수 확인 + // Check environment variables const appleId = process.env.APPLE_ID; const appleIdPassword = process.env.APPLE_APP_SPECIFIC_PASSWORD; const teamId = process.env.APPLE_TEAM_ID; if (!appleId || !appleIdPassword || !teamId) { - console.warn('⚠️ 공증을 건너뜁니다. 환경 변수를 설정하세요:'); + console.warn('⚠️ Skipping notarization. Please set environment variables:'); console.warn(' APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID'); return; } @@ -23,7 +27,7 @@ export default async function notarizing(context: any) { const appName = context.packager.appInfo.productFilename; const appPath = path.join(appOutDir, `${appName}.app`); - console.log(`🔐 공증 시작: ${appPath}`); + console.log(`🔐 Starting notarization: ${appPath}`); try { await notarize({ @@ -32,9 +36,9 @@ export default async function notarizing(context: any) { appleIdPassword, teamId, }); - console.log('✅ 공증 완료!'); + console.log('✅ Notarization completed!'); } catch (error) { - console.error('❌ 공증 실패:', error); + console.error('❌ Notarization failed:', error); throw error; } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7d5616..cb27c4f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ importers: cross-env: specifier: ^10.1.0 version: 10.1.0 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 electron: specifier: github:castlabs/electron-releases#v38.0.0+wvcus version: https://codeload.github.com/castlabs/electron-releases/tar.gz/678b5c7761825c5af936f5c67a9101f3fc6ab750 @@ -1098,6 +1101,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + dotenv@9.0.2: resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} engines: {node: '>=10'} @@ -3516,6 +3523,8 @@ snapshots: dotenv@16.6.1: {} + dotenv@17.2.3: {} + dotenv@9.0.2: {} dunder-proto@1.0.1: