# 完整构建与发布链路

按前端项目版本生成不可变制品，发布为静态站点，并完成验证和版本恢复。

百积木站点按“项目＋版本”构建和部署。版本必须与源码根目录 `package.json.version` 完全一致；平台在首次构建时固定源码，后续重试使用同一份源码。用户和 AI 无需查询或填写 Git SHA。

本文流程面向普通静态网站。需要平台身份的前端使用 `ENVIRONMENT_HOSTED_APP`，直接按
[平台应用版本创建流程](/development/bundle-development/platform-application-development/create-and-install/)
从项目版本构建并随 Bundle 安装；不先发布外部站点，也不把外部 HTTPS 地址写成平台应用入口。

## 标准生命周期

```text
前端 Project
  -> 严格 SemVer 版本
  -> 项目构建动作
  -> 不可变版本制品
  -> Site
  -> Site Deployment
  -> 当前稳定访问地址
  -> 浏览器端到端验证
```

具体参数以当前 CLI 和项目类型声明为准。开始前先查看当前能力：

```bash
baijimu --version
baijimu project type list --json
baijimu project action --help
baijimu site --help
```

## 1. 先选择正确的前端 Project 类型

| 目标                                        | 必须选择的项目类型                  | 发布链路                                         |
| ----------------------------------------- | -------------------------- | -------------------------------------------- |
| 官网、活动页、Dashboard 等普通静态网站                  | `REACT_STATIC_APPLICATION` | `buildReactProject` → 项目版本 → Site Deployment |
| 工作区应用入口、需要平台身份或 Runtime 能力、随 Bundle 安装的前端 | `PLATFORM_APPLICATION`     | 平台应用版本 → Bundle 版本 → 安装或升级                   |

`WEB_APPLICATION` 是不提供 `buildReactProject` 和不可变项目版本的旧版通用类型，不能用于新的静态站点发布。
不能根据“网站”这个名称选择它，也不能在创建项目后临时补一个版本号绕过构建。

创建或复用项目前，必须先执行 `baijimu project type list --json`，按返回的稳定 `typeKey` 选择；不要使用数字类型 ID。
已有项目还必须执行 `baijimu project action list <PROJECT_ID> --json`：普通静态网站如果没有
`buildReactProject`，说明项目类型选错，应新建 `REACT_STATIC_APPLICATION` 项目并迁移源码，不要继续创建 Site Deployment。

创建普通前端项目：

```bash
baijimu project create \
  --workspace-id <WORKSPACE_ID> \
  --project-type-key REACT_STATIC_APPLICATION \
  --name <PROJECT_NAME>
```

创建请求只声明工作区、稳定项目类型代码和项目基本信息。初始化归档与初始文件由项目类型目录维护；
不要在创建时传入访问范围、模板项目、模板提交或下载地址。项目类型在创建后不可转换；需要另一种项目类型时应创建新项目。

已有项目应直接使用真实 `projectId`，不要用项目名称或列表第一项代替。项目类型是否可用以及它提供哪些动作，
以当前工作区查询结果为准。

## 2. 完成开发并声明版本

提交依赖锁文件，并确保生产构建不依赖开发机上的未提交文件。发布前至少完成：

- 类型检查、单元测试和生产构建。
- 首页与深层路由的本地预览。
- 公开环境变量使用目标环境值。
- API 地址来自环境配置，不在业务代码中固定测试地址。
- 产物不包含 token、私钥、数据库凭据或内部管理地址。

在根目录 `package.json` 中声明本次版本，例如 `"version": "1.2.3"`，把源码推送并合并到平台项目主线。
构建时填写该版本。首次构建校验主线中的版本并固定源码；一旦绑定，主线继续变化也不会改变该版本。

构建失败或取消后，不修改源码可以使用原版本重试。需要修复源码时，先设置新版本并提交主线，再构建新版本。
平台不会自动修改源码版本，也不允许删除版本后复用同一版本号。

## 3. 创建并等待前端构建任务

先读取项目公开的动作名称和参数 Schema：

```bash
baijimu project action list <PROJECT_ID> --json
```

使用返回的前端构建动作 `functionName` 创建任务。下面参数文件展示通用 React/Vite 构建；字段必须以动作当前
返回的 `parameterSchema` 为准：

```json title="frontend-build.json"
{
  "version": "1.2.3",
  "packageManager": "auto",
  "installCommand": "auto",
  "buildCommand": "pnpm run build",
  "outputDirectory": "dist"
}
```

```bash
baijimu project action run \
  --workspace-id <WORKSPACE_ID> \
  <PROJECT_ID> <FUNCTION_NAME> \
  --params @frontend-build.json
```

调用成功只表示构建任务已经创建。使用返回的真实 `jobId` 查询状态：

```bash
baijimu project action status \
  <PROJECT_ID> <FUNCTION_NAME> <JOB_ID> \
  --json
```

构建成功后按相同项目版本部署。成功版本的制品不可替换；重复请求会返回已有构建结果。失败时先查看日志，原源码可用原版本重试，修改源码则使用新版本。

## 4. 创建 Site

Site 是稳定的站点身份，Deployment 是它的一次发布。首次发布前创建 Site；后续版本继续使用同一个
`siteKey`，不要为每次构建创建新 Site。

```bash
baijimu site create \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY>
```

已有 Site 可以直接读取确认：

```bash
baijimu site get \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> \
  --json
```

`siteKey`、Project 和 Artifact 必须属于目标工作区。不要从另一个工作区复制 ID，也不要从域名格式推导
`siteKey`。

## 5. 部署项目版本

用构建成功的项目和版本创建 Site Deployment：

```bash
baijimu site deployment create \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> \
  --project-id <PROJECT_ID> \
  --version 1.2.3
```

`--version` 不是任意部署标签。它必须已经由同一项目的 `buildReactProject` 成功登记。若返回
`PROJECT_VERSION_NOT_FOUND`，不要重试部署：先回到第 3 步完成构建并确认任务成功；如果动作列表中没有
`buildReactProject`，则按第 1 步更换为正确项目类型。

如果站点只发布 Artifact 中的一个子目录，显式增加 `--publish-sub-path <RELATIVE_PATH>`；默认情况下不要猜测或
重复填写构建输出目录。`outputDirectory` 属于构建动作，`publish-sub-path` 属于站点 Artifact 内的发布选择，
两者不是同一个字段。

创建请求返回后，使用真实 `deploymentId` 等待最终状态，并读取当前发布：

```bash
baijimu site deployment get \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> <DEPLOYMENT_ID> \
  --json

baijimu site deployment current \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> \
  --json
```

只有 Deployment 成功、当前发布指向目标 Deployment，并且真实访问地址通过验证，发布才算完成。

## 6. 验证真实站点

使用 `deployment current` 返回的正式地址完成浏览器验证，至少覆盖：

1. 首页可以打开，HTML、脚本、样式和图片均返回成功。
2. 每个深层路由都能直接打开，刷新不会返回 404。
3. 静态资源使用正确基路径；子路径发布时不存在重复或缺失路径前缀。
4. API 请求指向目标环境，且没有把服务 token 或其他长期密钥发送给浏览器。
5. 未登录、权限不足、后端不可用和业务错误都有明确反馈。
6. 发布的项目版本、部署记录和正式地址能够相互对应。
7. 普通站点使用自己的后台授权；站点部署不会创建平台应用版本或授予平台身份。

## 7. 需要平台能力时的交付流程

普通网站到 Site Deployment 和浏览器验证为止，不需要创建平台应用或 Bundle。
需要平台身份和 Runtime 能力时，把前端放入专属平台应用项目，使用环境托管入口和同源配置 SDK，
按以下链路重新交付，而不是把站点 URL 填入历史外部应用类型：

```text
PLATFORM_APPLICATION 项目主线与精确版本
  -> ENVIRONMENT_HOSTED_APP 版本内入口
  -> CLI 等待构建并冻结平台应用版本
  -> Bundle 引用精确版本并安装或升级
  -> 平台生成托管入口和同源配置
  -> 验证 PKCE 授权与真实业务调用
```

完整步骤见 [发布并纳入 Bundle](/development/bundle-development/platform-application-development/create-and-install/)。

## 8. 恢复此前版本

恢复时选择此前已经验证的项目版本，再创建一次 Deployment。平台复用该版本的既有制品，不重新构建，也不会读取当前主线替换旧版本：

```bash
baijimu site deployment list \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> \
  --json

baijimu site deployment create \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> \
  --project-id <PROJECT_ID> \
  --version <PREVIOUS_VERSION>
```

恢复同样必须等待新 Deployment 成功，并重新执行正式地址、深层路由、API 和权限验证。
此流程只恢复普通站点，不能替代环境托管平台应用的版本发布与 Bundle 安装管理。

### 恢复没有版本号的旧站点制品

版本构建启用前产生的普通静态站点制品没有真实项目版本。仅在恢复这类历史制品时，使用旧构建记录中已经成功的 Artifact ID：

```bash
baijimu site deployment restore-artifact \
  --workspace-id <WORKSPACE_ID> \
  <SITE_KEY> <HISTORICAL_ARTIFACT_ID>
```

该命令只接受旧静态站点制品；新版本统一使用 `deployment create --project-id --version`。不要把任务编号或 Artifact ID 当作项目版本。

> **构建成功不等于发布成功**
>
> 项目动作成功只产生 Artifact；Site Deployment 成功才会改变站点当前版本。两步都必须保存真实 ID 并分别
> 验证。
