# `release.toml` reference
## Top-level concepts
```toml
required_version = "0.1.0" # minimum release-tool SemVer,类似 cmake_minimum_required
[repository]
github = "owner/name" # 必须与 origin identity 一致
branch = "main" # release 只能从该 branch 的 remote HEAD 执行
[hooks]
preflight = ["just", "verify"] # 可空;argv,不经过 shell
```
```text
current release-tool crate < required_version
-> 在完整 shape parsing 前拒绝,并要求更新 Cargo dependency/Cargo.lock
current release-tool crate >= required_version
-> 按已定义字段语义读取;unknown field 仍拒绝,防止拼写错误
```
没有 `schema_version`、`version_file`、`RELEASE_TAG` 或 lifecycle command list。
## Command values
所有 project hooks 是 argv array:
```toml
build = ["just", "_build-release-image", "{image}"] # 一个 program + 两个 args
# 禁止:shell = "just build && just test"
```
```text
Supported placeholders
{version} # resolved calendar tag
{image} # Docker target 的 resolved image(仅 build/local_check)
```
工具直接执行 argv,不调用 `sh -c`,因此空格、`$()`、`;` 不会被二次解释。
`preflight`、Docker `build` / `local_check` 的 native stdout/stderr 会实时继承到调用方。
接收 tool-injected credentials 的 `remote_check` 仍由工具 capture,并在错误输出前 redaction。
## GitHub Release publisher
```toml
[publishers.release]
kind = "github_release"
title = "CPE {version}"
prerelease = true
```
remote identity 是 GitHub Release tag + asset name。一个 Release 可以承载多个 target 的 assets。
## Docker archive target
```toml
[[targets]]
name = "sc"
kind = "docker_archive"
publisher = "release"
default = true
platform = "linux/amd64"
image = "cpe:{version}"
asset = "cpe-{version}-linux-amd64.tar.xz"
build = ["just", "_build-release-image", "sc", "{image}"]
local_check = ["just", "_check-release-image", "sc", "{image}"]
```
`asset` 必须是单一安全文件名。adapter 校验 image platform,执行 `docker save` + `xz`,并生成
GNU-compatible SHA-256 checksum file。
## GitHub Maven publisher
```toml
[publishers.packages]
kind = "github_maven"
settings = ".mvn/settings.xml" # repository-owned;只引用 env credentials
server_id = "github"
```
settings example:
```xml
<settings>
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers>
</settings>
```
token 由工具从 `gh` 读取,仅注入 Maven/remote-check child environment。
## Maven reactor target
```toml
[[targets]]
name = "maven"
kind = "maven_reactor"
publisher = "packages"
default = true
wrapper = "./mvnw"
pom = "pom.xml"
projects = ["jobs/cpe/cpe-job-model", "jobs/skycross/skycross-job-model"]
also_make = true
remote_check = ["just", "_check-published-maven", "{version}"]
```
```text
POM reactor model
-> selected projects + internal dependencies when also_make=true
-> derived groupId/artifactId/version/packaging
-> planned jar/pom identities
```
配置不复制 `coordinates`。第一期为保持 adapter 小而可证明,接受以下 reactor subset:
```text
- selected modules 的 GAV 可从 module/parent direct fields 得到
- ${revision} 是 GAV 中唯一支持的 expression
- packaging: jar | pom
- main artifact + POM;不猜测 classifiers/attached artifacts
- duplicate GAV、unresolved expression 或其它 packaging 立即失败
```
这不是静默近似 Maven effective model:无法确定 exact deploy inventory 时停止,后续按真实 adopter
需求扩展解析能力。
完整 adopter 配置见 [`examples/`](../examples)。
## OCI image targets
每个 image 是一个普通 target。`kind = "oci_image"` 隐式选择 registry publisher,因此没有
`[publishers.registry]`,也不配置 `publisher = "registry"`:
```toml
[[targets]]
name = "base"
kind = "oci_image"
image = "ghcr.io/example/base:{version}"
platform = "linux/amd64"
reuse_check = ["just", "_reuse-image", "base"]
build = ["just", "_build-image", "base"]
[[targets]]
name = "prepared"
kind = "oci_image"
default = true
depends_on = ["base"]
image = "ghcr.io/example/prepared:{version}"
platform = "linux/amd64"
reuse_check = ["just", "_reuse-image", "prepared"]
build = ["just", "_build-image", "prepared"]
```
选择 `prepared` 会自动包含 `base`。配置顺序不决定执行顺序;Resolve 展开 transitive closure,
然后按依赖关系排序,无依赖关系的 targets 按 name 稳定排序。unknown、self、duplicate dependency
和 cycle 都会在发布前失败。v1 只允许 `oci_image -> oci_image` dependencies。
### Project command environment
`reuse_check` 和 `build` 是 argv arrays,不经过 shell,也不需要在每个 command 中重复 placeholders。
工具注入:
```text
RELEASE_TARGET current target name
RELEASE_VERSION calendar release version/tag
RELEASE_COMMIT exact source commit
RELEASE_IMAGE local candidate / remote destination tag
RELEASE_DEPENDENCIES_JSON prepared direct dependencies
```
`reuse_check` 额外收到:
```text
RELEASE_CANDIDATE_IMAGE digest-pinned previous/current candidate
```
dependency JSON 按 target name 排序;每个 value 包含:
```json
{
"base": {
"reference": "ghcr.io/example/base@sha256:...",
"config_digest": "sha256:..."
}
}
```
Build dependency 尚未 push 时,`reference` 是已本地 Inspect 的 current candidate tag;
Reuse/Existing dependency 使用 digest-pinned remote reference。两种情况都提供已冻结的 OCI
config digest。
### Build / Reuse / Existing
release-tool 从较早的 sealed repository releases 由新到旧查找同一 target 的 image tag,并立即
解析为 exact digest。没有 previous candidate 时直接 Build;不需要 bootstrap 文件。
```text
reuse_check exit 0 candidate 满足当前 source/dependency context,Reuse
reuse_check exit 10 candidate 已过期,Build
其它 exit code 无法可靠判断,停止 release
```
freshness 规则属于项目。`reuse_check` 可以读取 project-owned labels、source facts、testsets 或
dependency digests;release-tool 不定义 `inputs`、fingerprint 或 external input schema。check 必须
只读,不得 login、push、retag、修改 local image 或 tracked source。
Prepare 后 target 的内部 action 是:
```text
Existing sealed current tag 已存在且 reuse_check 通过;不写,只验证
Reuse previous exact manifest 通过 reuse_check;remote-retag 到 current tag
Build 无 candidate 或 reuse_check 返回 10;build 生成 current local image
```
被依赖 target 始终保留在 plan 中;所谓“跳过”仅是不运行其 `build`。Prepare、Publish、Verify
都按同一稳定拓扑顺序执行。
publisher 不执行 `docker login`,只使用当前 Docker credential store。v1 只接受一个
`os/architecture` platform,不创建 multi-platform index。builder 只生成 current local image;
不得 push、retag 或修改 tracked source。
### Registry recovery 与 concurrency
publisher 对 current tag 执行 write-before/write-after Inspect;任何已存在但与 prepared
manifest/config/platform 不一致的 tag 都停止,且从不 delete、force 或 clobber。未 Seal candidate
出现 current tag 时视为 orphan publication。
write command 失败后重新 Inspect;只有 remote 与 prepared artifact 完全一致时,丢失响应才按
成功处理。普通 OCI tag write 没有通用 compare-and-swap,因此同一 release 必须由 single writer
串行发布,或由 registry 提供 immutable-tag enforcement;Doctor 将无法无写入证明的能力报告为
`UNVERIFIABLE`。
完整 Resources 配置见
[`release.toml`](../examples/computed-parameter-engine-resources/release.toml)。