[Fix] #42 - Swift 빌드 검증 및 Swift 6 동시성 오류 수정#43
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Walkthrough패키지 매니페스트에 iOS 16을 추가하고 일부 동시성 어노테이션 및 코드 생성 네이밍을 조정한 뒤, GitHub Actions를 macOS로 전환해 토큰으로 생성된 Swift 파일을 xcodebuild로 검증하도록 CI를 확장합니다. 변경사항Swift 빌드 검증 파이프라인
Sequence Diagram(s)sequenceDiagram
participant Runner
participant StyleDict
participant XcodeBuild
participant Git
Runner->>StyleDict: npm install & build tokens
StyleDict->>Runner: emit Swift files
Runner->>XcodeBuild: xcodebuild MDS scheme (simulator)
XcodeBuild->>Runner: build result
Runner->>Git: commit & create PR if needed
Estimated code review effort 🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
시 🐰
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/style-dictionary.yml (1)
12-12:macos-latest런너 비용 급증 유의
xcodebuild를 위해 macOS 런너는 불가피하지만, GitHub Actions 과금 모델에서 macOS 런너는 Linux 대비 약 10배 비쌉니다. 이 워크플로우가token-sync브랜치 push마다 실행되므로, 비용이 예상보다 빠르게 누적될 수 있습니다.Swift 빌드 검증 스텝만 별도 job으로 분리하고
needs:의존성을 설정하면, npm 빌드/diff 생성/커밋은 저렴한 Linux 런너에서 실행하고, xcodebuild만 macOS에서 실행하는 구조로 비용을 최적화할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/style-dictionary.yml at line 12, The workflow currently uses runs-on: macos-latest for the whole job causing high costs; refactor the job into two jobs: (1) a Linux job to run npm build/diff generation/commit steps (keep the existing steps that produce npm artifacts and commits) and (2) a macOS-only job that runs the Swift/xcodebuild validation step; make the macOS job depend on the Linux job using needs: so the Linux job runs on push to token-sync and only the xcodebuild step runs on macOS (runs-on: macos-latest) while everything else uses runs-on: ubuntu-latest to reduce runner costs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/style-dictionary.yml:
- Around line 103-109: The "Validate Swift build" step can hide xcodebuild
failures because the pipeline uses a pipe to xcpretty without pipefail; update
the "Validate Swift build" step to run its shell with bash and enable pipefail:
set shell to "bash" for the step and prepend the command with "set -o pipefail"
(or use "set -eo pipefail") before running the existing cd MDS && xcodebuild ...
| xcpretty || exit 1 so that any non-zero exit from xcodebuild fails the step;
reference the step name "Validate Swift build" and the existing pipeline command
string to locate where to change.
---
Nitpick comments:
In @.github/workflows/style-dictionary.yml:
- Line 12: The workflow currently uses runs-on: macos-latest for the whole job
causing high costs; refactor the job into two jobs: (1) a Linux job to run npm
build/diff generation/commit steps (keep the existing steps that produce npm
artifacts and commits) and (2) a macOS-only job that runs the Swift/xcodebuild
validation step; make the macOS job depend on the Linux job using needs: so the
Linux job runs on push to token-sync and only the xcodebuild step runs on macOS
(runs-on: macos-latest) while everything else uses runs-on: ubuntu-latest to
reduce runner costs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b0768d0b-6bd1-42cc-b50f-aac5f632efbd
📒 Files selected for processing (2)
.github/workflows/style-dictionary.ymlMDS/Package.swift
<원인> UIFont는 class 타입이라 plain Sendable 선언 시 컴파일 에러가 발생함. <해결> UIFont는 생성 후 불변이므로 동시 접근이 안전하지만, 컴파일러가 이를 정적으로 증명할 수 없어 @unchecked Sendable로 개발자가 직접 보장함을 명시
<원인> isRegistered는 mutable static var로, Swift 6에서 여러 Task가 동시 접근 시 데이터 레이스가 발생할 수 있음. <해결> registerIfNeeded()는 UIKit 컨텍스트(메인 스레드)에서만 호출되므로 @mainactor 격리. 별도 동기화 없이 안전하게 상태를 보호할 수 있음.
<원인> capitalize(toSwiftName(base))는 toSwiftName이 먼저 backtick을 붙여 `default`로 만들어버려 capitalize가 동작하지 않음. <해결> toSwiftName(capitalize(base))로 순서를 바꾸면 default → Default로 대문자화된 뒤 keyword 검사를 하므로 backtick 없이 enum Default가 생성됨. 빌드 에러의 원인이었던 중복 선언 에러가 제거 됨. - 같은 스코프의 static let `default`와 enum Default가 이름이 달라 invalid redeclaration 에러 사라짐.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@MDS/Sources/MDS/Foundation/MDSFont.swift`:
- Line 8: Add a brief documentation comment on the MDSFont struct that justifies
the use of `@unchecked` Sendable by citing the thread-safety basis (e.g., that
stored properties like UIFont and CGFloat are effectively immutable and Apple
documents UIFont as safe to use from multiple threads), mention any invariants
you rely on, and note that you considered `@MainActor` if stronger isolation is
needed; target the comment to appear immediately above the MDSFont declaration
so reviewers can see the rationale for `@unchecked` Sendable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c3089b76-3274-4d9e-94f2-06ab11dde8be
📒 Files selected for processing (3)
MDS/Sources/MDS/Foundation/Base/FontLoader.swiftMDS/Sources/MDS/Foundation/MDSFont.swiftbuild.js
✅ Files skipped from review due to trivial changes (1)
- MDS/Sources/MDS/Foundation/Base/FontLoader.swift
xcodebuild ... | xcpretty 구성에서 bash의 기본 동작은 파이프의 마지막 명령(xcpretty)의 종료 코드만 반환함. xcpretty는 포맷팅 도구라 항상 exit 0을 반환하므로 xcodebuild가 실패해도 || exit 1이 트리거되지 않아 빌드 실패가 CI를 통과하는 문제가 있었음. shell: bash 명시로 GitHub Actions가 -eo pipefail 옵션을 포함해 실행하도록 하고, set -o pipefail을 추가해 파이프 중 하나라도 실패하면 전체 파이프라인 종료 코드가 실패로 처리되도록 수정.
🌴 PR 요약
🌱 작업한 브랜치
🌱 PR Point
1. CI 빌드 검증 수정
AS-IS
ubuntu-latestrunner에서swift build로 빌드 검증swift build는 항상 macOS 호스트를 타겟으로 빌드하기 때문에 UIKit 모듈을 찾지 못해 빌드 자체가 불가능한 상태였음TO-BE
macos-latestrunner에서xcodebuild -destination 'generic/platform=iOS Simulator'로 교체Package.swift에platforms: [.iOS(.v16)]추가하여 iOS 타겟임을 명시2. xcodebuild 빌드 실패가 파이프라인에서 묻히는 문제 수정
AS-IS
xcodebuild ... | xcpretty || exit 1구성에서 bash 기본 동작은 파이프의 마지막 명령(xcpretty)의 종료 코드만 반환|| exit 1이 트리거되지 않아 빌드 실패가 CI를 통과하는 문제TO-BE
shell: bash명시로 GitHub Actions가-eo pipefail옵션을 포함해 실행하도록 변경set -o pipefail추가로 파이프 중 하나라도 실패하면 전체 파이프라인 종료 코드가 실패로 처리됨3. MDSFont —
@unchecked SendableAS-IS
MDSFont가Sendable미준수 상태MDSFont를 격리 도메인 간 전달 시non-'Sendable' type컴파일 에러 발생TO-BE
@unchecked Sendable추가UIFont는 class 타입이라 컴파일러가 자동으로 Sendable을 증명할 수 없음font,lineHeight,letterSpacing)는 생성 후 불변(let)이므로 동시 접근이 안전 — 개발자가 직접 보장@MainActor가 아닌@unchecked Sendable을 선택한 이유MDSFont는UILabel,UIButton같은 UI 컴포넌트가 아니라 폰트 정보를 담는 데이터 타입@MainActor는 "이 타입은 메인 스레드에서만 써야 한다"는 의미인데,MDSFont는 어떤 폰트를 어떻게 쓸지에 대한 명세(spec)에 가까움label.font = ...)의 책임이므로MDSFont자체를 메인 스레드에 귀속시킬 이유가 없음CGSize,UIEdgeInsets처럼 어느 스레드에서든 자유롭게 들고 다닐 수 있는 값으로 설계4. FontLoader —
@MainActorAS-IS
isRegistered가private static var로 선언TO-BE
FontLoader전체에@MainActor추가registerIfNeeded()는 UIKit 초기화 컨텍스트(메인 스레드)에서만 호출되므로@MainActor격리가 의미적으로 적합nonisolated(unsafe)대신@MainActor를 선택한 이유: 실제 호출 시점이 메인 스레드로 보장되므로 불필요한unsafe없이 컴파일러가 안전성을 검증할 수 있음5. build.js — SemanticColor
invalid redeclaration수정AS-IS
capitalize(toSwiftName(base))로 state 그룹 enum 이름 생성toSwiftName이 먼저 실행되어default→`default`(backtick 포함)로 변환한 뒤capitalize가 첫 글자인 backtick을 대문자화하려다 무력화됨static let \default`(프로퍼티)와enum `default`(타입)이 동시 생성 → Swiftinvalid redeclaration` 에러TO-BE
toSwiftName(capitalize(base))로 순서 변경capitalize가 먼저 실행되어default→Default로 변환 후toSwiftName이 keyword 여부를 검사Default는 Swift 예약어가 아니므로 backtick 없이enum Default로 생성 → 프로퍼티`default`와 이름이 달라 충돌 없음📌 참고 사항
📸 스크린샷
해당 없음
📮 관련 이슈