Initial commit: EG-BIM installer plans and design concepts
This commit is contained in:
commit
54f0cfe360
25 files changed
+4251
No files matched your search
@@ -0,0 +1,77 @@
|
||||
# Rust + Tauri 구조와 모듈
|
||||
|
||||
## 실행 구조
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
UI[Tauri 웹 UI] --> IPC[타입이 지정된 Tauri Command]
|
||||
IPC --> APP[Rust 작업 서비스]
|
||||
CLI[CI용 CLI] --> APP
|
||||
APP --> DOMAIN[프로젝트 검증 · 파일 해석 · 버전/패치 정책]
|
||||
APP --> ADAPTER[도구와 저장소 어댑터]
|
||||
ADAPTER --> WIX[WiX · Burn]
|
||||
ADAPTER --> SIGN[SignTool · 서명 공급자]
|
||||
ADAPTER --> STORE[작업 디렉터리 · 불변 릴리스 저장소]
|
||||
APP --> REPORT[진행 이벤트 · 검증 보고서]
|
||||
```
|
||||
|
||||
화면은 설정 편집과 결과 표시만 담당한다. 파일 수집, GUID 할당, 패치 판정, 외부 프로세스 실행, 서명, 최종 상태 변경은 모두 Rust에서 처리한다. CLI도 같은 서비스를 호출하므로 화면 없이 CI에서 동일한 검증을 수행한다.
|
||||
|
||||
## 제안 저장소 구조
|
||||
|
||||
```text
|
||||
Cargo.toml # Cargo workspace
|
||||
Cargo.lock
|
||||
rust-toolchain.toml
|
||||
apps/
|
||||
desktop/
|
||||
src/ # TypeScript + React 화면
|
||||
src-tauri/ # Tauri Command, 이벤트, capabilities
|
||||
cli/ # package-builder 명령
|
||||
crates/
|
||||
package-domain/ # 타입과 순수 검증/비교 규칙
|
||||
package-engine/ # 작업 흐름, 취소, 상태, 포트 정의
|
||||
package-infra/ # 파일 I/O, WiX, 서명, Windows 프로세스
|
||||
templates/wix/ # 버전 관리되는 설치 정의 템플릿
|
||||
schemas/ # 프로젝트/매니페스트/IPC JSON Schema
|
||||
tests/fixtures/ # 작은 가상 제품과 기준 MSI 정의
|
||||
docs/
|
||||
```
|
||||
|
||||
의존 방향은 UI/CLI → engine → domain이다. infra는 engine이 정의한 포트를 구현하고 실행 시작점에서 주입한다. domain은 Tauri·네트워크·프로세스에 의존하지 않는다. Rust 공통 의존성은 workspace에서 관리하고 `Cargo.lock`을 저장한다. [Cargo workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html)
|
||||
|
||||
## 핵심 서비스와 포트
|
||||
|
||||
| 구성 | 책임 |
|
||||
| --- | --- |
|
||||
| ProjectService | 열기·저장·스키마 마이그레이션·편집 revision 관리 |
|
||||
| ManifestResolver | 파일 규칙을 정렬된 실제 파일 목록으로 확장 |
|
||||
| IdentityPlanner | 기존 identity lock을 기준으로 컴포넌트와 제품 식별자 계획 |
|
||||
| ReleasePlanner / PatchPlanner | 실행 전 검사, 차이 보고, 출력과 적용 경로 확정 |
|
||||
| InstallFlowCompiler | 단계 의존성과 설치 모드 검증, MSI/Burn 실행 정의로 변환 |
|
||||
| InstallerUiCompiler | UI 템플릿·리소스·바인딩 검증, 백엔드 기능 지원 검사 |
|
||||
| BuildCoordinator | 작업 잠금, 단계 실행, 체크포인트, 취소, 실패 기록 |
|
||||
| WixBackend | 설치 정의 생성, MSI/MSP/Burn 빌드, 결과 메타데이터 추출 |
|
||||
| Signer | 서명 정책 적용, 타임스탬프, 실제 서명 검증 결과 반환 |
|
||||
| ArtifactRepository | 기준 릴리스 조회, 콘텐츠 검증, 불변 결과 등록 |
|
||||
| ProcessRunner | 허용 도구 실행, 로그 스트리밍, 시간 제한, 자식 종료 |
|
||||
|
||||
포트는 외부 도구를 가짜 구현으로 바꿀 수 있게 한다. 실제 Rust trait의 비동기 형태는 구현 시 확정하되, 모든 작업은 `BuildContext`, 취소 토큰, 타입이 지정된 요청과 결과를 받는다. 도구 종료 코드만 성공 기준으로 삼지 않는다.
|
||||
|
||||
후보 라이브러리는 `serde/serde_json`, `uuid`, `sha2`, `quick-xml`, `tokio`, `clap`, `tracing`이다. 도입 시 유지보수 상태·라이선스·Windows 지원을 확인하고 버전을 고정한다. WiX CLI와 확장, Windows SDK SignTool도 정확한 버전·파일 해시를 `toolchain.lock.json`에 기록한다. WiX 세대가 다른 명령 구문을 혼용하지 않는다.
|
||||
|
||||
## 작업 수명과 장애 복구
|
||||
|
||||
생성 작업은 UI 스레드 밖에서 실행한다. 최초 버전은 한 프로세스에서 빌드 한 건씩 수행하며, CLI와 GUI 간에도 프로젝트/출력 저장소에 OS 파일 잠금을 사용한다. 프로젝트 편집은 가능하지만 실행 중인 작업은 시작 시점 스냅샷을 사용한다.
|
||||
|
||||
작업 기록은 `job.json`, 단계별 구조화 로그와 체크포인트 파일로 저장한다. 임시 파일 작성 후 동일 볼륨 내 교체로 저장하며 프로세스 종료 후 다시 읽어 마지막 단계를 복원한다. 기존 작업을 무조건 이어서 실행하지 않고 입력·도구·서명 완료 파일의 해시를 재검사한다. 확정 결과를 변경하는 재개는 금지한다.
|
||||
|
||||
GUI 종료 시 실행 중 작업을 안내하고 취소를 요청할 수 있다. 프로세스 중단 후의 작업은 `Interrupted`로 복구한다. 최초 버전은 GUI를 닫아도 계속 도는 서비스가 아니다. 무인 장시간 실행은 CLI를 사용한다.
|
||||
|
||||
## 권한 경계
|
||||
|
||||
생성기는 일반 사용자 권한으로 동작한다. 대상 HKLM 레지스트리를 편집하는 것은 생성된 설치기의 역할이다. 빌드 중 사용자 PC에 MSI/MSP를 설치하지 않는다.
|
||||
|
||||
웹 UI에는 임의 셸 실행·임의 파일 쓰기 API를 노출하지 않는다. Rust가 허용한 프로젝트와 소스 루트 안에서 요청을 검증한다. 외부 도구는 절대 경로와 인자 배열로 실행하며 `.bat`, `cmd /c`, PowerShell 문자열 조합을 허용하지 않는다. Windows Job Object로 자식 프로세스 수명을 관리하고 실패·취소 시 남은 프로세스를 정리한다. [Rust Command](https://doc.rust-lang.org/std/process/struct.Command.html)
|
||||
|
||||
Tauri의 로컬 번들 UI만 사용하고 원격 페이지에 IPC 권한을 주지 않는다. 사용자 입력·로그는 HTML로 렌더링하지 않으며 CSP와 capabilities를 제한한다. 사용자 정의 Command는 등록만 하면 기본적으로 모든 앱 창에서 호출할 수 있으므로 `AppManifest::commands`와 명시적 권한을 함께 구성한다. capability가 Rust 내부의 경로 검증을 대신하지 않는다. [Tauri capabilities](https://v2.tauri.app/security/capabilities/)
|
||||
@@ -0,0 +1,58 @@
|
||||
# 프로젝트와 데이터 모델
|
||||
|
||||
## 설정과 결과를 분리하는 파일 구조
|
||||
|
||||
```text
|
||||
project/
|
||||
package-project.json # 사람이 편집하는 제품/패키지 설정
|
||||
package-project.local.json # PC별 소스 경로, 도구/서명 프로필 참조
|
||||
identity.lock.json # 제품 계열 및 컴포넌트 식별자 이력
|
||||
toolchain.lock.json # 승인한 도구/템플릿 버전
|
||||
.work/jobs/<jobId>/ # 스냅샷, 스테이징, 생성 WXS, 로그
|
||||
releases/<releaseId>/
|
||||
release.json # 확정된 메타데이터
|
||||
input.snapshot.json # 설정과 도구, 소스 정보
|
||||
files.resolved.json # 실제 파일 목록, 원본/서명 후 해시
|
||||
identity.snapshot.json
|
||||
artifacts/ # 배포 가능한 파일
|
||||
baseline/ # MSI, wixpdb, signed payload, 설치 정의
|
||||
reports/ # 정적 검사와 빌드 당시 검증
|
||||
patches/<patchId>/ # 기준→목표 패치와 동일 종류의 기록
|
||||
attestations/<artifactDigest>/ # 이후 VM 시험 결과; 아티팩트는 수정 안 함
|
||||
```
|
||||
|
||||
프로젝트·identity lock·toolchain lock은 형상 관리한다. local 파일, 자격 증명, 대용량 릴리스와 작업 폴더는 제외한다. 릴리스 저장소는 백업 가능한 별도 위치를 지정할 수 있다. 인증서 개인 키나 토큰은 어떤 JSON에도 넣지 않고 OS/CI 자격 증명 저장소의 참조만 사용한다.
|
||||
|
||||
## 주요 데이터
|
||||
|
||||
| 타입 | 핵심 필드와 규칙 |
|
||||
| --- | --- |
|
||||
| PackageProject | schemaVersion, projectId, product, sources, files, registry, outputs, prerequisites, signing, patchPolicy, installationFlow, installerUi |
|
||||
| InstallationFlow / InstallerUi | 단계 의존성·모드·조건, 테마/페이지/바인딩. [상세 계약](09-install-flow-and-ui.md) 참조 |
|
||||
| ProductSpec | productId, displayName, manufacturer, architecture, language, installScope, version, engineVersion, upgradeCode, installRoot |
|
||||
| FileRule | 고유 id, source alias, include/exclude 패턴, destinationDirectory, required |
|
||||
| ResolvedFile | source-relative path, target-relative path, 크기, SHA-256, PE 정보, componentId/Guid, signingPolicy |
|
||||
| RegistryEntry | id, hive, view, key, name, typed value, component, 설치/제거 정책 |
|
||||
| IdentityLock | 제품 계열, ProductCode, 컴포넌트 GUID/키 경로, 삭제된 식별자 tombstone |
|
||||
| ReleaseRecord | releaseId, buildId, 설정 해시, 소스 커밋(선택), 실제 MSI/Burn 식별자, artifacts, 호환성, 서명/도구 정보 |
|
||||
| PatchRecord | patchId/PatchCode, 기준 상태, 목표 releaseId, family/sequence, 필요한 원본·패치, 전체 대체 경로 |
|
||||
| Artifact | artifactId, kind, 상대 경로, u64 크기, 최종 SHA-256, dependsOn, 서명 결과 |
|
||||
| ValidationReport | reportId, 대상 해시, 검사 항목, pass/fail/notRun, 환경, 도구 버전 |
|
||||
|
||||
시각은 UTC로 저장하고 화면에서 현지 시간으로 표시한다. 파일 크기는 Rust `u64`; JavaScript 정밀도 손실을 막기 위해 IPC의 바이트 수는 십진 문자열로 표현한다. 경로는 Rust `PathBuf`로 다루고 프로젝트 이식 경로는 `/`로 정규화한다. 직렬화 불가능한 파일명은 손실 변환하지 않고 오류로 표시한다.
|
||||
|
||||
## 프로젝트 예제와 검증
|
||||
|
||||
[egbim.package-project.json](examples/egbim.package-project.json)은 필드 형식을 보여 주는 **초안**이다. 제조사, 실제 스테이징 경로, 필수 런타임은 확인되지 않았으며 예제만으로 정식 패키지를 생성할 수 없다. `sources.alias`는 local 설정에서 실제 폴더로 연결한다. 레지스트리 예제도 실제 제품에서 요구하는 설정으로 확인해야 한다.
|
||||
|
||||
`schemaVersion`은 앱 버전과 분리한다. 알 수 없는 상위 스키마 버전과 알 수 없는 필드는 거부한다. 마이그레이션은 원본 백업과 변경 보고서를 만든 후 새 파일로 저장한다. JSON Schema와 Rust 검증이 일치하는지 계약 테스트를 수행한다.
|
||||
|
||||
버전·GUID 문자열 형식, 참조 id 존재 여부, 중복 대상 경로, 필수 파일 누락, hive와 설치 범위의 모순은 Rust에서 검사한다. 출력 경로는 소스 루트 밖이어야 한다. 검증 결과는 `severity`, `code`, `fieldPath`, `message`, `remediation`으로 반환하여 화면에서 해당 설정으로 이동하게 한다.
|
||||
|
||||
`release.json`은 고정된 프로젝트 설정을 복사하는 것으로 끝내지 않는다. 빌드된 MSI·MSP·EXE에서 읽은 실제 제품 코드·버전과 파일 정보를 기록하고 기대값과 대조한다. 메타데이터 자신의 해시를 자기 안에 넣지 않는다. 메타데이터 서명을 사용할 경우 별도 서명 파일을 생성한다.
|
||||
|
||||
## 편집·빌드 동시성
|
||||
|
||||
프로젝트 저장은 `expectedRevision`을 받아 변경 충돌을 검사한다. 빌드 계획에는 프로젝트 스냅샷 해시, 기준 릴리스 해시, 도구 해시와 identity lock revision을 포함한다. 계획 후 입력이 바뀌면 이전 계획을 실행하지 않고 다시 계산한다.
|
||||
|
||||
`releaseId`와 `buildId`는 각각 불변 릴리스와 작업 시도를 구분한다. 실패한 빌드는 이력에 남지만 배포 가능한 릴리스가 아니다. 입력이 같아도 타임스탬프 서명 때문에 재빌드 결과가 바이트 단위로 같을 것이라고 보장하지 않는다. 정확한 재배포는 보존한 최종 아티팩트를 사용한다.
|
||||
@@ -0,0 +1,43 @@
|
||||
# 파일 목록, 설치 위치와 레지스트리
|
||||
|
||||
## 파일 목록 편집과 해석
|
||||
|
||||
파일/폴더 추가, 상대 경로 유지, 포함/제외 패턴, 필수 파일 지정, 대상 폴더 변경을 지원한다. 화면에는 최종 배포 경로, 크기, PE 여부, 서명 상태, 직전 릴리스 대비 추가·수정·삭제를 표시한다. 패턴만 저장하되 빌드마다 확장한 실제 목록도 보존한다.
|
||||
|
||||
규칙의 처리 순서는 소스 alias 해석 → include 합집합 → exclude 제거 → 필수 파일 검사 → 대상 경로 계산 → 충돌 검사다. 같은 대상에 둘 이상 매핑되면 뒤의 규칙으로 덮어쓰지 않고 실패한다. 결과는 정규화된 대상 경로 기준으로 정렬한다.
|
||||
|
||||
Windows 대소문자 충돌, `..`, 절대 대상 경로, 예약 이름, ADS, 끝의 공백/점과 지원하지 않는 경로 길이를 검사한다. junction/symlink 등 reparse point는 최초 버전에서 거부한다. 출력·작업 폴더가 입력에 포함되는 순환 수집도 차단한다. 원본은 읽기만 하고 실제 파일 복사본을 스테이징한다. 하드링크로 복사하여 원본을 함께 서명하는 방식은 금지한다.
|
||||
|
||||
배포 범위는 실제 빌드 결과와 필요한 리소스로 한정한다. PDB, 소스, 테스트, 로그, 비밀 설정 제외는 프로젝트에서 명시하며, 이름이 `.config`라는 이유로 런타임 필수 파일까지 제외하지 않는다. 최초 입력 루트는 `D:\egbim\repo\14.1` 전체 대신 검증된 배포 스테이징 폴더로 설정한다.
|
||||
|
||||
## 설치 위치
|
||||
|
||||
| 디렉터리 id | 기본 의미 |
|
||||
| --- | --- |
|
||||
| INSTALLROOT | Windows의 64비트 Program Files 아래 `Baron` |
|
||||
| APPDIR | INSTALLROOT 아래 `EG-BIM` |
|
||||
| COMMONDATADIR | ProgramData 아래 제품 공용 데이터; 필요한 경우만 정의 |
|
||||
|
||||
드라이브 문자 `C:`는 하드코딩하지 않는다. 기존 설치가 있으면 탐지한 경로를 우선하며 신규 설치는 기본 경로 또는 검증된 사용자 지정 경로를 사용한다. 경로 설정은 WiX 디렉터리와 MSI 속성으로 변환한다. `ProgramFiles64Folder`와 설치 범위는 x64/perMachine에 맞춘다. [WiX Directory](https://docs.firegiant.com/wix/schema/wxs/directory/)
|
||||
|
||||
앱이 수정하는 CUI·도면·사용자 설정을 Program Files의 공급자 파일과 섞지 않는다. 공용/사용자 데이터로 옮기는 작업은 제품 변경과 마이그레이션 설계가 선행되어야 한다. 생성기가 파일 소유권을 추정해 자동 이동·삭제하지 않는다.
|
||||
|
||||
## MSI 컴포넌트 규칙
|
||||
|
||||
기본적으로 파일 하나에 컴포넌트 하나를 할당하고 해당 파일을 key path로 지정한다. 레지스트리 전용 컴포넌트도 별도로 만든다. 컴포넌트의 안정적인 식별 기준은 대상 경로·아키텍처·설치 범위·리소스 종류이며 소스 절대 경로·파일 해시·정렬 순번을 GUID 생성 기준으로 쓰지 않는다.
|
||||
|
||||
처음 할당한 WiX id와 Component GUID는 `identity.lock.json`에 보존한다. 경로/키 경로/비트수/소유권이 바뀌면 기존 GUID를 기계적으로 재사용하지 않고 호환성 검토 대상으로 분류한다. 삭제된 식별자는 tombstone으로 남겨 무관한 리소스에 재사용하지 않는다. 동일 프로젝트 동시 빌드가 서로 다른 GUID를 확정하지 못하도록 잠근다.
|
||||
|
||||
기존 ISM의 컴포넌트 GUID를 그대로 가져온다고 패치 호환성이 확보되지는 않는다. 최초 전환은 전체 업그레이드로 검증하고 이후 WiX 기준 릴리스부터 패치 계열을 관리한다.
|
||||
|
||||
## 레지스트리 편집
|
||||
|
||||
입력 필드는 `hive`, 32/64비트 `view`, `key`, 값 이름(기본값 포함), 타입, 값, 설치 조건, 제거 정책이다. 초기 지원 타입은 string, expandableString, integer, binary, multiString이며 DWORD 범위·바이너리 형식·문자열 배열을 타입별로 검증한다. 지원하지 않는 타입은 자동 문자열 변환하지 않는다. [WiX RegistryValue](https://docs.firegiant.com/wix/schema/wxs/registryvalue/)
|
||||
|
||||
문자열에는 `literal`과 `msiFormatted`를 구분한다. literal의 대괄호 등은 MSI 형식으로 오인되지 않게 변환하고, formatted는 `[APPDIR]` 같은 허용 속성만 참조한다. XML은 라이브러리로 직렬화하여 사용자 값을 원시 WXS에 삽입하지 않는다.
|
||||
|
||||
perMachine 기본은 HKLM이다. 파일 연결/COM 등록은 HKCR의 병합 뷰를 무작정 수정하지 않고 실제 소유 hive와 뷰를 명시한다. HKCU는 관리자 권한 설치를 실행한 계정과 실제 앱 사용자가 다를 수 있으므로 최초 버전의 perMachine 프로젝트에서는 사용자별 기본값 초기화를 앱 첫 실행 작업으로 분리한다. HKCU 설치 기능은 별도 구현·시험 없이는 차단한다.
|
||||
|
||||
제거 시 기본 정책은 생성한 값만 제거하는 것이다. 공유 키 전체나 `Software\Baron` 전체 삭제는 허용하지 않는다. 사용자 수정 값과 기존 값 보존 정책은 MSI repair/upgrade 동작까지 검증한 템플릿만 제공하며 UI 체크박스 하나로 보장한다고 표시하지 않는다.
|
||||
|
||||
설정 미리보기는 빌드 PC 레지스트리를 바꾸지 않는다. `.reg` 파일이나 ISM을 가져오는 기능은 향후 파서로 변환·검토하고 실행하지 않는다. 설치 과정 편집기는 표준 기능과 등록된 핸들러의 추가·삭제·조건 설정을 지원한다. 임의 셸 스크립트 입력은 최초 범위에서 제외하고, COM/서비스/CustomAction에는 소유권·롤백·권한 계약을 요구한다. [설치 과정과 UI 설계](09-install-flow-and-ui.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
# 버전과 GUID 관리
|
||||
|
||||
## 서로 다른 버전의 구분
|
||||
|
||||
| 값 | 목적 |
|
||||
| --- | --- |
|
||||
| productVersion | MSI의 3자리 버전. 예: `1.14.0` |
|
||||
| displayVersion | 사용자 표시용 버전. 사전 배포 표기 허용 |
|
||||
| engineVersion | 제품이 사용하는 엔진 버전. 현재 대상 `14.1` |
|
||||
| PE FileVersion / ProductVersion | 실제 실행 파일에 들어 있는 버전 |
|
||||
| releaseId / buildId | 릴리스/빌드 시도의 고유 식별자 |
|
||||
| project schemaVersion | 생성기 설정 파일 형식의 버전 |
|
||||
|
||||
MSI ProductVersion은 처음 세 필드만 비교하며 최대값은 각각 255, 255, 65535다. 네 번째 필드만 바꾼 릴리스를 새로운 MSI 업데이트로 처리하지 않는다. [Microsoft ProductVersion](https://learn.microsoft.com/en-us/windows/win32/msi/productversion)
|
||||
|
||||
앱 버전과 엔진 `14.1`을 동일시하지 않는다. 기존 `.ism`의 `1.13.1.0`도 MSI 비교 관점은 `1.13.1`이다. 기존 업데이터는 실제 Grimi.exe 버전을 참조하므로 생성 전에 목표 릴리스와 EXE 버전의 매핑을 검사한다. 이미 빌드한 PE의 버전을 생성기가 임의 수정하지 않는다. 불일치는 제품 재빌드 또는 명시적으로 승인된 버전 매핑으로 해결한다.
|
||||
|
||||
## 식별자 수명
|
||||
|
||||
| 식별자 | 정책 |
|
||||
| --- | --- |
|
||||
| productId | 업데이트 서비스 제품 키. 기존 `E901`; MSI GUID와 별개 |
|
||||
| UpgradeCode | 동일 제품 업그레이드 계열에서 유지 |
|
||||
| ProductCode | 최초/major upgrade 시 신규; minor upgrade 패치 계열에서는 유지 |
|
||||
| PackageCode | 내용이 바뀐 MSI마다 신규; 같은 확정 파일 재배포는 유지 |
|
||||
| Component GUID | 같은 컴포넌트 규칙을 지키는 동안 유지 |
|
||||
| PatchCode | 새 MSP마다 신규; 동일 파일 재배포는 유지 |
|
||||
| Patch family / sequence | 같은 제품 패치 순서와 대체 관계를 명시적으로 관리 |
|
||||
| Bundle UpgradeCode | 번들 업그레이드 계열에서 유지; MSI UpgradeCode와 별개 |
|
||||
| Bundle id / version | 실제 Burn 출력에서 추출하고 탐지·등록 정책에 맞게 관리 |
|
||||
|
||||
Major/Minor는 앱 버전의 첫째·둘째 숫자를 의미하지 않고 Windows Installer의 업데이트 종류다. 변경된 MSI는 새 PackageCode를 가져야 하며 ProductCode 유지 여부는 업데이트 종류에 따른다. [Windows Installer 업데이트 구분](https://learn.microsoft.com/en-us/windows/win32/msi/patching-and-upgrades)
|
||||
|
||||
## EG-BIM 초기 전환
|
||||
|
||||
기존 ISM에서 확인한 UpgradeCode는 `{E6381427-A8BC-4506-A428-CE860BDA119F}`, ProductCode는 `{FBEE188C-7D40-4CBD-80DA-89919B116F57}`이다. 이것은 확인한 파일의 값이며 모든 실제 설치본이 동일하다는 보장은 없다. 출시된 설치 파일들의 식별자·언어·아키텍처를 수집해 전환 목록을 확정한다.
|
||||
|
||||
초기 설계는 기존 UpgradeCode 유지와 새 ProductCode를 사용하는 전체 전환이다. 기존 제거 CustomAction이 데이터까지 지울 수 있으므로 GUID 연계만으로 전환을 허용하지 않는다. 백업 위치, 실제 삭제 범위, 제거 순서와 복원 시험이 통과해야 전환 경로를 활성화한다. [기존 전환 계획](../plan/02-installer-migration.md)
|
||||
|
||||
## 편집과 자동 할당
|
||||
|
||||
화면에서 표시명·버전·UpgradeCode를 설정할 수 있지만, 첫 정식 릴리스 이후 계열 식별자는 잠근다. 새 제품/계열 생성은 기존 프로젝트를 덮어쓰지 않고 명시적인 새 계열 작업으로 처리한다. ProductCode/PackageCode/PatchCode는 엔진이 계획 단계에서 할당하고 화면에는 변경 이유를 보여 준다.
|
||||
|
||||
정식 빌드의 GUID를 매번 무작위로 모두 재생성하지 않는다. 실행 전에 identity lock revision과 계획된 값을 예약한다. 실패한 작업의 예약 이력은 남기고, 재개 시 동일 바이트 산출물은 재사용한다. 내용을 바꿔 다시 만드는 MSI/MSP는 새 패키지 식별자를 할당한다.
|
||||
|
||||
동일 버전으로 서로 다른 파일을 정식 배포하는 것은 기본 금지다. 시험 빌드는 별도 draft buildId로 구분하되 배포 등록을 허용하지 않는다. 사용자 그룹은 버전/GUID를 바꾸는 이유가 아니다. 개발자 테스트를 통과한 동일 파일을 다음 그룹으로 승격한다.
|
||||
@@ -0,0 +1,68 @@
|
||||
# 전체 릴리스 생성 파이프라인
|
||||
|
||||
## 작업 단계와 상태
|
||||
|
||||
```text
|
||||
Draft → Planned → Running → Built → ArtifactVerified → Finalized
|
||||
└→ Failed / Cancelled / Interrupted
|
||||
Finalized + 별도 설치 시험 증빙 → DeploymentReady
|
||||
```
|
||||
|
||||
`Finalized`는 아티팩트가 변경 불가능하게 보관됐다는 뜻이다. 설치 시험과 배포 등록까지 성공한 상태는 아니다. `DeploymentReady` 판정은 후속 검증 증빙을 참조하며 기존 릴리스 JSON이나 바이너리를 고치지 않는다. 시험 전 결과는 패치 후보 비교에 사용할 수 있지만 정식 배포 기준으로 승격할 수 없다.
|
||||
|
||||
| 단계 | 처리와 실패 조건 |
|
||||
| --- | --- |
|
||||
| 사전 검사 | 프로젝트 스키마, 확정 필드, 도구/확장 버전, 서명 접근, 출력 잠금, 디스크 여유 확인 |
|
||||
| 계획 | 파일 목록과 차이, 설치 기능, GUID, 출력 프로필, 전체 설치·업그레이드 경로 결정 |
|
||||
| 과정/UI 변환 | 모드별 단계 의존성, 핸들러 계약, UI 백엔드 지원을 검증하고 MSI/Burn/테마 정의로 변환; 미지원 기능은 차단 |
|
||||
| 스냅샷 | 설정·identity lock·도구 정보 고정, 실제 파일 복사, 크기와 원본 해시 기록 |
|
||||
| 입력 검증 | 필수 파일, PE 버전/아키텍처, 의존 런타임, 예상한 입력 해시와 복사본 일치 검사 |
|
||||
| 내부 파일 서명 | 자체 PE 서명과 타임스탬프, 외부 PE 검증, 서명 후 해시 고정 |
|
||||
| WiX 생성 | 디렉터리·파일·컴포넌트·레지스트리·업그레이드 정의를 결정적 순서로 생성 |
|
||||
| MSI 생성 | 분할 CAB 포함 출력, 설치 테이블/식별자 검증, 정적 MSI 검증 |
|
||||
| MSI 서명 | 외부 CAB 서명 및 MSI에 서명 정보 반영이 필요한 순서 처리, 최종 MSI 서명 |
|
||||
| Burn 생성 | 확정 MSI와 런타임으로 네트워크/오프라인 번들 생성, 엔진·최종 EXE 서명 |
|
||||
| 산출물 검증 | 도구 결과뿐 아니라 실제 파일의 식별자·서명·크기·의존 관계 검사 |
|
||||
| 확정 | 모든 최종 해시 계산, 보고서/매니페스트 작성, 동일 볼륨 임시 디렉터리를 불변 경로로 이동 |
|
||||
|
||||
입력 원본은 빌드 전에 변경을 멈춘 스테이징 폴더를 사용한다. 복사 중 변경이 감지되면 실패하고 다시 스냅샷을 만든다. 서명 이후 파일 수정이 필요하면 영향받은 단계부터 새 작업으로 실행한다. 진행률은 파일 수·처리 바이트와 단계로 표시하고 외부 도구가 제공하지 않는 정확한 남은 시간을 추정값으로 단정하지 않는다.
|
||||
|
||||
디스크 여유는 원본 스테이징, 서명 복사본, 압축 전후 파일, 임시 파일, 기준 버전과 최종 결과를 포함해 계산한다. 정확히 예측할 수 없는 부분은 보수적인 여유량을 적용한다. 수 GB 파일을 메모리에 통째로 적재하지 않고 스트림으로 복사·해시한다.
|
||||
|
||||
## 대용량 출력 프로필
|
||||
|
||||
| 프로필 | 산출물과 정책 |
|
||||
| --- | --- |
|
||||
| offline-layout | Setup.exe + EG-BIM.msi + Data*.cab + prerequisites. 인터넷 없이 설치 가능한 전체 폴더 |
|
||||
| network | WebSetup.exe + 원격 MSI/CAB/런타임. 모든 payload에 불변 URL·해시·크기 연결 |
|
||||
| store-singlefile | 필수 요소를 포함한 단일 오프라인 EXE 또는 적합한 MSI. 크기·서명·Store 검증 실패 시 생성 불가 |
|
||||
|
||||
총 설치 용량이 2GB를 넘는 경우 외부 CAB를 분할한다. 기본 압축 전 CAB 예산은 **512MiB 제안값**이며 파일별 크기와 실제 생성 CAB를 검사한다. 이것은 Windows Installer의 고정 제한값이 아니다. WiX MediaTemplate의 미디어 분할 설정과 단일 대형 파일 처리 설정은 서로 다르다. 도구 버전별 지원을 검증하여 매핑한다. [WiX MediaTemplate](https://docs.firegiant.com/wix/schema/wxs/mediatemplate/)
|
||||
|
||||
전체 용량 분할이 단일 초대형 파일이나 EXE 형식의 제한까지 해결하지는 않는다. 최초 버전은 개별 파일 2GiB 이상을 보수적으로 차단하고 해당 파일의 별도 패키징 설계를 요구한다. 이 기준은 도구가 지원할 수 있는 최대값에 대한 단정이 아니라 초기 지원 범위다. 큰 파일 분할 기능을 추가할 때는 설치·복구·MSP까지 시험한다.
|
||||
|
||||
서명할 PE 파일은 4GB 이상에서 서명 문제가 있으므로 단일 EXE에 모든 내용을 무조건 포함하지 않는다. 4GB 미만도 선택한 Burn 버전·컨테이너·압축 방식에서 성공한다는 보장은 없어 실제 빌드와 서명 검증으로 판정한다. [Microsoft 대형 파일 서명 문제](https://learn.microsoft.com/en-us/windows/msix/package/signing-known-issues)
|
||||
|
||||
Store의 MSI/EXE 제출은 독립 실행 가능한 오프라인 설치 패키지를 요구한다. 네트워크 stub이나 별도 CAB URL 목록이 단일 제출 파일을 대신한다고 가정하지 않는다. `store-singlefile`이 성립하지 않으면 Store 준비 상태를 실패로 보고하고 MSIX/제품 분할 등 별도 경로를 검토한다. [Store 패키지 요건](https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msi/app-package-requirements)
|
||||
|
||||
## 서명 정책
|
||||
|
||||
Rust/WiX는 서명 인증서를 발급하지 않는다. `Signer` 어댑터가 SignTool과 사전 구성된 인증서 또는 Azure Artifact Signing 프로필을 호출한다. 프로젝트에는 프로필 id만 저장한다. 인증서/서비스 계약은 별도이며 가격과 SmartScreen 설명은 [서명 계획](../plan/06-code-signing-and-smartscreen.md)을 따른다.
|
||||
|
||||
자체 EXE/DLL뿐 아니라 IRX 등 확장자가 다른 PE도 헤더로 식별한다. 정책은 `sign-owned`, `verify-vendor`, `not-applicable`로 구분하고 파일 소유권과 허용 서명자를 명시한다. 타사 서명을 지우거나 모든 파일을 자사 서명으로 덮어쓰지 않는다. 서명이 필요한 외부 파일이 미서명인 경우 명시적인 공급자 조치가 없으면 정식 빌드를 차단한다.
|
||||
|
||||
내부 PE 서명 → CAB/MSI의 필요한 서명 정보 반영 및 최종 서명 → Burn 엔진 분리·서명·재결합 → 최종 번들 서명 → 최종 해시 순서를 적용한다. 단계별 정확한 명령은 고정된 WiX 버전 어댑터에 캡슐화한다. MSP도 생성 후 서명한다. [WiX 서명 절차](https://docs.firegiant.com/wix/tools/signing/)
|
||||
|
||||
인증서 체인·정책·타임스탬프를 검증하고 서명자, 검증 환경, 검증 시각을 기록한다. 일시적인 서명 서비스 오류는 제한적으로 재시도하되 완료된 파일을 재서명하여 해시를 바꾸지 않는다. 토큰·PIN·개인 키·전체 인증 응답은 로그에 남기지 않는다.
|
||||
|
||||
## 전체 설치와 Minor Upgrade
|
||||
|
||||
목표 릴리스마다 신규 설치 가능한 전체 MSI를 만든다. 같은 ProductCode를 유지하는 minor upgrade를 기존 설치에 적용하는 것은 단순히 새 MSI를 실행하는 것과 다르므로 별도의 `upgradeRoute`를 제공한다. MVP에서는 해당 기준에 MSP를 적용하는 경로를 우선한다.
|
||||
|
||||
MSP가 없는 상태에서 전체 MSI를 대체 업데이트로 사용하려면 해당 버전에 맞는 reinstall/업데이트 동작과 Burn 탐지를 검증한다. 미검증 시 `fallbackArtifactId`만 넣어 실행 가능하다고 표시하지 않고 `FullUpgradeRouteUnavailable`로 차단한다. major upgrade 대상과 minor upgrade 대상의 실행 계획을 분리한다.
|
||||
|
||||
## 확정·내보내기
|
||||
|
||||
동일 releaseId의 출력 폴더가 있으면 덮어쓰지 않는다. 확정 전 실패한 폴더는 격리하고 명시적인 정리 작업으로 제거한다. 기본 보존 대상은 최종 MSI/CAB/EXE, 서명된 실제 payload, wixpdb, 생성 WXS, 잠금/스냅샷, 로그와 검증 보고서다. 지원 중인 패치가 참조하는 기준은 자동 정리에서 제외한다.
|
||||
|
||||
배포 내보내기는 artifacts와 의존 관계, 최종 SHA-256, 설치/업그레이드 경로, 지원 OS·런타임, 패치 기준을 매니페스트로 만든다. offline-layout의 전체 설치 대체 경로는 단일 MSI가 아니라 필요한 CAB·런타임까지 포함한 artifact graph를 가리킨다. 업로드 URL에는 releaseId를 포함한다. payload URL 계획은 Burn 생성 전에 고정하고, 그룹 공개는 별도 배포 시스템에서 수행한다.
|
||||
@@ -0,0 +1,56 @@
|
||||
# 기준 버전별 패치 생성
|
||||
|
||||
## 입력 계약
|
||||
|
||||
패치는 이전 릴리스의 폴더와 새 폴더만 비교해 만드는 ZIP이 아니다. 보존한 기준 MSI/빌드 정보와 목표 전체 릴리스를 사용해 WiX MSP를 생성한다. WiX는 기준·업데이트 입력으로 MSI 또는 wixpdb와 관련 payload를 사용한다. 정확한 도구 호출은 버전별 백엔드가 담당한다. [WiX Windows Installer patches](https://docs.firegiant.com/wix/tools/patches/)
|
||||
|
||||
필수 입력은 `baseStateId`, `targetReleaseId`, 패치 정책, 고정 도구 프로필이다. baseState에는 기준 releaseId, 실제 ProductCode/PackageCode, ProductVersion, 언어, 아키텍처, 설치 범위, 기존 적용 PatchCode 집합, 관리 파일 상태를 포함한다. 목표는 이미 확정한 전체 릴리스의 동일한 서명 완료 파일을 사용한다. 패치 생성 중 목표 PE를 다시 서명하거나 재빌드하지 않는다.
|
||||
|
||||
기준 ProductVersion 문자열만 같은 임의 MSI는 허용하지 않는다. 등록된 기준 아티팩트 해시와 도구/설치 정의를 검증한다. 사용자 변경 데이터는 관리 파일 해시 비교에서 제외한다.
|
||||
|
||||
## 호환성 판정
|
||||
|
||||
| 검사 | 패치 생성 정책 |
|
||||
| --- | --- |
|
||||
| 제품 계열·ProductCode·언어·아키텍처·설치 범위 | 같은 패치 계열인지 확인; 불일치 시 전체 업그레이드 필요 |
|
||||
| 목표 버전 | 기준보다 높은 MSI 버전; 네 번째 필드 변경만으로는 허용하지 않음 |
|
||||
| GUID/key path/대상 경로 | MSI 컴포넌트 규칙 위반 시 차단 |
|
||||
| 파일 추가 | 허용되는 새 컴포넌트/feature 구조인지 검사 후 지원 |
|
||||
| 파일 삭제·이동·컴포넌트 제거 | 최초 버전은 전체 업그레이드 대상으로 분류; 자동 MSP 생성 금지 |
|
||||
| 파일 버전 | PE 버전 역행, 내용 변경 없이 버전만 조작, 내용 변경인데 파일 버전 동일 등의 교체 규칙 검사 |
|
||||
| 레지스트리 변경 | 지원 템플릿 내 변경과 제거/복구 동작 검증 |
|
||||
| 설치 과정·UI 변경 | Component/Feature/CustomAction/조건 변경을 호환성 검사에 포함. 번들 UI 변경은 MSP만으로 배포되지 않으므로 새 번들 경로도 검증 |
|
||||
| 필수 런타임·드라이버·서비스 구조 변경 | 최초 버전은 전체 업그레이드 대상으로 분류 |
|
||||
| 기준 파일·wixpdb 등 누락 | 생성 중단; 현재 폴더로 기준을 임의 복원하지 않음 |
|
||||
|
||||
판정 결과는 `PatchEligible`, `FullUpgradeRequired`, `InvalidInput`로 구분한다. `FullUpgradeRequired`가 나오면 위반 항목과 새 제품 계열/ProductCode 검토 필요성을 표시한다. 사용자가 패치 생성을 요청했다고 자동으로 GUID를 바꾸거나 다른 형태의 패키지를 성공 결과로 내놓지 않는다.
|
||||
|
||||
이 기준은 초기 지원 범위를 보수적으로 정의한 것이다. 모든 파일 삭제·런타임 변경이 Windows Installer에서 원천적으로 불가능하다는 뜻은 아니다. 지원 범위를 넓히려면 템플릿과 시험 매트릭스를 함께 확장한다.
|
||||
|
||||
## 생성 흐름
|
||||
|
||||
1. 기준과 목표의 서명·해시·식별자 및 잠금 스냅샷을 읽는다.
|
||||
2. 파일/레지스트리/컴포넌트 차이와 호환성 보고서를 생성한다.
|
||||
3. PatchCode와 patch family/sequence, 대체 관계를 예약한다.
|
||||
4. 기준→목표 패치 정의를 생성하고 WiX로 MSP를 만든다.
|
||||
5. MSP를 서명하고 실제 적용 대상·순서·식별자를 기대값과 비교한다.
|
||||
6. 크기·SHA-256·서명·기준 상태·목표·전체 대체 경로를 기록하고 불변 패치로 보관한다.
|
||||
7. 각 선언된 기준 상태의 VM 시험 결과를 연결하여 배포 가능 여부를 판정한다.
|
||||
|
||||
초기에는 **기준 상태 하나에서 목표 하나로 가는 MSP 하나**를 기본으로 한다. 여러 기준을 선택하면 작업을 여러 개 만든다. 실제로 여러 기준을 지원하는 단일 MSP와 무제한 패치 체인은 후속 범위다. 패치가 전체 설치보다 커지거나 이점이 작으면 결과에 표시하고 배포 정책에서 전체 경로를 선택할 수 있게 한다.
|
||||
|
||||
새로 설치한 1.14.1과 1.14.0에 패치를 적용해 도달한 1.14.1은 표시 버전이 같아도 기준 MSI/패치 이력이 다를 수 있다. 별도 baseState로 기록하여 다음 패치를 각각 시험한다. 불필요한 모든 조합을 지원하지 않고 지원 상태 목록을 명시한다.
|
||||
|
||||
## 실행기와 Burn의 계약
|
||||
|
||||
패키지 생성기는 `applyRoute`를 출력하고 실제 적용은 기존 업데이터의 연계 작업이다. MSI가 관리하는 파일을 Rust 업데이터가 직접 덮어쓰지 않는다. 실행기는 설치 식별자와 패치 상태를 조회하고 승인된 MSP 적용 명령을 사용한다.
|
||||
|
||||
최초 구현의 시험용 경로는 Windows Installer를 통한 직접 MSP 적용으로 둘 수 있다. 정식 배포 전에는 Burn으로 설치한 제품에서 패치 후 번들 표시 버전, ARP, repair, uninstall, 다음 전체 업데이트가 일관적인지 확인해야 한다. 필요 시 패치용 Burn 번들을 추가한다. 이 검증이 끝나기 전에는 패치 파일 생성 성공만으로 운영 배포를 허용하지 않는다.
|
||||
|
||||
패치 실패 뒤에는 rollback 완료·재부팅 필요·현재 설치 상태를 확인한다. 상태가 불명확하면 전체 설치를 즉시 덮어 실행하지 않는다. 전체 대체 경로는 동일 목표 릴리스이며 해당 source state에서 검증된 업그레이드 동작을 가져야 한다. [전체 릴리스의 업그레이드 경로](05-release-pipeline.md)
|
||||
|
||||
## 검증·보존 기준
|
||||
|
||||
기준 설치 → 패치 적용 → 목표 신규 설치와 공급자 관리 파일/레지스트리/제품 등록 비교 → 실행 → repair → 제거 → 다음 패치 순서를 검증한다. MSI 파일 버전 규칙과 수정된 비버전 파일 때문에 파일이 실제로 교체되지 않는 경우까지 검사한다. 재부팅 코드와 MSI source cache 누락도 시험한다.
|
||||
|
||||
패치 제거 지원은 기본 꺼짐이며, 가능하게 작성하고 데이터/다음 업데이트까지 검증한 패치만 활성화한다. 일반 장애 대응은 더 높은 버전의 수정 릴리스를 우선한다. 기준과 목표의 전체 패키지, 원본 서명 payload, 패치 순서 정보와 검증 증빙은 지원 기간 동안 함께 보존한다. [운영 패치 정책](../plan/08-version-patching.md)
|
||||
@@ -0,0 +1,70 @@
|
||||
# Tauri 화면과 명령 인터페이스
|
||||
|
||||
## 화면 구성
|
||||
|
||||
| 화면 | 입력/행동 | 결과 |
|
||||
| --- | --- | --- |
|
||||
| 프로젝트 | 생성·열기·저장, 제품명/제조사/엔진, 소스 alias 연결 | 현재 revision, 미확정 필드 |
|
||||
| 파일 목록 | 파일/폴더 추가, include/exclude, 대상 폴더, 서명 정책 | 실제 설치 트리, 용량, 누락·충돌·변경 파일 |
|
||||
| 설치 설정 | 기본/기존 경로, perMachine, x64, 필수 런타임 | 설치 디렉터리·사전 조건 미리보기 |
|
||||
| 설치 과정 | 단계 추가·삭제·활성화·순서·조건, 핸들러 설정 | 모드별 실행 계획, 의존성·필수 단계 검사 |
|
||||
| 설치 UI | 테마·로고·색상·문구, 지원되는 페이지·입력 항목 편집 | 모드별 미리보기, 선택한 BA 백엔드의 지원 범위 |
|
||||
| 레지스트리 | hive/view/key/name/type/value 편집 | 형식 검증, 생성/수정/삭제 차이 |
|
||||
| 버전과 식별자 | 목표 버전, 전체 전환/동일 계열 선택 | 자동 할당 GUID와 변경 이유, 기존 계열 잠금 |
|
||||
| 릴리스 생성 | 출력 프로필, 서명 프로필, 생성 계획 | 파일/용량/도구/설치 경로 요약과 오류 |
|
||||
| 패치 생성 | 목표 릴리스, 기준 상태 복수 선택 | 기준별 호환 여부·차이·대체 경로 |
|
||||
| 작업/이력 | 실행·취소·실패 작업 재검사, 로그 보기 | 단계 진행률, 실패 원인, 결과 폴더 |
|
||||
| 릴리스 상세 | 파일·서명·검증 증빙, 내보내기 | 확정 결과와 배포 준비 상태 |
|
||||
|
||||
파일 수가 수천 개이므로 트리·표는 가상화하고 정렬·검색·필터를 제공한다. 큰 목록은 Rust 쪽에서 페이지 단위로 조회하며 매번 전체 파일 목록을 IPC로 보내지 않는다. 단일 EXE로 만들 수 없는 용량은 생성 시작 전에 가능한 출력 방식을 설명한다.
|
||||
|
||||
일반 흐름은 프로젝트 열기 → 설정 수정 → 계획 미리보기 → 빌드 실행 → 결과 확인이다. 패치는 목표 전체 릴리스를 먼저 만들고 기준 릴리스를 선택한다. 설정이 달라졌으면 예전 계획을 실행할 수 없으며 차이를 다시 계산한다.
|
||||
|
||||
미서명 개발 결과에는 `개발용 · 배포 불가`를 표시한다. 서명 완료와 설치 시험 완료를 별도 항목으로 표시하여 성공 아이콘 하나로 뭉뚱그리지 않는다. 업로드/그룹 승격 버튼은 초기 구현 범위에 넣지 않고 배포 시스템용 파일 내보내기를 제공한다.
|
||||
|
||||
## Tauri IPC 계약
|
||||
|
||||
아래 이름은 구현할 Command 제안이며 현재 존재하는 API가 아니다.
|
||||
|
||||
| Command | 요청 → 응답 |
|
||||
| --- | --- |
|
||||
| open_project | 허용된 파일 선택 결과 → ProjectHandle, revision, 요약 |
|
||||
| save_project | handle, expectedRevision, DTO → 새 revision |
|
||||
| resolve_files | handle, revision → 목록 snapshotId, 요약 |
|
||||
| list_resolved_files | snapshotId, cursor, filter → page, nextCursor |
|
||||
| validate_project | handle, revision → ValidationReport |
|
||||
| preview_install_flow | handle, revision, installMode, mockState → 시스템 변경 없는 실행 계획 |
|
||||
| preview_installer_ui | handle, revision, backend, installMode → 미리보기 모델과 미지원 기능 |
|
||||
| plan_release | handle, revision, outputProfiles → planId, 입력 해시, 변경/경고 |
|
||||
| plan_patch | targetReleaseId, baseStateIds → 기준별 planId 또는 차단 이유 |
|
||||
| start_build | planId, clientRequestId → jobId |
|
||||
| get_job / cancel_job | jobId → 작업 상태 / 취소 접수 |
|
||||
| list_releases / get_release | 조회 조건 / releaseId → 이력 / 상세 |
|
||||
| export_release | releaseId, 허용된 목적지 → export 결과 |
|
||||
|
||||
서버 측 세션의 ProjectHandle과 planId를 사용하고 WebView에서 전달한 절대 경로를 그대로 신뢰하지 않는다. `clientRequestId`는 중복 클릭/재전송을 같은 jobId로 연결한다. 계획 데이터·권한·프로젝트 revision은 Rust가 재검증한다.
|
||||
|
||||
작업 이벤트는 `jobId`, 단조 증가 `sequence`, `stage`, `status`, `completedBytes`, `totalBytes`, `messageCode`를 포함한다. WebView가 끊겼다가 돌아오면 `get_job`과 마지막 sequence 이후 기록을 조회한다. 이벤트만이 유일한 상태 저장소가 되지 않는다. 로그는 크기 제한·회전·비밀값 제거를 적용한다.
|
||||
|
||||
오류는 `code`, `stage`, `message`, `details`, `retryable`, `logRef` 형태다. 예: `MissingRequiredFile`, `TargetPathCollision`, `IdentityConflict`, `PatchIncompatible`, `PayloadTooLarge`, `SigningFailed`, `ToolchainMismatch`, `FullUpgradeRouteUnavailable`. 화면은 원인과 바꿔야 할 설정을 보여 주고 외부 도구 원문은 상세 로그에서 확인한다.
|
||||
|
||||
## CLI 계약
|
||||
|
||||
다음은 구현 예정인 명령 형식이다. 현재 실행 가능한 명령이 아니다.
|
||||
|
||||
```powershell
|
||||
package-builder validate --project .\package-project.json --format json
|
||||
package-builder plan release --project .\package-project.json --profile offline-layout
|
||||
package-builder build --plan-id <planId>
|
||||
package-builder plan patch --target <releaseId> --base-state <baseStateId>
|
||||
package-builder job status --id <jobId> --format json
|
||||
package-builder export --release <releaseId> --output D:\exports\egbim
|
||||
```
|
||||
|
||||
CI용 `release`/`patch` 편의 명령은 같은 엔진에서 plan+build를 연속 호출하도록 추가한다. 비대화식 실행은 미확정 설정을 질문으로 보류하지 않고 실패 코드로 종료한다. JSON 결과는 stdout, 진행 로그는 stderr로 분리하고 비밀값을 두 출력 모두에서 제거한다.
|
||||
|
||||
제안 종료 코드는 0 성공, 2 입력/검증 오류, 3 호환 불가, 4 도구 실행 실패, 5 서명/무결성 실패, 6 작업 잠금 충돌, 130 취소다. 이것은 생성기 종료 코드이며 MSI의 0/3010/1641 등 설치 결과 코드와 혼동하지 않는다. 명령 성공은 해당 명령의 완료만 의미하고 일반 사용자 배포 성공을 의미하지 않는다.
|
||||
|
||||
## 생성 프로그램 자체 배포
|
||||
|
||||
Tauri 앱 자체의 설치 패키지와 버전은 EG-BIM의 프로젝트/제품 GUID와 분리한다. 개발 머신의 WebView2, WiX, SDK 및 서명 연동 도구를 검사하는 환경 진단 화면을 제공한다. 필요한 외부 도구를 자동 다운로드하거나 번들에 재배포하는 기능은 라이선스·고정 버전 검토 후 추가하며, 최초 구현은 관리자가 준비한 도구 프로필을 사용한다.
|
||||
@@ -0,0 +1,58 @@
|
||||
# 검증 계획과 구현 순서
|
||||
|
||||
## 자동 검증
|
||||
|
||||
| 계층 | 검증할 핵심 동작 |
|
||||
| --- | --- |
|
||||
| 도메인 | MSI 버전 경계, GUID 수명, component 이동/삭제 판정, 지원 기준 상태 비교 |
|
||||
| 프로젝트 계약 | JSON Schema와 Rust 역직렬화 일치, 알 수 없는 필드, 마이그레이션, revision 충돌 |
|
||||
| 파일 해석 | 포함/제외, 필수 파일 누락, 대소문자 충돌, 경로 탈출/reparse point, 원본 무변경 |
|
||||
| 레지스트리 | 타입 범위, 32/64비트, XML/MSI 문자열 escaping, 지원하지 않는 HKCU 정책 차단 |
|
||||
| 작업 엔진 | 가짜 WiX/Signer를 통한 단계 실패, 취소, 중복 요청, 체크포인트, 잠금 충돌 |
|
||||
| 실제 도구 통합 | 작은 샘플 제품으로 MSI/EXE/MSP 생성, 실제 식별자와 서명/해시 추출 |
|
||||
| 대용량 | 총 2GB 초과와 여러 CAB, 크기 합산 오버플로, 메모리 사용, 개별 제한 초과 실패 |
|
||||
| UI/IPC | 계획 이후 설정 변경 차단, 권한 없는 Command, 입력/로그의 HTML 실행 방지 |
|
||||
| 설치 과정/UI | 의존 단계 삭제·순환·조건 오류 차단, 대화형/무인 결과 일치, patch/repair Feature 유지, CustomAction 복구, WebView2 없는 PC |
|
||||
|
||||
CAB 시험에는 압축이 매우 잘 되는 0바이트 반복 데이터만 쓰지 않는다. 실제 압축률에 가까운 fixture를 사용해 산출물 크기와 분할 경계를 검증한다. 개발용 인증서 시험과 공인 서명 서비스 시험을 구분한다. 개발용 인증서 통과를 공인 서명이나 SmartScreen 평판 통과로 표시하지 않는다.
|
||||
|
||||
## Windows VM 설치 시험
|
||||
|
||||
실제 설치 시험은 생성기/개발자의 업무 PC가 아닌 스냅샷 복구 가능한 VM에서 수행한다. 각 결과에는 사용한 최종 아티팩트 해시, OS, 계정/권한, 기준 상태, 실행 로그와 결과를 연결한다.
|
||||
|
||||
| 시나리오 | 합격 조건 |
|
||||
| --- | --- |
|
||||
| 신규 설치 | 기본/사용자 지정 경로, 파일·레지스트리·런타임·실행 정상 |
|
||||
| 기존 InstallShield 전환 | 실제 배포본별 탐지, 설정·CUI·도면 보존, 기존 삭제 스크립트 영향 확인 |
|
||||
| 오프라인 전체 설치 | 네트워크 차단 상태에서 CAB와 런타임을 모두 로컬로 해석 |
|
||||
| 네트워크 설치 | 단절·재시도·캐시·해시 불일치 처리, 불완전 다운로드 미적용 |
|
||||
| 패치 | 선언한 기준 상태 각각에서 목표 신규 설치와 공급자 관리 상태 일치 |
|
||||
| 패치 불가/전체 대체 | 잘못된 ProductCode·언어·패치 이력 차단, 검증된 전체 업그레이드 실행 |
|
||||
| 파일 버전/수정 | 동일 PE 버전의 변경 파일, 수정된 비버전 파일, 누락 파일의 결과 검증 |
|
||||
| 실패/재부팅 | 앱 실행 중, 파일 잠김, 디스크 부족, 3010/1641, rollback와 복구 판정 |
|
||||
| 설치 후 유지보수 | Burn 표시와 MSI 상태, repair, uninstall, 다음 패치·전체 업그레이드 |
|
||||
| Store 출력 | 단일 파일, 무다운로드, silent 경로, 서명, 버전별 고정 URL 조건 |
|
||||
|
||||
사용자 데이터 보존은 해시가 반드시 동일해야 하는 공급자 파일과 별도 판정한다. 저장된 백업이 있다는 것만으로 복구 성공이라고 하지 않고 실제 복원과 앱 재실행까지 확인한다.
|
||||
|
||||
## 구현 순서
|
||||
|
||||
| 단계 | 구현 내용 | 완료 기준 |
|
||||
| --- | --- | --- |
|
||||
| 1. 기준 확정 | 실제 배포 payload, ISM 대조, 런타임, 출시본 GUID, 도구 버전 | 출처가 기록된 첫 프로젝트와 전환 위험 목록 |
|
||||
| 2. Rust 엔진/CLI | 스키마, 파일 해석, identity lock, 검증/계획 | fixture에서 안정적인 목록·GUID와 설명 가능한 오류 |
|
||||
| 3. 전체 릴리스 | WXS 생성, MSI/Burn, 분할 CAB, 서명 어댑터 | 작은 제품과 2GB 초과 제품의 전체 설치 시험 통과 |
|
||||
| 4. 버전별 패치 | 기준 저장소, diff, 호환성, MSP, 순서/이력 | 최소 두 기준 상태에서 동일 목표 도달·repair·제거 통과 |
|
||||
| 5. Tauri UI | 프로젝트/파일/레지스트리/릴리스/패치/작업 화면 | CLI와 같은 계획·결과, 긴 작업 중 UI 응답 유지 |
|
||||
| 6. EG-BIM 전환 | 실제 파일/레지스트리/백업, 기존 업데이터 연계 | 실제 IS 출시본→WiX→후속 MSP 경로 시험 통과 |
|
||||
| 7. 배포 연결 | 내보내기, 외부 증빙, 업로드 계약, Store 가능성 | 불변 파일과 기준 정보가 배포 시스템에 연결 |
|
||||
|
||||
버전별 패치는 필수 범위이며 최초 제품 완성에서 제외하지 않는다. 다만 작은 시험 제품으로 엔진을 검증한 뒤 실제 EG-BIM 데이터를 적용한다. UI 작업은 엔진 계약이 안정화된 후 병행할 수 있다.
|
||||
|
||||
설치 과정/화면 편집 요구는 [09 설계](09-install-flow-and-ui.md)를 따른다. 단계 2~3에 과정 검증과 기본 테마 출력을, 단계 5에 과정/UI 편집기를 추가한다. 자유로운 페이지/분기 지원은 Rust/Burn 연결 실험 후 사용자 정의 BA로 구현하며 기본 테마 편집만으로 해당 요구를 완료 처리하지 않는다.
|
||||
|
||||
## 정식 배포를 막는 미확정 사항
|
||||
|
||||
실제 설치용 소스 폴더, 제조사 표시명, 런타임 목록, 서명 프로필, 기존 설치본 목록과 파괴적 제거 동작, 업데이터의 MSI/MSP 실행 계약, Burn과 패치의 유지보수 동작은 아직 확정되지 않았다. 초안 설정으로 편집·차이 계산·개발 패키지 검증을 진행할 수 있지만 정식 릴리스의 배포 준비 상태는 부여하지 않는다.
|
||||
|
||||
이 문서 작성 단계에서는 설계 문서의 경로·예제 JSON·문서 간 일관성만 검사한다. Rust 컴파일, WiX 빌드, 실제 서명, 설치·패치·Store 심사는 수행하지 않았다.
|
||||
@@ -0,0 +1,122 @@
|
||||
# 설치 과정 편집과 설치 UI 커스터마이징
|
||||
|
||||
## 목표
|
||||
|
||||
패키지 제작자가 설치 단계를 추가·삭제·비활성화·재배치하고, 최종 사용자가 보는 설치 화면도 변경할 수 있게 한다. 제작자가 정하는 실행 정책과 설치 사용자가 선택하는 옵션은 구분한다.
|
||||
|
||||
- **설치 과정 편집기**: 환경 검사, 런타임, 제품 설치, 설정 이전, 바로가기, 완료 후 실행 등 작업을 설정한다.
|
||||
- **설치 UI 편집기**: 로고·색상·문구·약관·입력 항목·화면 순서를 설정하고 모드별 미리보기를 제공한다.
|
||||
|
||||
화면을 숨기는 것과 설치 작업을 제거하는 것은 별개다. 설치 폴더 화면을 숨겨도 경로 탐지·검증은 수행한다. 무인 설치에도 같은 설치 규칙을 적용한다.
|
||||
|
||||
## 실행 구조
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Tauri 제작 프로그램] --> F[설치 과정 정의]
|
||||
A --> U[UI 정의와 리소스]
|
||||
F --> C[Rust 검증 및 변환]
|
||||
U --> C
|
||||
C --> M[MSI 컴포넌트 · Feature · Action]
|
||||
C --> B[Burn Chain · 조건 · BA 리소스]
|
||||
B --> S[최종 Setup.exe]
|
||||
M --> S
|
||||
S --> E[설치 PC의 Burn / Windows Installer]
|
||||
```
|
||||
|
||||
제작 프로그램의 Tauri 화면과 배포되는 Setup.exe의 화면은 별개다. 설정을 WiX/Burn 정의와 UI 리소스로 변환하여 서명된 산출물에 포함한다. 이미 서명한 EXE의 테마나 작업을 외부 JSON으로 바꾸지 않고 새 빌드·서명·검증을 거친다.
|
||||
|
||||
## 단계 카탈로그
|
||||
|
||||
| 작업 | 구현 위치 | 편집 규칙 |
|
||||
| --- | --- | --- |
|
||||
| OS·공간·기존 제품 검사 | Burn 탐지/조건; 필요한 항목은 MSI에도 검사 | 제품 필수 조건은 잠금 |
|
||||
| 런타임 설치 | Burn Chain 패키지 | 앱 의존성이 없어졌을 때 제거 가능 |
|
||||
| 파일·레지스트리 설치 | MSI Component/Feature와 표준 Action | 리소스 그룹 편집; MSI 표준 실행 순서는 임의 이동하지 않음 |
|
||||
| 바로가기·파일 연결 | MSI 표준 정의/검증된 확장 | 선택 기능으로 추가/제거, 기존 설치 영향 검사 |
|
||||
| 기존 설정 백업·이전 | 검증된 마이그레이션 핸들러 | 해당 전환의 필수 단계이면 삭제 차단 |
|
||||
| 앱/서비스 종료·시작 | MSI 표준 기능/검증된 확장 우선 | 데이터 저장, 종료 실패, 재시작 정책 필요 |
|
||||
| 완료 후 앱 실행 | BA의 설치 성공 후 작업 | 대화형 설치에서 선택, 원래 사용자 권한으로 실행 |
|
||||
| 추가 업무 작업 | 버전이 고정된 사용자 정의 핸들러 | 권한·입력·설치 모드·실패 복구 계약 필요 |
|
||||
|
||||
카드 목록에서 추가/삭제/활성화, 조건 설정, 가능한 범위의 순서 이동을 제공한다. 내부 모델은 의존 관계를 가진 그래프다. 카드의 파일·레지스트리 설정은 실제 리소스 정의를 참조하고, MSI 밖 스크립트로 중복 실행하지 않는다.
|
||||
|
||||
`StepDefinition`은 `id`, `kind`, `enabled`, `appliesTo`, `phase`, `dependsOn`, `condition`, `configRef`, `handlerRef`를 가진다. 필수 여부·권한·지원 phase·실패 정책은 신뢰된 핸들러 카탈로그에서 정한다. 제작자가 필수 여부를 바꿔 보호 동작을 우회하지 못하게 한다.
|
||||
|
||||
`appliesTo`는 install, upgrade, patch, repair, uninstall을 구분한다. phase는 detect, beforeApply, managedInstall, afterSuccess로 제한한다. 이것이 MSI Sequence 번호를 직접 의미하지는 않는다. MSI 내부 작업이 필요한 핸들러는 별도의 스케줄 계약을 가진다.
|
||||
|
||||
조건은 all/any/not/equals/isInstalled/featureSelected 같은 타입이 지정된 표현식으로 저장한다. 임의 JavaScript/PowerShell을 평가하지 않으며 변수 타입·평가 시점을 검사한다.
|
||||
|
||||
## 편집 검증
|
||||
|
||||
1. 삭제 단계의 의존 작업, 그래프 순환, phase 역전, 지원하지 않는 모드를 빌드 전에 검출한다.
|
||||
2. 필수 런타임·무결성 검증·제품 설치·필수 백업은 임의로 삭제할 수 없다.
|
||||
3. 재실행 가능한 작업에는 멱등성 또는 완료 마커가 필요하다. 마커는 제품·버전·설치 시도에 연결한다.
|
||||
4. 단계 삭제가 기존 PC의 자원 삭제를 뜻하지는 않는다. 유지/제거/이전 정책을 명시하고 Component/Feature/CustomAction 변경을 패치 호환성 검사에 전달한다.
|
||||
5. 모드별 실행 계획을 각각 보여 준다. 완료 후 앱 실행은 uninstall·무인 패치에서 제외한다.
|
||||
|
||||
설치에 필수인 변경을 afterSuccess에 놓아 실패 시 복구할 수 없는 구성을 허용하지 않는다. 완료 후 선택 작업 실패는 이미 성공한 설치 트랜잭션 실패와 구분해 보고한다.
|
||||
|
||||
## 사용자 정의 작업
|
||||
|
||||
표준 MSI 기능과 검증된 WiX 확장을 우선한다. 추가 업무 작업은 개발자가 작성한 Rust 실행 파일/DLL 등의 핸들러를 등록하는 인터페이스로 지원한다. MSI ABI 또는 외부 프로세스 프로토콜과 수명 관리 어댑터가 필요하며, 임의 EXE를 곧바로 MSI CustomAction으로 넣는 기능은 아니다.
|
||||
|
||||
핸들러에는 버전·해시·서명자·입력 스키마·실행 계정·시간 제한·종료 코드·재부팅 동작·rollback/복구 방법을 등록한다. 제작자는 등록된 핸들러를 추가/삭제하고 매개변수를 편집한다. 셸 명령 문자열을 입력해 관리자 작업으로 실행하는 기능은 초기 범위에서 제외한다.
|
||||
|
||||
시스템을 변경하는 MSI CustomAction은 적합한 deferred 실행과 rollback 작업을 설계하고 필요한 데이터를 제한된 CustomActionData로 전달한다. 즉시 실행 Action에서 시스템을 변경하거나 변경이 자동 복구된다고 가정하지 않는다. [Microsoft Custom Actions](https://learn.microsoft.com/en-us/windows/win32/msi/about-custom-actions), [Rollback Custom Actions](https://learn.microsoft.com/en-us/windows/win32/msi/rollback-custom-actions)
|
||||
|
||||
Burn 체인 전체를 무조건 하나의 원자적 트랜잭션으로 표시하지 않는다. 런타임 EXE·외부 설정 이전은 별도의 복구 한계가 있다. MSI rollback, 보상 작업, 수동 복구 필요 상태를 구분한다. 기존 InstallShield 제거 스크립트에 의한 데이터 삭제도 별도 백업·복원 범위다.
|
||||
|
||||
## UI 출력 방식
|
||||
|
||||
| 백엔드 | 지원 목적 | 제약 |
|
||||
| --- | --- | --- |
|
||||
| `wixstdba-theme` | 로고, 이미지, 문구, 약관, 글꼴/배치 등 외형 수정 | WixStdBA의 페이지·컨트롤·동작 계약 안에서 변경 |
|
||||
| `custom-burn-ba` | 추가 입력 화면, 기능 선택 마법사, 조건별 분기, 자유로운 배치 | 별도 BA 프로그램과 Burn 연결 구현·검증 필요 |
|
||||
| MSI 자체 UI | MSI 직접 실행 시 기본 화면 | Burn UI와 별도이며 중복 입력/표시 방지 필요 |
|
||||
|
||||
WixStdBA는 테마 XML과 리소스로 화면을 교체할 수 있지만 동작까지 제한 없이 바꾸는 UI 프레임워크는 아니다. 공식 페이지 계약을 지키는 테마를 생성한다. [WixStdBA 테마](https://docs.firegiant.com/wix/tools/burn/wixstdba/)
|
||||
|
||||
첫 구현은 기본 테마 편집으로 브랜드·문구·배치를 제공한다. **임의의 페이지 추가/삭제·분기까지 필요한 프로젝트는 사용자 정의 BA로 처리한다.** 미지원 기능은 생략하지 않고 `UnsupportedInstallerUiCapability`로 표시한다. 자유로운 화면 요구를 기본 테마만으로 완료했다고 표시하지 않는다.
|
||||
|
||||
UI 편집기는 템플릿 선택, 리소스 등록, 문구/다국어, 허용 컨트롤 배치, 모드별 미리보기로 구성한다. 자유 배치 캔버스에 앞서 템플릿+속성 패널을 구현한다. 색상 등의 토큰은 백엔드에서 실제 지원하는 속성에만 매핑한다. 웹 CSS를 native 테마에 그대로 적용한다고 가정하지 않는다.
|
||||
|
||||
## Rust/Tauri 사용자 정의 설치 UI
|
||||
|
||||
제작 프로그램과 별도로 `installer-ui` 실행 프로그램과 `burn-bridge` 계층을 설계한다. 설치 화면에는 제작기의 파일 편집·도구 실행 API를 포함하지 않는다. UI는 입력·탐지·진행률을 표시하고 Rust 어댑터가 Burn의 Detect → Plan → Apply 및 취소/오류/재부팅 이벤트를 연결한다. UI가 별도로 msiexec를 실행하여 Burn과 경쟁하게 만들지 않는다.
|
||||
|
||||
WiX는 out-of-process BA와 native API를 제공하지만 Rust/Tauri용 완성 SDK를 제공한다는 뜻은 아니다. 고정한 WiX 버전의 native ABI/콜백에 대한 Rust FFI 연결을 작은 실험으로 먼저 검증한다. 필요한 native 어댑터의 범위·유지보수 비용도 이때 확정한다. [WiX out-of-process BA](https://docs.firegiant.com/wix/whatsnew/oopbas/)
|
||||
|
||||
Tauri 설치 UI는 WebView2 없는 PC에서도 시작할 수 있어야 한다. 지원되는 native 선행 BA/오프라인 UI 런타임 등 부트스트랩 경로를 검증한다. UI가 뜬 다음에야 UI 런타임을 설치하는 순환 구조를 피한다. 오프라인/Store 출력은 UI 런타임도 다운로드 없이 준비하고 전체 용량에 포함한다.
|
||||
|
||||
UI는 일반 권한을 유지하고 시스템 변경은 Burn/MSI의 적합한 권한 경로로 수행한다. 입력·경로·Feature 선택을 Rust에서 재검증한다. 원격 페이지나 임의 JS에 관리자 실행 기능을 연결하지 않는다. Windows UAC 보안 화면은 커스터마이징 대상이 아니다.
|
||||
|
||||
## 데이터 계약과 무인 설치
|
||||
|
||||
`PackageProject`에 `installationFlow`와 `installerUi`를 추가한다. 기존 초안 예제에서 생략한 경우 버전이 고정된 기본 과정/테마를 적용하고 빌드 스냅샷에는 전체 정의와 리소스 해시를 저장한다.
|
||||
|
||||
| 정의 | 필드 |
|
||||
| --- | --- |
|
||||
| InstallationFlow | schemaVersion, templateId/version, steps, variables, features |
|
||||
| InstallerUi | backend, templateId/version, assets, strings/locales, pages, bindings |
|
||||
| UiPage | id, kind, appliesTo, visibleWhen, controls, transitions |
|
||||
| UiBinding | controlId, variableRef, type, validator, silentDefault 또는 requiredInput |
|
||||
| HandlerDescriptor | id/version, capability set, inputSchema, execution/rollback contract |
|
||||
| CompiledInstallPlan | 모드별 단계, MSI/Burn 매핑, UI 지원 검사, 정의/리소스 해시 |
|
||||
|
||||
페이지 전환과 작업 의존성은 다른 그래프다. 다음 버튼을 여러 번 눌러도 설치는 중복 실행되지 않는다. 적용 시작 후 선택값과 계획을 고정한다. MSI 속성 입력은 허용 목록·타입·권한을 검사하며 비밀번호/토큰을 일반 속성·명령줄·로그에 넣지 않는다.
|
||||
|
||||
Feature 선택은 MSI 모델에 연결하고 repair/patch에서 설치된 선택 상태를 유지한다. 패치가 미설치 선택 기능을 임의 추가하지 않게 한다. 무인 설치는 같은 검증을 사용하며 필수 입력이 기본값이나 명령줄로 제공되지 않으면 명확히 실패한다. 약관 화면 숨김을 동의로 처리하지 않고 무인 배포의 동의 전달 규칙을 정의한다. 작업을 특정 화면 버튼에서만 실행하지 않는다.
|
||||
|
||||
## 검증과 구현 순서
|
||||
|
||||
단계 카탈로그·검증 → 과정 편집기 → 기본 테마 편집 → Rust/Burn 연결 실험 → 사용자 정의 BA·페이지 편집 순서로 구현한다. 모두 기존 전체 릴리스·MSP와 같은 스냅샷·서명·검증 절차를 적용한다.
|
||||
|
||||
- 의존 단계 삭제, 순환, 모드/조건 오류의 사전 검출.
|
||||
- 대화형·숨김·무인 모드에서 관리 파일/레지스트리 결과의 동등성.
|
||||
- optional Feature, patch/repair 선택 상태 유지, 제거와 rollback.
|
||||
- DPI·키보드·스크린 리더·다국어·취소·실패·재부팅 화면.
|
||||
- 핸들러 실패/시간 초과/재부팅 재개, WebView2 없는 PC와 오프라인 실행.
|
||||
- 테마/핸들러 변경 후 새 빌드 해시·서명·증빙 연결.
|
||||
|
||||
편집기 미리보기는 시스템 변경 없이 동작한다. 미리보기와 최종 native UI는 다를 수 있어 실제 번들의 VM 화면 시험을 완료 기준으로 둔다. 현재는 설계만 작성했으며 BA/FFI 구현·설치 시험은 수행하지 않았다.
|
||||
@@ -0,0 +1,45 @@
|
||||
# 설치 패키지 자동화 생성 프로그램 설계
|
||||
|
||||
작성 기준: 2026-10-16. 대상 제품: EG-BIM/Baron. 구현 언어는 **Rust**, 데스크톱 화면은 **Tauri 기반 웹 UI**로 확정한다. 이 문서들은 구현 전 설계이며 실행 가능한 프로그램이나 검증된 설치 패키지는 아직 없다.
|
||||
|
||||
프로그램은 설치 파일 목록, 설치 위치, 레지스트리, 버전·GUID를 프로젝트로 관리하고, 전체 릴리스와 기준 버전별 패치를 생성한다. GUI와 CI용 CLI가 같은 Rust 엔진을 사용한다. 패키지 생성 백엔드는 기존 검토를 이어 **WiX MSI/MSP + Burn EXE**를 기준으로 설계한다.
|
||||
|
||||
## 문서 구성
|
||||
|
||||
| 문서 | 설계 내용 |
|
||||
| --- | --- |
|
||||
| [01 구조와 모듈](01-architecture.md) | Tauri, Rust 공통 엔진, CLI, 작업 실행과 저장 구조 |
|
||||
| [02 프로젝트와 데이터 모델](02-project-model.md) | 설정 파일, 파일 목록, 릴리스 기록, 예제 JSON |
|
||||
| [03 파일·설치 위치·레지스트리](03-files-and-registry.md) | 파일 수집, 컴포넌트, 설치 경로, 레지스트리 작성 규칙 |
|
||||
| [04 버전과 GUID](04-version-and-identity.md) | ProductCode, UpgradeCode, PackageCode, 패치 계열 |
|
||||
| [05 릴리스 생성](05-release-pipeline.md) | 스냅샷, WiX 생성, 서명, 대용량 분할, 산출물 확정 |
|
||||
| [06 패치 생성](06-patch-pipeline.md) | 기준 선택, 호환성 판정, MSP 생성, 전체 설치 전환 |
|
||||
| [07 화면과 명령 인터페이스](07-ui-and-commands.md) | 화면별 기능, Tauri IPC, 작업 이벤트, CLI |
|
||||
| [08 검증과 구현 순서](08-validation-and-roadmap.md) | 자동 검증, Windows VM 시험, 단계별 완료 기준 |
|
||||
| [09 설치 과정과 UI 편집](09-install-flow-and-ui.md) | 단계 추가·삭제·순서·조건, UI 테마, 사용자 정의 Burn 화면 |
|
||||
| [프로젝트 예제](examples/egbim.package-project.json) | 설계용 초기 프로젝트 설정 |
|
||||
|
||||
## 범위와 결정
|
||||
|
||||
| 구분 | 내용 |
|
||||
| --- | --- |
|
||||
| 필수 | 파일·폴더 등록, 포함/제외, 설치 경로, 레지스트리, 버전/GUID, 전체 릴리스, 버전별 MSP |
|
||||
| 필수 | PE·MSI·MSP·Burn 서명 연동, 2GB 초과 전체 용량 대응, 기준 릴리스 보존, 검증 보고서 |
|
||||
| 필수 | 제작자의 설치 과정 추가·삭제·조건 편집, 설치 UI 커스터마이징; 표준 테마와 사용자 정의 BA의 지원 범위 구분 |
|
||||
| 확정 | Windows 대상, InstallShield 중단, Rust + Tauri |
|
||||
| 설계 제안 | Tauri 2, TypeScript + React + Vite, JSON 프로젝트, WiX/Burn 백엔드 |
|
||||
| 연계 | 업로드용 메타데이터 내보내기, 개발자→1차→2차→사용자 배포에 동일 아티팩트 사용 |
|
||||
| 별도 시스템 | 배포 서버·그룹 승인, EG-BIM의 실제 자동 업데이트 실행부, Store 제출 |
|
||||
| 후속 검토 | MSIX 출력, 클라우드 업로드 어댑터, 기존 ISM의 자동 가져오기 |
|
||||
|
||||
Tauri는 **생성 프로그램의 화면과 데스크톱 실행 환경**이다. Tauri가 자체 앱을 배포하는 번들러와 EG-BIM 패키지를 만드는 엔진은 별개다. EG-BIM을 Tauri 앱으로 바꾸거나, Tauri 업데이터를 기존 제품에 바로 적용한다는 뜻이 아니다.
|
||||
|
||||
기존 설치 기본 경로 `C:\Program Files\Baron\EG-BIM`을 유지한다. 실제 설치 파일 목록은 별도로 확정해야 하며 `D:\egbim\repo\14.1` 전체를 배포 파일로 취급하지 않는다. InstallShield 제거 스크립트가 사용자 데이터를 지울 수 있으므로 최초 전환에는 백업·복원 검증이 필요하다. [기존 현황](../plan/01-requirements-and-current-state.md), [설치기 전환](../plan/02-installer-migration.md)
|
||||
|
||||
전체 설치 결과는 단일 EXE로 한정하지 않는다. 대용량 기본 출력은 `Setup.exe + MSI + 분할 CAB + 필수 런타임` 레이아웃이며, 네트워크용 EXE는 필요한 데이터를 내려받는다. Store용 단일 오프라인 설치 파일은 용량과 제출 요건을 통과한 경우에만 생성한다.
|
||||
|
||||
## 완료된 설계와 남은 확정 사항
|
||||
|
||||
문서의 타입·명령·파일 형식은 구현 계약 제안이다. 도구의 정확한 버전, 제조사 표시명, 실제 배포 소스 폴더, 필수 런타임 목록, 서명 프로필, 지원 기준 릴리스는 첫 구현 단계에서 확정한다. 값이 비어 있거나 검증되지 않은 프로젝트는 편집·미리보기만 허용하고 정식 릴리스 확정은 차단한다.
|
||||
|
||||
기존 운영 정책은 [배포 계획](../plan/README.md)을 따른다. 이 설계에서는 생성 프로그램의 책임과 출력 계약을 구체화한다.
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"projectId": "egbim-windows-x64",
|
||||
"status": "draft",
|
||||
"product": {
|
||||
"productId": "E901",
|
||||
"displayName": "EG-BIM",
|
||||
"manufacturer": null,
|
||||
"architecture": "x64",
|
||||
"language": 1042,
|
||||
"installScope": "perMachine",
|
||||
"version": "1.14.0",
|
||||
"displayVersion": "1.14.0",
|
||||
"engineVersion": "14.1",
|
||||
"upgradeCode": "{E6381427-A8BC-4506-A428-CE860BDA119F}",
|
||||
"installRoot": {
|
||||
"base": "ProgramFiles64Folder",
|
||||
"relativePath": "Baron",
|
||||
"appDirectory": "EG-BIM",
|
||||
"preserveExistingPath": true,
|
||||
"allowUserSelection": true
|
||||
}
|
||||
},
|
||||
"sources": [
|
||||
{ "alias": "appPayload", "binding": "local" }
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"id": "application-payload",
|
||||
"source": "appPayload",
|
||||
"include": ["**/*"],
|
||||
"exclude": ["**/*.pdb", "**/*.log", "**/.git/**"],
|
||||
"destinationDirectory": "APPDIR",
|
||||
"required": ["Grimi.exe"]
|
||||
}
|
||||
],
|
||||
"registry": [
|
||||
{
|
||||
"id": "example-install-path",
|
||||
"hive": "HKLM",
|
||||
"view": "registry64",
|
||||
"key": "Software\\Baron\\EG-BIM",
|
||||
"name": "InstallPath",
|
||||
"value": { "type": "string", "mode": "msiFormatted", "data": "[APPDIR]" },
|
||||
"component": "registry-install-path",
|
||||
"uninstall": "removeOwnedValue",
|
||||
"reviewed": false
|
||||
}
|
||||
],
|
||||
"identity": {
|
||||
"lockFile": "identity.lock.json",
|
||||
"initialMigration": "majorUpgrade",
|
||||
"legacyProducts": [
|
||||
{
|
||||
"productCode": "{FBEE188C-7D40-4CBD-80DA-89919B116F57}",
|
||||
"productVersion": "1.13.1",
|
||||
"migrationValidated": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"prerequisites": { "reviewed": false, "items": [] },
|
||||
"outputs": {
|
||||
"profiles": ["offline-layout"],
|
||||
"cabUncompressedBudgetBytes": 536870912,
|
||||
"singleFileRejectAtBytes": 2147483648,
|
||||
"networkBaseUrl": null,
|
||||
"storeSingleFileEnabled": false
|
||||
},
|
||||
"signing": {
|
||||
"profileRef": null,
|
||||
"ownershipPolicyRef": null,
|
||||
"requiredForRelease": true
|
||||
},
|
||||
"patchPolicy": {
|
||||
"enabled": true,
|
||||
"mode": "oneMspPerBaseState",
|
||||
"supportedBaseStateIds": [],
|
||||
"allowFileRemoval": false,
|
||||
"allowUninstall": false,
|
||||
"requireValidatedFullUpgradeRoute": true
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user