96 lines
9.6 KiB
Markdown
96 lines
9.6 KiB
Markdown
---
|
||
name: builder
|
||
description: >-
|
||
初始化或检查 makefile.builder 契约,再构建或发布 deb/镜像/Android APK/iOS IPA,
|
||
或把产物拷到目录/容器。产物可在本机或 CI 上构建;拿到产物用 obtain。触发词:初始化
|
||
builder、检查 makefile.builder、构建/发布 deb、推送 apt、构建/发布 Docker 镜像、
|
||
打 APK/IPA、拷到 File Browser、make push、看构建、监听 CI、obtain。
|
||
未授权不上传。Docker 仅用户点名镜像时才走。
|
||
---
|
||
|
||
# Builder:DEB / Docker / Android / iOS 构建发布
|
||
|
||
**make 管构建,skill 脚本管发布,本 SKILL.md 只留脚本做不了的决策。**
|
||
项目状态是**当前 builder 项目根**的 `makefile.builder` 与 `.env.builder`;项目自定义分发脚本放在
|
||
同一项目根的 `.pouch/builder/`,不要改用户的 `Makefile` / `makefile` / `.env`。如果父仓库包含
|
||
submodule,submodule 是独立 builder 项目:它的 `makefile.builder`、`.env.builder` 和
|
||
`.pouch/builder/` 必须放在 submodule 内,父仓库只负责调用或固定 submodule commit。
|
||
|
||
配置来源原则:项目要构建什么、发布哪些轨道、使用哪个已提交的分发脚本,放在
|
||
`makefile.builder`;本机路径和工具链覆盖放在被忽略的 `.pouch/builder/local.mk`;凭据、
|
||
发布目标和本轮别名放在被忽略的 `.env.builder`。`COPY_SCRIPT` 若指向项目内
|
||
`.pouch/builder/` 的脚本,优先写入 `makefile.builder`,这样迁移项目时配置与脚本一起进入 Git。
|
||
|
||
构建执行位置、Agent CLI、模型、推理强度和 session 生命周期由共享 `agent-runtime` 的
|
||
`.pouch/agent.yaml` 管理。`builder.<name>` 是可自由增加的 binding:可以指向本地
|
||
worktree,也可以指向已配对的远程 Mac/其它构建机;不要把远程主机、模型或 terminal 参数
|
||
硬编码进 `makefile.builder`。跨机器或跨 session 时先读 `agent-runtime`,构建目标仍只能
|
||
由 `makefile.builder` 提供。
|
||
|
||
开始时解析当前 `SKILL.md` 所在目录,记为 `<skill-dir>`。优先
|
||
`git rev-parse --show-toplevel` 解析项目根。
|
||
|
||
## 选择模式
|
||
|
||
- 初始化、接入 builder,或还没有 `makefile.builder`:执行「初始化」。
|
||
- 检查契约或发布配置:执行「检查」。
|
||
- 构建、发布、上传:执行「工作流」。不要静默初始化。
|
||
- 看构建、监听 CI、ACK/short-ship/long-ship 要产物:执行「拿到产物」。不要当成第五条轨道。
|
||
- 指定 `builder.<name>`、远程构建机或跨 session:先读共享 `agent-runtime`。
|
||
- 不适用:本地安装/卸载 DEB;RPM/语言包;从零设计打包体系(先出方案);普通编码与 Dockerfile 编辑。
|
||
- 改本 skill 自身:契约先改 `scripts/check.py`,再同步 [contract.md](references/contract.md) 与 templates;不在生产上传上试脚本。
|
||
|
||
## 初始化
|
||
|
||
1. 确认项目根。优先以包含目标 `makefile.builder` 的仓库根为准;若目标位于 submodule,则以 submodule 根为准,不向父仓库回溯配置。探测 `makefile.builder`、`.env.builder`、用户 Makefile(只当抄配方的证据,不改)、`Dockerfile`、`debian/`。`.env.builder` 只看键是否存在且非空,不读、不打印值。不要读取用户 `.env`。
|
||
2. 判定轨道:有 Dockerfile → docker;有 deb 信号或用户要打 deb → deb;`app.config.ts` / `assembleRelease` / `.apk` → android;`ios/` / `xcodebuild` / `.ipa` → ios;用户要拷到目录或容器 → copy。可多轨道。都不清则问。不要猜测 registry、token、COPY_DEST 或仓库名。
|
||
3. 没有 `makefile.builder`:按轨道拷模板。deb/docker 用 `templates/makefile.builder`;仅 android 用 `templates/makefile.android.builder`;仅 ios 用 `templates/makefile.ios.builder`。按轨道删掉未使用的 deb/docker/push* 段,把 `build` 的 TODO 换成仓库里已有的真实编译命令(可从用户 Makefile 抄配方,但不要 `include` 或递归调用它),且配方必须使用 `$(ARCH)`。Android/iOS 的 `ARCHES` 是构建机 ISA(fat APK/IPA 仍只留本机一项)。按 [contract.md](references/contract.md) 填 `ARCHES`:`debian/control` / CI matrix / 用户点名的子集;否则只写本机(`x86_64`→`amd64`,`aarch64`→`arm64`)。不要默认双架构;看不出交叉编法时只留一项并说明。`include` builder 的 `scripts/version.mk`。多产物把 `push` 改成 `push: push-deb push-docker push-copy` 的子集。不要改用户 Makefile。
|
||
4. 已有 `makefile.builder`:跑检查;按 FAIL 给出修补说明。不覆盖 `build`。用户明确要求按契约改时再加 `ARCHES`,并确认配方里有 `$(ARCH)`。不要调用 create-makefile(版本规则冲突)。
|
||
5. 没有 `.env.builder`:把 `<skill-dir>/templates/env.builder` 拷到项目根(注释键,不含值)。缺发布键时在报告里给出可粘贴示例,并把 `.env.builder` 加入 `.gitignore`,不要提交。
|
||
6. 运行 `python3 -I -S <skill-dir>/scripts/check.py <project-dir> --ready`。结构校验通过且当前轨道能构建才称「完成」;只缺发布键是「部分完成」。契约 FAIL 或轨道工具缺失是「阻塞」。除非用户明确要求,不提交、不推送、不上传。
|
||
|
||
```text
|
||
## builder 初始化:完成 | 部分完成 | 阻塞
|
||
|
||
已具备: …
|
||
待配置: 路径 + 字段 + 可粘贴示例 + 缺了会挡住哪步
|
||
工具链: make / docker / dpkg-deb(缺则怎么装,不擅自安装)
|
||
下一步: 一句话
|
||
```
|
||
|
||
```text
|
||
# .env.builder 键名示例
|
||
DEB_SERVER_URL=https://deb.example.com
|
||
DEB_REPOSITORY=main
|
||
DEB_TOKEN=
|
||
DOCKER_REGISTRY=registry.example.com
|
||
COPY_DEST=file-server:/srv
|
||
COPY_AS=latest.apk
|
||
# 外部/临时脚本才放这里;项目内脚本优先在 makefile.builder 设置 COPY_SCRIPT
|
||
```
|
||
|
||
## 检查
|
||
|
||
只读。运行 `check.py <project-dir> --ready`,用同一报告格式,标题改为 `## builder 检查:…`。不写 `makefile.builder` / `.env.builder`,不改用户 Makefile 或 `.env`。用户明确要求修复后再转入初始化。
|
||
|
||
## 工作流
|
||
|
||
契约见 [contract.md](references/contract.md)。Docker 的 registry/tag 不明确时再读 [registry.md](references/registry.md)。
|
||
|
||
1. 跑 `check.py <project-dir>`;需要工具链与发布键时加 `--ready`;要实构 deb 时加 `--build`。契约 FAIL 或轨道工具缺失:停下,转入「初始化」,不要绕过校验,不要改用户 Makefile。只缺发布键:允许构建,禁止上传。未接契约的存量项目按 contract.md §6 发现已有入口,上传仍用 builder 脚本;成功交付一次后引导迁到 `makefile.builder`。
|
||
2. 仅当用户明确要求发布、上传或提交时才上传。不猜测生产端点;不把 token 写入输出、文件、提交或回复;不用 `set -x` 跑含凭据的命令。可能覆盖同版本时先问。脏工作树默认拒绝发布;用户明确接受时设 `ALLOW_UNCOMMITTED=1` 并注明未提交修改。
|
||
3. 构建:用户指定了架构才传 `ARCH=`;否则不要传,让 makefile 按 `ARCHES` 展开(`make -s -f makefile.builder arches`)。`make -f makefile.builder build` 始终单架构;DEB 用 `make -f makefile.builder deb`。版本按契约从 Git 祖先稳定 tag 推导,不要调用 releaser,不要用全仓库最新 tag。仅获构建授权时不要走会自动上传的目标。脚本含 `rm -rf` 时先确认为受限构建目录。若通过 `builder.<name>` 执行,先精确解析 `environment + host + project + path` 对应的 worktree;远程 binding 不能 fallback 到本机。持久 session 只显式 attach/resume,不能按标题复用旧 terminal。
|
||
4. DEB 上传前:对每个包 `verify_deb.sh <exact-package-path.deb> <version> <arch>`。多个包时不凭文件时间猜测。镜像轨道由 `publish_docker.sh` 自带远端 inspect。
|
||
5. 发布优先 `make -f makefile.builder push[-deb|-docker|-copy]`,或直接调 `upload_deb.sh` / `publish_docker.sh` / `copy_artifact.sh` / `obtain.sh`。`BUILD_VENUE=ci` 时 `push-docker` 就是 obtain。未指定 `ARCH=` 时 `push-deb` 上传清单里每一个 `.deb`。拷贝轨道至少配置 `COPY_DEST`(本地目录或 `container:/dir`)或 `COPY_SCRIPT`(项目内脚本优先在 `makefile.builder` 设置;同时配置时命令行/环境值优先)。自定义脚本按 `FILE [FILE ...]` 接收产物路径,自行完成重命名、上传、远端校验和通知;相对路径按项目根解析,`BUILDER_PROJECT_ROOT` 提供项目根。`COPY_AS` 只由内置 `COPY_DEST` 路径处理。脚本缺环境变量时加载 `.env.builder`(shell 显式值优先),不读 `.env`。不要把 token 当命令行参数;脚本可随项目放在 `.pouch/builder/` 下。多平台镜像只能走 `publish_docker.sh`,不能拆进 make;不要把项目架构清单写进 `.env.builder`。`build` 里禁止 `docker cp`。
|
||
6. 发布成功不能只看「curl/push 已执行」。要有退出码、HTTP 成功或远端 digest;索引异步时报告「上传已接受,索引尚待更新」。最终回复给出包名/镜像引用、版本、架构、SHA-256 或 digest、源 commit、工作区状态和未完成项。
|
||
|
||
## 拿到产物
|
||
|
||
调用方是 short-ship、long-ship、ACK(delivery-loop 的 `artifact_built`),或用户要看 CI 构建。
|
||
按 [obtain.md](references/obtain.md) 执行 `scripts/obtain.sh --sha <commit>`。
|
||
|
||
- `BUILD_VENUE=local`:当前 HEAD 必须是该 SHA,跑 makefile 的 docker/deb。
|
||
- `BUILD_VENUE=ci`:等该 SHA 的 GitLab/GitHub/Gitea 流水线,再 inspect `version.sh --docker` 的镜像 tag。不触发流水线,不本机 push。
|
||
- 失败(无流水线、job 失败、digest 不对)必须原样返回给调用方,不得标 `artifact_built`。
|
||
- 合进默认分支若项目不跑 CI,这是正确失败;预览用 `dev/*`,正式用 tag。
|