C.W.K.
Stream
Lesson 04 of 05 · published

doctor: 설치된 아티팩트를 검증해

~12 min · self-contained, verification, codesign, deployment

Level 0릴 입문자
0 XP0/39 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"소스, 번들, 설치된 버전은 install/doctor 스크립트가 명시적으로 비교해야 해. 성공한 swift build 는 배포 증명이 아냐."

/Applications 에 실제로 뭐가 있어?

빌드했고, closure 를 번들했고, 서명했고, 인스톨러를 돌렸어. 이제 앱이 /Applications 에 앉아 있어. 불편한 질문이 여기 있어: 설치된 게 실제로 네가 생각하는 거야? 인스톨러가 옛 빌드를 복사했을 수도. 서명이 안 먹었을 수도. dylib 이 아직 Homebrew 를 가리킬 수도. 지난주 버전을 보고 있을 수도. 믿음은 검증이 아니고, '설치했어' 와 '설치된 게 맞아' 사이의 틈이 딱 배포 버그가 숨는 데야.

Ashen Reel 은 그 틈을 doctor 로 닫아: 유일한 일이 실제 설치된 번들을 심문하고 그게 진짜인지 증명하는 스크립트. 빌드 출력이 아니라 — 사용자가 실행하는 디스크 위의 그것.

doctor 가 증명하는 것

doctor 는 컴파일이 못 하는 주장들을 검사해: 앱 그리고 모든 중첩 Mach-O 바이너리에 걸친 안정된 code signature; Homebrew 런타임 링크가 없는 완전한 내부 의존성 closure; 번들된 커스텀 아이콘; 그리고 소스 빌드와 설치된 릴리스의 명확한 구분. 각 검사가 바람을 출력에서 읽을 수 있는 사실로 바꿔.

빌드 출력이 아니라 설치된 아티팩트를 검증해. 사용자가 실행하는 유일한 건 디스크 위 번들이야. 네 검증을 그것에 겨눠 — 서명, 의존성, 버전 — 소스와 설치 사이의 모든 단계가 뭔가 조용히 잘못될 수 있는 곳이니까.

doctor 는 검사 몇 개고, 각각 가정을 통과나 시끄러운 실패로 바꿔:

소스-대-설치 드리프트를 보이게 만들어. install 이랑 doctor 스크립트는 소스 빌드, 번들된 릴리스, 설치된 앱을 명시적으로 비교해서, 불일치가 조용하지 않고 보이게. /Applications 의 버전이 네가 방금 빌드한 거랑 안 맞을 때, 넌 스크립트가 알려주길 원하지 — 네가 이미 고친 버그를 리포트하는 헷갈린 사용자 말고.

doctor 가 '완료'의 진짜 정의야

Track 6 은 'swift build 는 배포 증명이 아냐' 로 열었어. doctor 가 배포 증명이 실제로 어떻게 생겼는지야. 초록 빌드는 코드가 의향이 있다고 말하고; 초록 doctor 는 진짜 타겟의 설치된 아티팩트가 서명됐고, 자립했고, 네가 내려던 버전이라고 말해. Ashen Reel 한텐 '완료' 는 빌드가 통과할 때가 아냐 — 실제 Office Mac 의 /Applications 번들에 대해 doctor 가 통과할 때야. 그게 소프트웨어를 컴파일하는 거랑 배포하는 거의 경계야.

Code

doctor 는 빌드가 아니라 설치된 번들을 심문해·bash
APP="/Applications/Ashen Reel.app"
fail() { echo "doctor: FAIL -- $1"; exit 1; }

# 1. Signed, with a stable identity across the app AND every nested Mach-O.
codesign --verify --deep --strict "$APP" || fail "signature invalid or incomplete"

# 2. Self-contained: NO runtime dependency resolves to Homebrew.
if otool -L "$APP/Contents/MacOS/AshenReel" | grep -q '/opt/homebrew'; then
  fail "installed app still links Homebrew -- not self-contained"
fi

# 3. Installed != a stray dev build: the version must match the release source.
installed=$(defaults read "$APP/Contents/Info" CFBundleShortVersionString)
product=$(jq -r .version cwk-product.json)
[ "$installed" = "$product" ] || fail "installed $installed != product $product"

echo "doctor: PASS -- installed artifact is signed, self-contained, and v$installed"

External links

Exercise

네가 배포하는 뭔가에 doctor 를 짜. '배포된' 아티팩트(네 소스나 빌드 말고)를 검사하고 최소 세 가지를 단언해야 해: 네가 의도한 정확한 버전/신원, dev 전용 의존성이 새어들지 않음, 그리고 무결성 속성 하나(서명, 체크섬, 필수 파일 존재). 진짜 배포에 대해 돌려. 모든 단언이 통과했어 — 그리고 하나가 조용히 안 통과했으면 알았을까?
Hint
doctor 규칙: 사용자가 실제로 실행하는 걸 검사하고, 빌드 단계가 못 하는 속성을 확인해. 버전 매치가 '엉뚱한 빌드 설치' 를 잡아. dev-의존성 grep 이 '자립 아님' 을 잡아. 서명/해시가 '변조되거나 불완전' 을 잡아. 매번 마지막에 돌리면, '완료' 가 마침내 확인 가능한 뭔가를 뜻해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.