# 持续集成

用一条命令执行生成的 GitHub Actions 发布拉取请求或发布分支行为。

Source: https://semifold.noctisynth.org/zh/docs/commands/ci/
Language: zh



在 `smif init` 中选择 GitHub Actions 的仓库，推荐使用 `smif ci` 作为发布入口。它拒绝在 GitHub Actions 之外运行，并跳过配置基础分支以外的分支。

```bash
smif ci
```

## 存在变更集时 [#存在变更集时]

在基础分支上，`ci` 计算版本修改，渲染配置的发布分支、提交消息与 Pull Request 标题，应用版本文件，强制更新发布分支，再创建或刷新返回基础分支的拉取请求。提交消息与 Pull Request 标题都默认使用 `chore(release): bump versions`；也可以在 `[release]` 中使用与分支模板相同的严格 `release.*` 上下文定制。

渲染后的发布分支必须与基础分支不同。Semifold 会在应用版本文件或修改 Git ref 前检查这项约束；把基础分支用作发布分支会直接失败，不会被解释为 trunk release 工作流。

因此，贡献者只需要把变更集与代码一起提交并合入。维护者在自动创建的发布拉取请求中审查版本和变更日志。

发布拉取请求正文通常包含各软件包的变更日志。如果正文超过保守的 65,536 UTF-8 字节预算，Semifold 会改用软件包版本摘要，并提示审查者到拉取请求的 **Files changed** 页面查看完整变更日志。摘要按软件包 ID 排序，只保留预算内的完整软件包条目，变更日志文件仍保留完整内容。创建和更新拉取请求均执行此保护，无需额外配置。

## 不再存在变更集时 [#不再存在变更集时]

发布拉取请求合入后，下一次基础分支运行发现没有待处理变更集，于是调用发布操作，并启用 GitHub Release 处理。软件包会先接受检查，再按依赖关系发布。

<LifecycleDiagram
  items="[
  '代码与变更集进入基础分支',
  '自动维护发布拉取请求',
  '发布拉取请求合入基础分支',
  '按依赖关系发布软件包',
]"
/>

## 环境与输出 [#环境与输出]

命令使用 `GITHUB_ACTIONS`、`GITHUB_REF_NAME`、`GITHUB_REPOSITORY` 和 `GITHUB_TOKEN`。生成的工作流使用稳定 step ID `semifold`；该 step 实际运行的分支会写出 `semifold-version` 或 `semifold-publish` output key。所在 job 再把它们映射成 `version` 和 `publish`：

```yaml
jobs:
  release:
    outputs:
      version: ${{ steps.semifold.outputs['semifold-version'] }}
      publish: ${{ steps.semifold.outputs['semifold-publish'] }}
    steps:
      - id: semifold
        run: smif ci
```

后续 job 使用 `needs.release.outputs.version` 或 `needs.release.outputs.publish`；本次没有运行的分支对应空字符串。发布部分失败时，Semifold 会先尽力写出包含恢复状态的 publish JSON，再返回非零状态。

`--dry-run` 会准备相应分支行为，但不会推送分支、创建拉取请求或发布。配置权限时应以生成的工作流为受支持基线，不要从一段缺少权限说明的最小示例重新拼装。

## GitHub 错误诊断 [#github-错误诊断]

GitHub 操作失败时会显示失败操作、HTTP 状态、API 消息，以及可用的校验详情和文档链接。客户端错误保留底层错误链。这些信息无需开启 `--debug`，GitHub token 会被遮蔽。403 会按操作提供权限检查提示，但不会将原因一律断定为权限不足。

发布 PR 的查询、创建、更新或分支推送失败会终止命令。`ci` 进入发布流程时，使用与 `publish` 相同的 Release 和附件诊断。

