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

9.9 KiB
Raw Blame History

name, description
name description
builder 初始化或检查项目是否满足 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 配方的证据,不改)、Dockerfiledebian/、语言清单。 .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. 运行:

    python3 -I -S <skill-dir>/scripts/check.py <project-dir> --ready
    
  7. 按下面格式报告。结构校验通过且当前轨道能构建时才能称「完成」;只缺发布 键是「部分完成」(可构建,不可发布)。契约 FAIL 或轨道工具缺失是「阻塞」。 除非用户明确要求,不提交、不推送、不上传。

## builder 初始化:完成 | 部分完成 | 阻塞

已具备: …
待配置: 路径 + 字段 + 可粘贴示例 + 缺了会挡住哪步
工具链: make / docker / dpkg-deb(缺则怎么装,不擅自安装)
下一步: 一句话

发布键示例(只示范键名):

# .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. 校验契约

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。存量项目未接契约时走 「存量项目 fallback」;成功交付一次后引导用户迁到 makefile.builder

1. 确认发布边界

上传是外部写操作。仅当用户明确要求发布、上传或提交时执行;只要求查看、诊断或构建 则停在相应阶段。

执行上传前确认:

  • 目标服务和仓库来自项目配置(.env.builder)或用户输入,不猜测生产端点。
  • 认证令牌已通过环境变量或密钥系统提供;绝不写入命令输出、文件、提交或回复, 不用 set -x 执行含凭据的命令。
  • 相同版本是否允许覆盖;无法确认且可能覆盖时,先询问。
  • Docker 轨道需要已确定 registry/repositorytag 未给出时按契约「版本号」推导。

脏工作树默认拒绝发布;用户明确接受时设置 ALLOW_UNCOMMITTED=1 并在汇报中注明 包含的未提交修改。

2. 构建

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. 上传前检查

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](契约要求的薄包装);直接调用等价:

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.buildershell 显式值优先),不读 .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

从项目根目录查找,不预设文件位置:

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.buildertemplates/makefile.builder + check.py 通过为准)。

修改 builder 自身时

  • 上传/发布脚本是 SSOT:通用行为修改落在 skills/builder/scripts/,不同步复制到 业务项目。产物版本只通过 scripts/version.sh 推导,不要在 makefile.builder 内联 git describesort -V
  • 契约变更先改 scripts/check.py,再同步 references/contract.mdtemplates/makefile.buildertemplates/env.builder
  • 可用 bash -n 检查脚本语法;有 ShellCheck 时一并运行。
  • 不通过真实生产上传测试脚本,除非用户明确授权并给出测试版本/仓库。

完成标准

  • 初始化/检查:报告为完成、部分完成或阻塞;待配置项含文件、字段和示例。
  • 仅分析:入口、调用链、配置来源和风险已被准确说明。
  • 仅校验:check.py 结果逐条可解释,修复建议明确。
  • 仅构建:产物已生成并通过 verify_deb.sh,未发生上传。
  • 发布:构建检查通过,服务端接受上传,仓库可见性已验证或准确标记为待更新。