원격 Mac에서 macOS DMG 제작과 드래그 설치 검증하기

CI/CD ·약 8분 읽기

원격 Mac에서 macOS DMG 제작과 드래그 설치 검증하기

빌드 머신에서 Example.app을 만들었고 배포 작업에서 DMG도 생성했습니다. 하지만 전달하기 전에는 세 가지를 확인해야 합니다. 디스크 이미지를 마운트했을 때 앱과 ‘응용 프로그램’ 바로 가기가 제대로 들어 있는지, 복사한 앱의 서명이 유효한지, 사용자가 그래픽 인터페이스에서 드래그해 설치할 수 있는지입니다. 아래에서는 이 세 가지를 반복 가능한 검사로 나눕니다. 예시의 Example.app은 실제 산출물 이름으로 바꾸세요.

패키징 범위부터 확정하기

입력은 반드시 최종 버전의 앱 번들이어야 합니다. 먼저 빌드 작업에서 산출물 경로를 고정하고 앱 실행 파일이 있는지 확인한 다음, 예정된 서명 절차를 마치세요. ‘DMG 만들기’를 앱 내용을 손보는 기회로 삼지 마세요. 리소스, 실행 파일 또는 내장 구성 요소를 수정하면 기존 서명이 무효화될 수 있습니다.

디렉터리를 확인할 때는 같은 이름의 파일이 있는지만 보지 말고 test -d를 사용하세요. 출력 경로에 이전 DMG가 없는지도 확인해야 합니다. 지난 배포 산출물을 조용히 덮어쓰는 것보다 작업이 명시적으로 실패하는 편이 원인을 추적하기 쉽습니다. 파이프라인이 작업을 재시도한다면 패키징 스크립트가 알 수 없는 파일을 삭제하게 하지 말고, 파이프라인이 자신의 출력 디렉터리를 먼저 정리하도록 하세요.

디스크 이미지의 무결성, 앱 서명의 유효성, 앱에 대한 시스템의 신뢰는 서로 다른 결론입니다. 어느 하나를 통과했다고 나머지도 통과한 것은 아닙니다.

설치 바로 가기가 있는 디스크 이미지 만들기

다음 스크립트는 임시 디렉터리에서 볼륨 내용을 구성합니다. 서명된 앱을 복사하고 /Applications를 가리키는 심볼릭 링크를 만듭니다. 앱 번들은 ditto로 복사하며, 복사한 뒤에는 번들 내부 파일을 편집하지 마세요.

#!/bin/bash
set -euo pipefail

APP="$PWD/build/Release/Example.app"
OUT="$PWD/dist/Example.dmg"

test -d "$APP"
test -f "$APP/Contents/MacOS/Example"
mkdir -p "$(dirname "$OUT")"
test ! -e "$OUT"

work="$(mktemp -d "${TMPDIR:-/tmp}/dmg-build.XXXXXX")"
trap 'rm -rf "$work"' EXIT

stage="$work/stage"
mkdir -p "$stage"
ditto "$APP" "$stage/Example.app"
ln -s /Applications "$stage/Applications"

hdiutil create -volname "Example" \
  -srcfolder "$stage" -fs HFS+ -format UDZO "$OUT"

앱 실행 파일의 이름이 Example이 아니라면 검사 경로도 함께 바꾸세요. 볼륨 이름은 사용자가 마운트 후 보는 이름일 뿐, 앱 설치 경로를 결정하지는 않습니다. 임시 구성 디렉터리와 최종 출력 디렉터리를 분리하면 종료 시 정리하기 쉽고, 이전 디스크 이미지가 새 이미지에 실수로 포함되는 것도 막을 수 있습니다.

볼륨에 넣지 말아야 할 파일

먼저 디렉터리 목록을 확인해 구성 영역에 앱 번들과 설치 바로 가기만 있는지 확인하세요. 빌드 로그, 서명 자료, 디버그 파일, 프로젝트 저장소는 DMG에 포함해 전달하면 안 됩니다. 스크립트에서 stage는 유일한 입력 디렉터리입니다. 나중에 안내 파일을 추가하더라도 명시적으로 넣고 확인해야 하며, 작업 공간 전체를 대상으로 hdiutil create를 실행해서는 안 됩니다.

다시 마운트해 실제 전달 내용 확인하기

원본 디렉터리만 확인하지 말고 방금 만든 DMG를 여세요. hdiutil verify로 디스크 이미지를 검사한 다음 읽기 전용으로 마운트해 볼륨 안의 경로를 확인합니다. 이어서 앱을 별도 디렉터리로 복사하고 서명을 검증합니다.

#!/bin/bash
set -euo pipefail

OUT="$PWD/dist/Example.dmg"
work="$(mktemp -d "${TMPDIR:-/tmp}/dmg-check.XXXXXX")"
mountpoint="$work/mount"
attached=0

cleanup() {
  if [ "$attached" -eq 1 ]; then
    hdiutil detach "$mountpoint" >/dev/null || true
  fi
  rm -rf "$work"
}
trap cleanup EXIT

mkdir -p "$mountpoint" "$work/installed"
hdiutil verify "$OUT"
hdiutil attach -readonly -nobrowse \
  -mountpoint "$mountpoint" "$OUT" >/dev/null
attached=1

test -d "$mountpoint/Example.app"
test -L "$mountpoint/Applications"
test "$(readlink "$mountpoint/Applications")" = /Applications

ditto "$mountpoint/Example.app" "$work/installed/Example.app"
codesign --verify --deep --strict \
  "$work/installed/Example.app"

검사에 실패하면 스크립트가 0이 아닌 종료 상태를 반환하므로 배포 작업에 연결하기 좋습니다. 마운트 해제에 실패했다면 해당 볼륨을 사용 중인 프로세스가 있는지 직접 확인하세요. 강제 마운트 해제로 점유 상태를 감추지 마세요. codesign --verify는 복사한 번들이 여전히 서명 요건을 충족하는지 검사하지만, 시스템이 해당 앱을 신뢰한다는 뜻은 아닙니다. 외부 배포용 서명과 공증 절차를 사용한다면, 그 절차에 따라 시스템 평가 결과도 별도로 검증해야 합니다.

그래픽 세션에서 사용자 설치 과정 확인하기

명령줄에서는 경로와 서명을 검사할 수 있지만, 아이콘 배치가 명확한지, 드래그할 대상이 보이는지, 첫 실행에 문제가 없는지는 확인할 수 없습니다. 로그인된 macOS 그래픽 세션에서 DMG를 열고 일반 사용자와 같은 순서로 진행하세요.

  1. 볼륨에 예상한 앱과 ‘응용 프로그램’ 바로 가기만 있는지, 이름이 잘리거나 혼동을 주지 않는지 확인합니다.
  2. 앱을 ‘응용 프로그램’으로 드래그하고 복사가 완료되는지 확인합니다. 읽기 전용 볼륨에서 바로 실행하는 것으로 설치 테스트를 대신하지 마세요.
  3. 복사한 앱을 실행해 첫 화면과 필요한 파일 접근 과정을 확인합니다.
  4. 볼륨을 마운트 해제한 뒤 설치된 앱을 다시 실행해, 앱이 여전히 볼륨 내부 리소스에 의존하지 않는지 확인합니다.

검사를 시작하기 전에 테스트 위치에 같은 이름의 이전 앱이 없는지 확인하세요. 그렇지 않으면 지난번에 설치한 버전을 열 수 있습니다. 테스트용 복사본을 정리할 때도 경로를 확인해 평소 사용하는 앱을 실수로 삭제하지 않도록 하세요. 그래픽 세션을 사용할 수 없다면 배포 상태를 ‘명령줄 검사 통과, 그래픽 검수 미완료’로 표시하고 두 결과를 하나의 성공으로 합치지 마세요.

실패한 단계를 정확히 찾아내기

hdiutil verify가 실패하면 원본 DMG와 생성 로그를 보관하고, 쓰기가 끝나기 전에 산출물이 업로드되거나 읽혔는지 확인하세요. 볼륨에 파일이 빠졌다면 구성 디렉터리와 ditto의 입력 경로로 돌아가 점검하세요. 서명 검증이 실패했다면 서명 완료 후에도 스크립트가 앱 번들을 수정했는지 확인하고 최종 앱으로 디스크 이미지를 다시 만드세요. 기존 DMG를 반복해서 부분 수정하면 전달한 산출물의 이력을 추적하기 어려워집니다.

명령줄 검사는 모두 통과하지만 드래그 후 앱이 실행되지 않는다면 실제 실행 경로, 앱 서명, 외부 배포에 필요한 시스템 신뢰 검사를 먼저 확인하세요. 마지막으로 앱 빌드 식별자, DMG 파일 체크섬, 자동 검사 결과, 그래픽 검수 결론을 기록하세요. 그래야 다음 배포에서 문제가 빌드, 패키징, 설치 중 어디에서 발생했는지 판단할 수 있습니다.

자주 묻는 질문

hdiutil verify가 성공하면 앱 실행도 보장되나요?

아니요. 이미지 무결성만 확인하므로 앱 서명과 복사 후 실행은 별도로 검사해야 합니다.

패키징 전에 앱 서명을 끝내야 하나요?

그렇습니다. 앱을 최종 상태로 서명하고 검증한 다음 DMG를 만들며, 앱을 변경했다면 다시 패키징해야 합니다.

클라우드 Mac을 단독으로 사용하고 싶으신가요?

모델, 리전, 과금 기간을 선택하세요. 전용 물리 머신을 제공하며, 실제 사용 가능 여부는 콘솔에서 실시간으로 확인할 수 있습니다.

구성 확인 및 주문