Files
.pouch/skills/builder/SKILL.md
T
laily 681aa9e237 feat(builder): load publish credentials from .env.builder
Keep DEB/Docker publish keys out of the project's .env. Scripts and
check.py --ready only read .env.builder; empty values count as missing.
2026-08-25 16:58:56 +08:00

206 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: builder
description: >-
初始化或检查项目是否满足 DEB/Docker 构建发布契约,再按契约构建并发布:
先校验 makefile.buildercheck.py),再 make -f makefile.builder 构建产物,
经授权后用 skill 自带脚本上传并验证。触发词:初始化 builder、接入 builder、
检查 makefile.builder、构建 deb、发布 deb、上传 deb、推送 apt 仓库、打 Debian
包、构建镜像、发布镜像、推送 Docker 镜像、make push。仅分析打包逻辑或只构建
不上传时也可使用;不会在未获授权时执行任何上传。Docker 轨道保持显式触发:
用户点名(builder/publish docker)时才走镜像发布。
---
# BuilderDEB / Docker 构建发布
复用项目已有发布约定,安全地完成"校验 → 构建 → 检查 → 授权 → 上传 → 验证"。
分工原则:**make 管构建,skill 脚本管发布,本 SKILL.md 只留脚本做不了的决策。**
项目状态是根目录 `makefile.builder` 与发布用 `.env.builder`,不要创建
`.pouch/builder/`,不要改用户的 `Makefile` / `makefile` / `.env`
开始时解析当前 `SKILL.md` 所在目录,记为 `<skill-dir>`。优先
`git rev-parse --show-toplevel` 解析项目根。
## 选择模式
- 用户要求初始化、接入 builder,或新项目还没有 `makefile.builder`:执行“初始化”。
- 用户要求检查 builder 契约或发布配置是否齐全:执行“检查”。
- 用户要求构建、发布、上传:执行“工作流”。不要静默初始化。
## 何时使用
- 用户要求初始化或接入 builder。
- 用户要求构建、发布、上传 `.deb` 包或 Docker/OCI 镜像。
- 用户要求检查 `makefile.builder` 是否符合 builder 契约。
- 用户要求梳理或接通项目现有的 DEB/镜像发布流程。
不适用:本地安装/卸载 DEB;RPM/APK/语言包管理器;从零设计全新打包体系(先出方案);
普通编码与 Dockerfile 编辑。
## 初始化
1. 确认项目根。探测 `makefile.builder``.env.builder`、用户 `Makefile`/`makefile`
(只当抄 build 配方的证据,不改)、`Dockerfile``debian/`、语言清单。
`.env.builder` 只看键是否存在且非空,不读、不打印值。不要读取用户 `.env`
2. 判定轨道:有 Dockerfile → docker;有 deb 信号或用户要打 deb → deb;都不清则问。
不要猜测 registry、token 或仓库名。
3. 没有 `makefile.builder`:把 `<skill-dir>/templates/makefile.builder` 拷到项目根。
按轨道删掉未使用的 deb/docker/push* 段,把 `build` 的 TODO 换成仓库里已有的
真实编译命令(可从用户 Makefile 抄配方,但不要 `include` 或递归调用它)。
`include` builder 的 `scripts/version.mk`。双产物把 `push` 改成
`push: push-deb push-docker`。不要改用户的 `Makefile` / `makefile`
4. 已有 `makefile.builder`:跑检查;按 FAIL 给出修补说明。不覆盖该文件,除非
用户明确要求按契约改。不要调用 create-makefile(其版本规则与本契约冲突)。
5. 没有 `.env.builder`:把 `<skill-dir>/templates/env.builder` 拷到项目根为
`.env.builder`(注释键,不含值)。不要改、不要读取用户 `.env`。缺发布键时在
报告里给出可粘贴示例,并说明把 `.env.builder` 加入 `.gitignore`,不要提交。
6. 运行:
```bash
python3 -I -S <skill-dir>/scripts/check.py <project-dir> --ready
```
7. 按下面格式报告。结构校验通过且当前轨道能构建时才能称「完成」;只缺发布
键是「部分完成」(可构建,不可发布)。契约 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
```
## 检查
只读。运行 `check.py <project-dir> --ready`,用同一报告格式,标题改为
`## builder 检查:…`。不写 `makefile.builder` / `.env.builder`,不改用户 Makefile
或 `.env`。用户明确要求修复后再转入初始化。
## 工作流
### 0. 校验契约
```bash
python3 -I -S <skill-dir>/scripts/check.py <project-dir> # 静态检查
python3 -I -S <skill-dir>/scripts/check.py <project-dir> --ready # 含工具链与发布键
python3 -I -S <skill-dir>/scripts/check.py <project-dir> --build # 额外实构 deb 并核对产物
```
契约 FAIL 或轨道工具缺失:停下,转入「初始化」按契约补齐 `makefile.builder`
不要绕过校验继续发布,不要改用户 Makefile。只缺发布键:允许构建,禁止上传。
完整要求见 [contract.md](references/contract.md)。存量项目未接契约时走
「存量项目 fallback」;成功交付一次后引导用户迁到 `makefile.builder`。
### 1. 确认发布边界
上传是外部写操作。仅当用户明确要求发布、上传或提交时执行;只要求查看、诊断或构建
则停在相应阶段。
执行上传前确认:
- 目标服务和仓库来自项目配置(`.env.builder`)或用户输入,不猜测生产端点。
- 认证令牌已通过环境变量或密钥系统提供;绝不写入命令输出、文件、提交或回复,
不用 `set -x` 执行含凭据的命令。
- 相同版本是否允许覆盖;无法确认且可能覆盖时,先询问。
- Docker 轨道需要已确定 registry/repositorytag 未给出时按契约「版本号」推导。
脏工作树默认拒绝发布;用户明确接受时设置 `ALLOW_UNCOMMITTED=1` 并在汇报中注明
包含的未提交修改。
### 2. 构建
```bash
make -f makefile.builder build ARCH=<amd64|arm64> VERSION=<version> # 主产物
make -f makefile.builder deb ARCH=<amd64|arm64> # DEB 项目
```
版本缺省按契约「版本号」从 Git 祖先稳定 tag 推导(正式 = HEAD exact-match
的 `vX.Y.Z`;测试 = `X.Y.Z~分支.距离+gSHA`)。不要调用 manage-release 来算
产物版本,不要用全仓库最新 tag。构建目标若会自动上传而当前仅获构建授权,改用
纯构建目标。执行前确认所需工具可用(docker、dpkg-deb 等)。不得擅自清理宽泛
目录;脚本含 `rm -rf` 时先解析确认为受限构建目录。
### 3. 上传前检查
```bash
find $(DIST_DIR) -maxdepth 2 -type f -name '*.deb' -print
<skill-dir>/scripts/verify_deb.sh <exact-package-path.deb> [期望版本] [期望架构]
```
verify_deb.sh 输出元数据、关键内容清单和 SHA-256。匹配到多个包时不凭文件时间猜测,
向用户确认唯一产物。镜像轨道无需单独校验步骤(publish_docker.sh 自带远端 inspect)。
### 4. 发布
优先 `make -f makefile.builder push[-deb|-docker]`(契约要求的薄包装);直接调用等价:
```bash
DEB_SERVER_URL=… DEB_TOKEN=… DEB_REPOSITORY=… \
<skill-dir>/scripts/upload_deb.sh <exact-package-path.deb>
DOCKER_REGISTRY=… \
<skill-dir>/scripts/publish_docker.sh # env 优先,flag 可覆盖
```
环境变量缺失时脚本会加载项目 `.env.builder`shell 显式值优先),不读 `.env`。不把 token
作为命令行参数;不把脚本复制进项目。upload_deb.sh 默认请求 `/api/v2/upload/package`
multipart 字段 `package`/`token`/`repository_name`,接受 200/201),协议不符时设
`DEB_UPLOAD_PATH` 或改用项目专属逻辑。publish_docker.sh 用 buildx 一步完成构建+推送,
多平台只能走它,不能拆进 make。
### 5. 验证与汇报
发布成功不能只依据"curl 已执行"/"push 已执行"。综合检查:
- 上传命令退出码为零,HTTP 状态与响应体明确成功;镜像以 `imagetools inspect`
的远端 digest 为准。
- 若仓库提供查询/索引/下载地址,确认该版本已可见;索引异步时报告
"上传已接受,索引尚待更新",不声称完全可用。
最终回复给出:包名/镜像引用、版本、架构/platform、产物路径与 SHA-256 或远端 digest、
源 commit 与工作区状态、各阶段验证结果、未完成项或覆盖风险。
## 存量项目 fallbacklegacy
从项目根目录查找,不预设文件位置:
```bash
rg -n -i --hidden --glob '!.git' \
'build-deb|upload-deb|publish-deb|dpkg-deb|debuild|curl.*deb|\.deb\b|aptly|reprepro'
```
重点检查用户 Makefile、CI 配置、`debian/`、构建脚本和发布文档中的入口、变量传递方式、
端点与认证方式。优先复用已有构建入口;上传仍用 builder 脚本。交付后引导迁移到
`makefile.builder``templates/makefile.builder` + `check.py` 通过为准)。
## 修改 builder 自身时
- 上传/发布脚本是 SSOT:通用行为修改落在 `skills/builder/scripts/`,不同步复制到
业务项目。产物版本只通过 `scripts/version.sh` 推导,不要在 `makefile.builder` 内联
`git describe` 或 `sort -V`。
- 契约变更先改 `scripts/check.py`,再同步 `references/contract.md`、
`templates/makefile.builder` 与 `templates/env.builder`。
- 可用 `bash -n` 检查脚本语法;有 ShellCheck 时一并运行。
- 不通过真实生产上传测试脚本,除非用户明确授权并给出测试版本/仓库。
## 完成标准
- 初始化/检查:报告为完成、部分完成或阻塞;待配置项含文件、字段和示例。
- 仅分析:入口、调用链、配置来源和风险已被准确说明。
- 仅校验:check.py 结果逐条可解释,修复建议明确。
- 仅构建:产物已生成并通过 verify_deb.sh,未发生上传。
- 发布:构建检查通过,服务端接受上传,仓库可见性已验证或准确标记为待更新。