Enterprise 에디션
Release — 심층 참조
한눈에 보기
섹션 제목: “한눈에 보기”NextPDF\Enterprise\Release 네임스페이스는 제품 릴리스를 불변의 타입 지정 값 객체로 모델링합니다. 그 공개 표면은 일곱 개의 final 클래스와 다섯 개의 문자열 기반 enum입니다. ReleaseManifest는 아티팩트별 ArtifactManifest 항목과 공급망 증거 경로를 집계합니다. BuildProfile은 하나의 아티팩트 변형에 대한 단일 진실 공급원입니다. ArtifactNamer와 PackageMapping은 프로파일로부터 결정론적 파일명과 Composer 패키지 정체성을 도출합니다. PublishingPlan::fromProfiles는 모든 프로파일을 올바른 채널과 액세스 경계를 갖춘 타입 지정 PublishingTarget 항목으로 해석합니다. ReleaseStatus는 릴리스 라이프사이클에 타입을 부여합니다. 이 모듈은 I/O, 네트워크 호출, 암호화 연산을 전혀 수행하지 않습니다. 순수한 메타데이터 모델링입니다.
가용성 및 라이선스
섹션 제목: “가용성 및 라이선스”이 역량은 NextPDF Enterprise(nextpdf/enterprise)로 제공되며 Enterprise 등급 라이선스 봉투로 활성화됩니다. 해당 권한이 없는 배포는 이 역량의 클래스를 로드하지 않습니다. 에디션 비교 및 라이선스 받기.
이 표면은 nextpdf/enterprise 패키지 경계로 라이선스가 부여되며 별도의 기능별 역량 코드가 없습니다. Core와 Pro는 릴리스 모델링 계층을 제공하지 않습니다.
공개 API 표면
섹션 제목: “공개 API 표면”composer require nextpdf/enterprise:^3| 심볼 | 매개변수 | 기본 동작 | 반환 | 예외 또는 실패 조건 | 비고 |
|---|---|---|---|---|---|
ReleaseManifest::__construct | version, sourceCommit, builtAt, artifacts = [], sbomPath = null, gpgSignature = null, checksumPath = null | 불변의 최상위 릴리스 문서를 빌드합니다 | 인스턴스 | — | final readonly; SCHEMA_VERSION은 '1.0'; 추가 필드에는 마이너, 호환성 파괴에는 메이저; since 3.0.0 |
ReleaseManifest::createWithDefaults | string $version, string $sourceCommit, DateTimeImmutable $builtAt, array $artifacts = [] | ArtifactNamer를 통해 기본 SBOM, 서명, 체크섬 파일명을 미리 연결합니다 | self | — | 릴리스 빌더를 위한 정규 진입점입니다; 개별 경로를 재정의하려면 생성자를 사용하십시오 |
ReleaseManifest::toArray / ::toJson | 없음 | 모든 아티팩트 항목과 함께 매니페스트를 직렬화합니다 | array / JSON 문자열 | toJson: 인코딩 실패 시 JsonException | 보기 좋게 출력되며 슬래시는 이스케이프되지 않습니다; built_at은 ATOM 형식 |
ReleaseManifest::validate | 없음 | 아티팩트 목록이 비어 있지 않으며 모든 아티팩트가 릴리스 버전 및 커밋과 일치하는지 확인합니다 | 오류의 list<string>; 비어 있으면 유효함 | 예외를 던지지 않음 | 호출자는 비어 있지 않은 목록을 결함으로 취급해야 합니다 |
ArtifactManifest::__construct | filename, version, sourceCommit, edition, deliveryMode, encodingTechnology, channel, phpTarget, sha256, ioncubeExpire, builtAt | 빌드된 하나의 아티팩트를 기록합니다: 무엇이 빌드되었는지, 어떻게, 그리고 어떻게 검증하는지 | 인스턴스 | — | final readonly; ioncubeExpire는 만료되지 않는 아티팩트의 경우 null |
ArtifactManifest::fromProfile | BuildProfile $profile, string $version, string $sourceCommit, string $sha256, ?DateTimeImmutable $builtAt = null | 파일명과 모든 프로파일 차원을 도출합니다 | self | — | builtAt은 현재 시각을 기본값으로 합니다 |
ArtifactManifest::toArray | 없음 | JSON 인코딩을 위해 직렬화합니다 | array<string, string|null> | — | enum 필드는 자신의 백킹 문자열 값으로 직렬화됩니다 |
BuildProfile::__construct / ::fromArray | 프로파일 필드 / array $data | 하나의 아티팩트 변형을 정의합니다; 명명, 매니페스트, 계획의 단일 진실 공급원 | 인스턴스 / self | fromArray: 누락되거나 비어 있는 필수 필드에 대해 InvalidArgumentException | 필수 키: name, edition, delivery, encoding_technology, channel, php_target |
BuildProfile::requiresEncoding / ::isEvaluation | 없음 | 프로파일 차원에 대한 술어 헬퍼 | bool | — | 인코딩은 DeliveryMode::Encoded와 EncodingTechnology::IonCube를 함께 요구합니다 |
ArtifactNamer::format | BuildProfile $profile, string $version | nextpdf-{edition}-{delivery}-{channel}-php{target}-{version}.zip을 생성합니다 | non-empty-string | — | 결정론적입니다; PHP 대상에서 점이 제거됩니다(8.4는 php84가 됨) |
ArtifactNamer::checksumFile / ::signatureFile / ::sbomFile / ::manifestFile | string $version (manifestFile: 없음) | SHA256SUMS-{v}.txt, SHA256SUMS-{v}.txt.asc, sbom-{v}.cdx.json, release-manifest.json을 생성합니다 | non-empty-string | — | SBOM 파일명은 core의 SBOM 생성기가 작성하는 CycloneDX 문서와 일치합니다 |
PackageMapping::packageName / ::resolvePackageName | BuildProfile / LicenseEdition + LicenseChannel | nextpdf/pro 또는 nextpdf/enterprise로 매핑합니다; 평가 채널은 -evaluation을 덧붙입니다 | non-empty-string | 알 수 없는 에디션에 대해 InvalidArgumentException | 별도의 평가 네임스페이스는 유료 아티팩트와의 혼합을 방지합니다 |
PackageMapping::distUrlPattern | BuildProfile $profile, string $version | 정규 아티팩트 저장소에서 아티팩트 다운로드 URL을 해석합니다 | non-empty-string | — | 인코딩 버전과 평문 버전은 패키지 이름을 공유합니다; 그 dist URL은 서로 다릅니다 |
PackageMapping::accessBoundary / ::artifactOrigin / ::consumptionChannel / ::allPackageNames | BuildProfile / 없음 / 없음 / 없음 | 경계는 라이선스 채널을 따릅니다; 고정된 원본 및 소비 채널; 모든 고객 대면 패키지 이름 | AccessBoundary / DistributionChannel / DistributionChannel / list<non-empty-string> | — | Core는 프리미엄 패키지가 아니며 이름 목록에서 제외됩니다 |
PublishingPlan::fromProfiles | array $profiles, string $version, PublishingEnvironment $environment = Staging | 프로파일마다 두 개의 대상을 해석합니다: 아티팩트 원본 하나, 소비 계층 하나 | self | — | 환경은 Staging을 기본값으로 합니다; 프로덕션은 항상 명시적인 선택입니다 |
PublishingPlan::targetsByBoundary / ::targetsByChannel / ::packageNames | AccessBoundary / DistributionChannel / 없음 | 해석된 대상에 대한 필터 및 열거 헬퍼 | list<PublishingTarget> / list<PublishingTarget> / list<non-empty-string> | — | packageNames는 정렬되고 중복이 제거됩니다 |
PublishingPlan::validate | 없음 | 대상이 비어 있지 않고, 버전이 계획과 일치하며, 평가 패키지가 유료 경계에 놓이지 않는지 확인합니다 | 오류의 list<string>; 비어 있으면 유효함 | 예외를 던지지 않음 | 모든 업로드 단계 전에 실행하십시오 |
PublishingPlan::toArray | 없음 | 드라이런 출력 및 로깅을 위해 직렬화합니다 | array<string, mixed> | — | target_count와 패키지 목록을 포함합니다 |
PublishingTarget::fromProfile | BuildProfile $profile, string $version, PublishingEnvironment $environment, DistributionChannel $channel | 하나의 채널에 대한 패키지 이름, 액세스 경계, 아티팩트 파일명을 해석합니다 | self | — | final readonly; toArray는 로깅을 위해 직렬화합니다 |
AccessBoundary | enum: Paid, Evaluation, Internal | isCustomerFacing는 Paid와 Evaluation에 대해서만 true입니다 | 'paid', 'evaluation', 'internal'로 백킹됨 | — | requiresAuthentication은 모든 경계에 대해 true를 반환합니다 |
DistributionChannel | enum: GitHubReleases, PrivatePackagist, DirectDownload | isArtifactOrigin과 isConsumptionLayer가 두 역할을 나눕니다 | 'github_releases', 'private_packagist', 'direct_download'로 백킹됨 | — | DirectDownload은 향후 서명된 URL 채널을 위해 예약되어 있습니다 |
EncodingTechnology | enum: IonCube, None | 전달 형식과 구별되는 인코딩 도구를 명명합니다 | 'ioncube', 'none'로 백킹됨 | — | 평문 아티팩트는 항상 None을 보고합니다 |
PublishingEnvironment | enum: Staging, Production | isCustomerFacing는 Production에 대해서만 true입니다 | 'staging', 'production'로 백킹됨 | — | Staging은 내부 검증 대상입니다 |
ReleaseStatus | enum: Built, Audited, Staged, Published, Revoked, Superseded | canPromote, nextStatus, isCustomerVisible, isTerminal이 라이프사이클에 타입을 부여합니다 | nextStatus는 ?self를 반환합니다 | — | 승격 체인 Built → Audited → Staged → Published; Revoked와 Superseded는 종단입니다 |
진입점 시그니처, 소스에서 그대로 발췌:
public static function createWithDefaults(string $version, string $sourceCommit, DateTimeImmutable $builtAt, array $artifacts = []): selfpublic static function fromProfile(BuildProfile $profile, string $version, string $sourceCommit, string $sha256, ?DateTimeImmutable $builtAt = null): selfpublic static function fromArray(array $data): selfpublic static function format(BuildProfile $profile, string $version): stringpublic static function fromProfiles(array $profiles, string $version, PublishingEnvironment $environment = PublishingEnvironment::Staging): selfpublic static function fromProfile(BuildProfile $profile, string $version, PublishingEnvironment $environment, DistributionChannel $channel): self동작 계약
섹션 제목: “동작 계약”- 모든 클래스는
final이며, 모든 값 클래스는readonly입니다. 생성이 모든 상태를 고정합니다. 이 모듈은 파일시스템, 네트워크, 암호화 연산을 수행하지 않습니다. ReleaseManifest는 한 버전에 대한 불변의 최상위 문서입니다: 시맨틱 버전, 소스 커밋, 빌드 타임스탬프, 아티팩트 목록, 그리고 선택적 공급망 증거 경로(SBOM, GPG 서명, 체크섬). 그 스키마 버전은 추가에는 마이너, 호환성 파괴에는 메이저입니다.BuildProfile은 아티팩트가 무엇을 담고 어떻게 패키징되는지에 대한 단일 진실 공급원입니다. 명명, 매니페스트, 계획은 모두 프로파일로부터 도출됩니다; 부차적인 구성 소스는 없습니다.EncodingTechnology는 인코딩 도구를 명명하고;DeliveryMode(Licensing 모듈에서)는 전달된 형식을 명명합니다. 둘은 의도적으로 분리되어 있으며, 평문 아티팩트는 항상EncodingTechnology::None을 보고합니다.DistributionChannel은 아티팩트 원본(이진 저장소; 업로드 목적지)을 패키지 소비 계층(composer require가 읽는 레지스트리)과 분리합니다. 원본은 이진 파일을 저장하고; 소비 계층은 그것을 가리키는 메타데이터를 제공합니다.AccessBoundary는 Paid, Evaluation, Internal을 열거합니다. 모든 경계는 인증을 요구합니다. Internal 아티팩트는 CI, QA, 스테이징에 사용되며 고객에게 절대 노출되지 않습니다.PublishingPlan::fromProfiles는 각 프로파일을 정확히 두 개의 대상으로 해석합니다: 아티팩트 원본 대상과 소비 계층 대상, 그리고 프로파일의 라이선스 채널로부터 도출된 액세스 경계를 적용하여 유료 및 평가 아티팩트가 올바르게 라우팅됩니다.- 이 계획은 의도된 대상을 설명하는 것이지 전송이 아닙니다. 실제 업로드는 주변 릴리스 도구가 수행하며, 매니페스트는 공급망 증거를 기록하지만 — 그것을 직접 생성하지는 않습니다.
ReleaseStatus는 라이프사이클에 타입을 부여합니다: Built → Audited → Staged → Published, 그리고Revoked와Superseded는Published로부터의 종단 출구입니다.Published만 고객에게 표시됩니다;canPromote는Published이후로false입니다.ReleaseManifest::validate와PublishingPlan::validate는 일관성 오류를 문자열 목록으로 보고하며 예외를 던지지 않습니다. 빈 목록만이 유일한 유효 결과입니다.
엣지 케이스 및 실패 모드
섹션 제목: “엣지 케이스 및 실패 모드”- 누락되거나, 문자열이 아니거나, 비어 있는 필수 필드를 가진
BuildProfile::fromArray: 해당 필드를 명명하는InvalidArgumentException. - 비어 있거나 문자열이 아닌
ioncube_expire를 가진BuildProfile::fromArray:null(만료 없음)로 정규화됩니다.encode_paths와exclude_paths에서 문자열이 아니거나 비어 있는 항목은 조용히 제거됩니다. - 알려진 맵 밖의 에디션을 가진
PackageMapping::resolvePackageName:InvalidArgumentException. - 인코딩할 수 없는 데이터에 대한
ReleaseManifest::toJson:JsonException. 직렬화는JSON_THROW_ON_ERROR를 사용합니다; 조용한 대체는 없습니다. ReleaseManifest::validate는 빈 아티팩트 목록과, 버전 또는 소스 커밋이 릴리스와 다른 모든 아티팩트를 오류로 보고합니다.PublishingPlan::validate는 빈 대상 목록, 계획과 어긋나는 모든 대상 버전, 그리고 유료 경계로 해석된 모든 평가 패키지를 보고합니다.ReleaseStatus::nextStatus는Published,Revoked,Superseded에서null을 반환합니다. 호출자는null을 처리해야 합니다; 순환은 없습니다.- 원본 채널과 소비 계층 채널은 서로 구별됩니다;
composer require를 아티팩트 원본으로 향하게 하지 마십시오. - Internal 경계 아티팩트는 고객에게 절대 노출되지 않습니다; 이를 고객 채널로 라우팅하는 것은 명시적인 모델링 오류입니다.
- 이 모듈은 어떠한 암호화 연산도 수행하지 않습니다. GPG 서명과 체크섬 생성은 외부에서 이루어지며 여기서는 참조만 됩니다.
적합성
섹션 제목: “적합성”이 모듈에 대해서는 어떠한 표준 적합성도 주장하지 않습니다; 이는 릴리스 모델링 계층이며, NextPDF는 어떠한 인증도 보유하지 않습니다. 기본 SBOM 파일명(sbom-{version}.cdx.json)은 core의 SBOM 생성기가 작성하는 CycloneDX 문서와 일치합니다; 매니페스트는 그 증거를 참조하며 그것을 검증하지는 않습니다. GPG 서명과 체크섬은 주변 릴리스 파이프라인이 생성하고 검증합니다. 증거 경로를 기록하는 것은 역량이지 증명이 아닙니다: 매니페스트는 그 자체로 증거가 아니며, 출처를 입증하지 않고, 릴리스를 인증하지 않으며, 법적 자문을 구성하지 않습니다.
개발 참고 사항
섹션 제목: “개발 참고 사항”- 증거 파일명이 항상
ArtifactNamer와 일치하도록ReleaseManifest::createWithDefaults를 선호하십시오. 원시 생성자는 의도적인 경로별 재정의를 위해 남겨 두십시오. - 모든 게시 단계 전에 CI에서 두
validate()게이트를 실행하고 비어 있지 않은 오류 목록에서 파이프라인을 실패시키십시오. PublishingPlan::fromProfiles는PublishingEnvironment::Staging을 기본값으로 합니다.Production을 명시적으로 전달하십시오; 이 모듈의 어떤 것도 환경을 암묵적으로 승격하지 않습니다.- 직렬화된 매니페스트는 enum 백킹 값(
paid,encoded,ioncube등)과 ATOM 타임스탬프를 담습니다; 그 문자열을 와이어 계약으로 취급하십시오. - 평가 아티팩트는 별도의 패키지 네임스페이스(
-evaluation접미사)에 존재합니다. Composer 구성에서 유료 및 평가 레지스트리를 구별하여 유지하십시오. - 채널별 라우팅, 자격 증명, 저장소는 운영자의 책임입니다. 이 계획은 도구에게 아티팩트가 어디에 속하는지를 알려주는 것이지, 그것에 어떻게 인증할지를 알려주는 것이 아닙니다.
게시 경계
섹션 제목: “게시 경계”이 페이지는 외부에서 관찰 가능한 동작과 지원되는 공개 API 표면만을 문서화합니다. 내부 네임스페이스 경로, 헬퍼 클래스, 메커니즘 표, 런북 파일명, 티켓 접두사는 범위 밖입니다.
함께 보기
섹션 제목: “함께 보기”- Release (역량 페이지)
- Licensing — 심층 참조 — 프로파일이 소비하는
LicenseEdition,LicenseChannel,DeliveryModeenum. - Enterprise 개요
- 라이선스 활성화