App 릴리스하기
App 버전과 호환 범위를 정하고 재현 가능한 패키지 업그레이드를 전달합니다.
App 릴리스하기
Workshop을 Composer 패키지로 배포하고 별도 호스트 변경에서 그 버전을 채택합니다. 예시는 최소 Core 0.5.0와 SDK 0.5.0를 지원하는 App의 v1.2.3 릴리스입니다. 테스트한 호환 범위를 선언하고 배포 환경에서 인증할 수 있는 Composer 저장소를 준비하세요.
버전·호환 범위 결정 → 후보 검사 → 승인된 tag 공개 → 호스트 요구 사항·lock 갱신 → 신규 설치·기존 테넌트 업그레이드 확인 순서로 진행합니다.
버전의 대상 구분
| 버전 | 선언 위치 | 예시와 의미 |
|---|---|---|
| App 패키지 | App Git tag | v1.2.3은 이 저장소의 배포본이며 Composer가 버전을 읽음 |
| SDK 패키지 | SDK 릴리스와 App require | ^0.5.0는 호환 SDK 패치를 허용하며 App 변경으로 SDK가 릴리스되지는 않음 |
| Core 호환성 | App extra.nexia.core_version | ^0.5.0는 지원하는 Core 패치 범위를 선언하며 Core 설치 명령이 아님 |
| Resource descriptor | ResourceDescriptor::version | '1.0'은 공개 Resource 계약 버전, App tag와 독립 |
| Event payload | EventDraft::schemaVersion, catalog·subscription 선언 | 1 같은 양의 정수, 소비자가 지원하는 정확한 버전을 검사 |
| 생성 catalog 형식 | 호스트 generator | Resource map schema 3, Event map schema 1은 JSON 형식 버전 |
1.0 전에는 호환 수정·추가는 patch, 비호환 변경은 minor를 올립니다. 1.0부터는 수정은 patch, 호환 기능 추가는 minor, 비호환 변경은 major를 올립니다. Core·SDK·App은 독립적으로 버전을 관리합니다. App이 새로운 계약이나 호스트 구현을 필요로 할 때만 해당 의존성의 최소 버전을 올립니다.
일치하는 의존성 선언
Scaffold는 Core·SDK의 호환 범위를 선언합니다.
{
"require": { "amuzcorp/nexia-app-sdk-laravel": "^0.5.0" },
"extra": { "nexia": { "core_version": "^0.5.0" } }
}기존의 다른 metadata는 유지하세요. Composer version 필드는 수동 추가하지 않으며 개발 branch alias는 릴리스 tag를 대신하지 않습니다. 호환성 명령은 설치된 버전에 대해 두 선언을 검사합니다. --core-version, --sdk-version은 대상 버전 판정을 시뮬레이션할 뿐 그 버전을 설치하거나 테스트하지 않습니다.
package.json의 peerDependencies["@nexia/sdk"]도 같은 SDK 범위(^0.5.0)로 유지합니다. 프런트엔드 검사는 정확한 버전 또는 안정 버전의 caret 범위를 허용합니다. Core ^0.5.0은 0.5.0 이상 0.6.0 미만을 허용하고 SDK ^0.5.0도 같은 규칙입니다. 프런트엔드 범위 검사는 Core 0.4.5에서 처음 지원됐지만 현재 scaffold는 Core 0.5.0을 요구합니다. 로컬 SDK 소스는 Core workspace 흐름으로 선택하며 App manifest에 vendor 또는 임시 link: SDK 의존성을 넣지 마세요. 최소 지원 버전과 후보 버전에서 테스트하세요. metadata 시뮬레이션은 호환성 테스트를 대신하지 않습니다.
Core만 호환 패치하면 App·SDK tag는 유지합니다. SDK만 호환 패치하면 App tag를 유지하고 필요할 때 Core lock에서 새 SDK를 채택합니다. App만 수정하면 해당 App을 릴리스하고 Core 배포 lock을 갱신합니다. 새 SDK 기능에 호스트 구현이 필요하면 소비 App에 두 최소 버전을 함께 선언합니다. 릴리스 절차는 소스 저장소의 docs/project/GIT-WORKFLOW.md를 참고하세요.
후보 검사
마이그레이션·공개 계약 변경을 포함해 App 테스트하기를 마칩니다. Composer가 릴리스 후보를 사용하는 상태에서 Core 루트 명령을 실행하세요.
task artisan -- nexia-apps:validate-app-compat --app=workshop --require-declarations
task artisan -- nexia-apps:validate-app-descriptors workshop
task artisan -- nexia-apps:validate-app-frontend-dependencies --app=workshop --require-manifests
task artisan -- nexia-runtime:generate-app-map결과와 함께 App 커밋, 설치된 Core·SDK 버전을 기록합니다. 생성된 .github/workflows/ci.yml은 저장소 인증과 대상 Core ref/version을 설정한 후 수동 실행합니다. 파일이 있다는 사실은 검사 성공을 뜻하지 않습니다.
후보 공개와 호스트 lock 갱신
App 작업 브랜치의 PR/MR과 릴리스 승인 절차를 마친 뒤 App 저장소에서 확정 후보에 tag를 붙여 공개합니다. 승인된 후보를 v1.2.3으로 배포하는 명령은 다음과 같습니다.
nexia_release_commit=REPLACE_WITH_APPROVED_COMMIT_SHA
git show --no-patch --oneline "$nexia_release_commit"
git tag -a v1.2.3 "$nexia_release_commit" -m 'Release 1.2.3'
git push origin v1.2.3호스트에는 해당 패키지를 제공하는 인증된 Composer 저장소와 tag를 선택할 요구 사항이 있어야 합니다. 로컬에서 Workshop 활성화에 성공했다고 미공개 패키지를 운영에서 받을 수 있는 것은 아닙니다. 별도 호스트 작업 브랜치에서 커밋 대상 composer.json을 변경한 뒤 Core 루트에서 실행합니다.
호스트 composer.json의 기존 require 객체에 아래 항목을 병합하고 다른 의존성·인증된 저장소 설정은 유지합니다. 첫 채택은 정확한 버전으로 고정합니다. 범위를 넓히려면 업데이트 정책을 별도로 결정하세요.
{ "require": { "amuzcorp/nexia-workshop": "1.2.3" } }task apps:lock -- workshop
task apps:lock:verify -- workshop이 명령은 무시되는 composer.local.*가 아닌 커밋 대상 composer.json/composer.lock을 사용합니다. 고정된 버전과 VCS ref를 검토하세요. 새 SDK가 필요한 App은 SDK를 먼저 공개합니다. 기존 범위에서 호환되는 미변경 App은 새 tag가 필요하지 않습니다. 선택한 패키지 조합은 Core에서 마지막으로 채택하고 관련 PR/MR에 순서를 적습니다. PR 생성 권한과 merge 승인은 별개입니다.
깨끗한 설치나 전체 릴리스 테스트 전에 대상 Core 버전과 committed lock의 호환성을 검사합니다:
task release:preflight CORE_VERSION=0.5.0기존 PHP/Composer 도구로 private 패키지를 가져오지 않고 metadata를 검사합니다. 정확한 버전을 고정한 기존 tag를 범위로 전환하려면 App 새 릴리스와 lock 채택이 한 번 필요합니다. 공개된 tag나 lock metadata를 고쳐 우회하지 마세요.
패키지 업그레이드 확인
로컬 소스 overlay가 없는 깨끗한 호스트에서 committed lock으로 설치합니다. 위 패키징 검사를 그 설치본에 적용한 뒤 활성화하고 대상 테넌트의 설치 계획을 확인하세요. 오래된 로컬 mount가 숨긴 누락 파일을 찾는 단계입니다.
기존 테넌트는 배포의 tenants:migrate --force로 설치된 App 스키마를 갱신합니다. 신규 App 설치는 자체적으로 미적용 마이그레이션과 초기화를 실행하며 이미 활성화된 App에는 문서화된 repair·upgrade 절차가 필요할 수 있습니다. 패키지 tag만으로 테넌트 DB·사용자 권한·호스트 배포가 바뀌지는 않습니다.
공개 필드 삭제·이름 변경 전에 저장된 descriptor 선택과 Event 소비자를 검토합니다. Event 선언과 소비자 버전은 의도적으로 맞추고 App tag가 바뀌었다는 이유로 모든 버전을 올리지 않습니다. 검토용 catalog를 재생성하되 수정 대상은 생성 JSON이 아니라 소유 선언입니다.
App·SDK·Core 커밋, lock ref, 업그레이드 검사 결과와 운영 절차를 기록합니다. 활성화·초기화·권한의 구분은 App 라이프사이클, descriptor 계약은 Resource 계약을 참고하세요.
운영 카탈로그 등록과 테넌트 설치
패키지 배포와 카탈로그 게시, 테넌트 설치는 각각 별도 단계입니다. 운영 호스트가 패키지를 로드한 뒤 실행합니다.
php artisan nexia-apps:reconcile-app-catalog
php artisan nexia-apps:reconcile-app-catalog --check신규 App은 private / draft로 등록됩니다. Central App Catalog에서 배포 대상을 정하고 published로 게시하세요. 비공개 App은 대상 테넌트와 필수 선행 App의 사용 자격도 부여합니다. 패키지는 available 또는 beta여야 합니다. 개발 전용 preview를 운영 설치에 사용하지 않습니다.
nexia_tenant=REPLACE_WITH_TENANT_ID
php artisan tenants:run "nexia-apps:install-tenant-app workshop --dry-run" --tenants="$nexia_tenant"
php artisan tenants:run "nexia-apps:install-tenant-app workshop --with-prerequisites" --tenants="$nexia_tenant"설치는 선행 App부터 미적용 마이그레이션을 실행하고 초기화한 뒤 활성화합니다. 별도 사용자 권한 부여가 필요합니다. 이후 배포의 tenants:migrate --force는 설치 이력이 있는 App만 업데이트하며, 비활성 App의 데이터도 유지·업데이트합니다. 기존 미설치 App 테이블은 삭제하지 않습니다. 마이그레이션 실패 시 완료된 이력은 남으며 원인을 고친 뒤 설치를 재시도합니다. 신규 테넌트는 전체 App이 담길 수 있는 기존 schema dump를 로드하지 않습니다. 이전 버전에서 미리 만든 pending 테넌트는 기존 테이블을 유지합니다.