Skip to content

패키징 ​

앱을 남에게 건넬 수 있는 형태로 빌드하는 방법입니다.

배포되는 것 ​

플랫폼산출물아키텍처
Linux.AppImagex64
macOS.dmgarm64, x64
Windows.exe (NSIS 설치 프로그램)x64

산출물의 이름은 snowpea-ide-<version>-<os>-<arch>.<ext> 형식이며 dist-electron/에 놓입니다. 아직 자동 업데이트 채널은 없고, 릴리스는 태그에 붙는 에셋으로 배포됩니다.

번들된 core ​

패키징된 앱은 자체 core를 품고 있어, 설치한 사람이 다른 것을 따로 설치할 필요가 없습니다. 이 core는 PyInstaller의 onedir 트리이며 — onefile 번들은 절대 아닙니다 — 공개 core 저장소에서 빌드해 앱 리소스의 resources/core/로 복사합니다.

패키징하려는 대상 플랫폼의 트리는 패키징 전에 반드시 있어야 합니다. 없으면 core 없이 설치 프로그램이 만들어지고, 앱은 컴퓨터에서 찾을 수 있는 아무 snowpea-core로 물러납니다:

bash
scripts/build-core.sh              # linux-x64, darwin-arm64, darwin-x64
pwsh -File scripts/build-core.ps1  # win-x64

PyInstaller는 크로스 컴파일을 할 수 없으므로, 각 플랫폼의 core는 그 플랫폼에서 빌드해야 합니다. 릴리스 파이프라인에 플랫폼마다 잡이 하나씩 있는 것도 정확히 이 때문입니다.

빌드 ​

bash
npm run dist          # every target this machine can produce
npm run dist:linux    # AppImage
npm run dist:mac      # dmg
npm run dist:win      # NSIS installer
npm run dist:dir      # unpacked tree, no installer — useful for testing

npm run dist는 프로덕션 빌드를 먼저 실행하므로, 언제나 out/에 마지막으로 남아 있던 것이 아니라 src/에 있는 것을 패키징합니다.

아이콘 ​

앱 아이콘은 손으로 그리지 않고 생성합니다.

bash
npm run icons

이 명령은 이 저장소에서 브랜드 마크를 담고 있는 유일한 파일이자 앱이 자체 워드마크로 인라인하는 바로 그 파일인 src/renderer/ui/mark.svg를 읽어 build/icon.svg, build/icon.png(1024²), build/icon-512.png을 씁니다. 마크를 고쳤으면 이 명령을 다시 돌리고 결과물을 커밋하세요. 창 안의 마크와 독 타일이 어긋나지 않게 하는 장치는 이것뿐입니다.

저장소에 .icns와 .ico는 없고 생성하지도 않습니다. 512² 이상의 icon.png 하나만 있으면 electron-builder가 패키징하면서 둘 다 만들어 냅니다.

앱 안에서 마크는 단색이며 테마의 강조색을 따라가므로 여덟 가지 테마 모두에서 어울립니다. 브랜드 그러데이션은 아이콘 타일에만 들어갑니다. 오직 그 자리만이 마크가 혼자 놓이는 자리이기 때문입니다.

앱이 core를 찾는 방법 ​

순서대로 확인하며, 먼저 걸리는 것이 이깁니다.

  1. SNOWPEA_CORE_BIN. 실행 파일을 가리키는 경우
  2. resources/core/ 아래의 번들된 트리
  3. PATH 상의 snowpea-core
  4. uv run --project $SNOWPEA_REPO snowpea-core. 개발자용 대체 경로

모든 갈래가 비어 있으면 앱은 spawn 오류로 실패하는 대신 설치 명령이 담긴 core 없음 화면을 보여줍니다.

개발 중에는 2번과 3번의 순서가 바뀝니다. !app.isPackaged이거나, 패키징된 빌드라도 SNOWPEA_REPO가 명시적으로 설정돼 있으면 "개발 중"으로 간주해 PATH/uv를 번들보다 먼저 시도합니다. 개발 트리의 resources/core/는 개발자가 실제로 실행하려는 core라기보다는 이전 scripts/build-core.sh 실행이나 electron-builder의 extraResources 복사가 남긴 낡은 산출물인 경우가 훨씬 많기 때문에, 더 이상 기본으로 이기지 않습니다. SNOWPEA_CORE_BIN은 여전히 무조건 1순위이고, SNOWPEA_PREFER_BUNDLED=1을 설정하면 개발 트리에서도 번들 자체를 테스트할 수 있도록 패키징된 순서로 되돌아갑니다.

낡은 번들은 건너뛸 뿐, 실행하지 않습니다. 번들된 트리가 2순위 자리를 차지하기 전에 CoreManager는 실행 파일 옆의 resources/core/<platform>/snowpea-core-info.json을 읽어, 다음 중 하나라도 해당하면 그 번들을 거부하고 이유를 메인 프로세스 콘솔에 로그로 남깁니다.

  • protocolVersion의 major/minor가 이 IDE 빌드가 대상으로 삼은 프로토콜 (@snowpea/sdk의 PROTOCOL_VERSION)보다 낮은 경우
  • gitRef가 scripts/build-core.sh에 박아 둔 기본 REF=보다 오래된 태그를 가리키는 경우 (이 검사는 resources/ 옆에 스크립트가 있는 개발 트리에서만 이루어집니다 — 패키징된 앱에는 비교할 스크립트가 없습니다)

snowpea-core-info.json이 아예 없는 트리 — 이 검사가 생기기 전에 만들어진 오래된 번들 — 는 거부하지 않고 신뢰합니다. 낡은 번들이 유일한 후보였다면, 해결은 그 core를 그대로 실행하는 대신 core 없음 화면을 보여주는 실패로 끝납니다.

프로토콜 major는 IDE와 같지만 minor가 뒤처진 core는 거부되지 않습니다. start()는 일단 연결하고 상태에 protocolOutdated만 표시해서, "core가 이 앱보다 오래됐습니다: 일부 화면은 동작하지 않습니다 — core를 업데이트하세요" 라는 배너를 띄운 채 나머지 앱은 계속 동작하게 둡니다. major가 다를 때만 앱을 막고, 전체 화면을 덮는 호환 불가 core 화면을 보여줍니다.

틀리기 쉬운 두 가지 ​

node-pty는 언팩된 상태로 두어야 합니다. 미리 빌드된 네이티브 모듈이 있고, 이는 asar 아카이브 안이 아니라 실제 파일 시스템에 있어야 합니다. 이 모듈이 로드되지 않으면 터미널은 파이프 기반 셸로 물러납니다.

웹소켓 라이브러리는 번들에 넣으면 안 됩니다. ws는 프로덕션 의존성으로 두고 메인 번들 바깥에 남겨야 합니다. 번들에 말아 넣으면 core를 띄우고 헬스 체크까지 통과한 뒤 연결 단계에서 영원히 멈추는 앱이 만들어집니다. 오류 메시지가 전혀 없는 종류의 실패입니다.

macOS 서명 ​

번들된 core는 서명되지 않은 서드파티 바이너리 트리이고, hardened runtime에서 이를 실행하려면 entitlements가 필요합니다. 서명과 공증은 v0.2의 범위가 아니므로, 여기서 빌드한 .dmg는 다른 사람의 Mac에서 손으로 격리를 해제하기 전까지 격리된 상태로 남습니다.

MIT licensed. The manual is generated from the product repositories — see the banner on each page.