Enterprise 版本
Release — 深度参考
NextPDF\Enterprise\Release 命名空间将一次产品发布建模为不可变的、带类型的值对象。其公开接口为七个 final 类和五个以字符串为底层类型的枚举。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';新增字段用次版本号,破坏性变更用主版本号;自 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> | — | 枚举字段序列化为其底层字符串值 |
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 / 无 / 无 / 无 | 边界跟随 license 渠道;固定的来源与消费渠道;所有面向客户的包名 | 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 | 枚举:Paid、Evaluation、Internal | 仅当为 Paid 与 Evaluation 时 isCustomerFacing 为 true | 底层为 'paid'、'evaluation'、'internal' | — | requiresAuthentication 对每个边界都返回 true |
DistributionChannel | 枚举:GitHubReleases、PrivatePackagist、DirectDownload | isArtifactOrigin 与 isConsumptionLayer 区分这两种角色 | 底层为 'github_releases'、'private_packagist'、'direct_download' | — | DirectDownload 预留给未来的签名 URL 渠道 |
EncodingTechnology | 枚举:IonCube、None | 命名编码工具,区别于交付形式 | 底层为 'ioncube'、'none' | — | 明文工件始终报告 None |
PublishingEnvironment | 枚举:Staging、Production | 仅当为 Production 时 isCustomerFacing 为 true | 底层为 'staging'、'production' | — | Staging 是内部验证目标 |
ReleaseStatus | 枚举: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 签名、校验和)。其 schema 版本对新增项采用次版本号、对破坏性变更采用主版本号。BuildProfile是关于一个工件包含什么、以及如何被打包的唯一事实来源。命名、清单与计划都由配置文件推导得出;不存在次级配置来源。EncodingTechnology命名编码工具;DeliveryMode(来自 Licensing 模块)命名交付形式。二者刻意分离,明文工件始终报告EncodingTechnology::None。DistributionChannel将工件来源(二进制存储;上传目标)与包消费层(composer require读取的注册表)分离开来。来源存储二进制文件;消费层提供指向它的元数据。AccessBoundary枚举 Paid、Evaluation 与 Internal。每个边界都要求认证。Internal 工件服务于 CI、QA 与 staging,绝不面向客户。PublishingPlan::fromProfiles将每个配置文件精确解析为两个目标:一个工件来源目标和一个消费层目标,其访问边界由配置文件的 license 渠道推导得出,使付费工件与评估工件得以正确路由。- 该计划是对预期目标的描述,而非传输本身。实际上传由周边的发布工具执行,而清单记录(但其本身并不产出)供应链佐证。
ReleaseStatus为生命周期赋予类型:Built → Audited → Staged → Published,其中Revoked与Superseded是从Published出发的终态出口。只有Published面向客户可见;从Published起canPromote为false。ReleaseManifest::validate与PublishingPlan::validate以字符串列表形式报告一致性错误,且从不抛出。空列表是唯一有效的结果。
边界情形与失败模式
标题为“边界情形与失败模式”的章节BuildProfile::fromArray遇到缺失、非字符串或为空的必填字段时:抛出指明该字段的InvalidArgumentException。BuildProfile::fromArray遇到为空或非字符串的ioncube_expire时:归一化为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 签名与校验和由周边的发布流水线产出与验证。记录佐证路径是一种能力,而非背书:清单本身并非证据、不为来源背书、不为发布颁发证明,也不构成法律意见。
开发说明
标题为“开发说明”的章节- 优先使用
ReleaseManifest::createWithDefaults,使佐证文件名始终与ArtifactNamer保持一致。将原始构造函数保留给有意的逐路径覆盖。 - 在任何发布步骤前于 CI 中运行两个
validate()闸门,并在错误列表非空时让流水线失败。 PublishingPlan::fromProfiles默认为PublishingEnvironment::Staging。请显式传入Production;本模块中没有任何环节会隐式晋级环境。- 序列化后的清单携带枚举的底层值(
paid、encoded、ioncube等)与 ATOM 时间戳;请将这些字符串视为对外的传输契约。 - 评估工件位于独立的包命名空间(
-evaluation后缀)。请在你的 Composer 配置中让付费注册表与评估注册表保持分离。 - 各渠道的路由、凭据与存储由运营方负责。计划告诉工具一个工件归属何处,而非如何对其进行认证。
发布边界
标题为“发布边界”的章节本页仅记录外部可观测的行为与受支持的公开 API 范围。内部命名空间路径、辅助类、机制表、runbook 文件名以及工单前缀均不在范围之内。
另请参阅
标题为“另请参阅”的章节- Release(能力页面)
- Licensing — 深度参考 — 配置文件所消费的
LicenseEdition、LicenseChannel与DeliveryMode枚举。 - Enterprise 概览
- License 激活