CNB hello-cnb 闯关全自动化复盘文档

CNB hello-cnb 闯关全自动化复盘文档

时间:2026-10-11 09:25 (UTC+8)
目标仓库:https://cnb.cool/cnb/tutorial/hello-cnb
验证机制:向该仓库提交 PR,其内置 CI(.cnb.yml include 的 hello-cnb-ci 各 level.yml)自动检查,8 条流水线全绿即通关,自动绑定「天才程序员」身份(个人设置 → 身份认证 自助领取 666 Credits/月)。

本文档记录从零到 8 条流水线全绿的完整可复现路径,所有操作均基于 API/HTTP 完成,无需打开浏览器。


0. 前置知识

  • API 网关:https://api.cnb.cool(OpenAPI,Bearer Token 认证,请求头必须带 Accept: application/vnd.cnb.api+json,否则部分 POST/DELETE 返回 406)
  • Swagger:https://api.cnb.cool/swagger.json(1.1MB,199 个路径,先拉下来通读一遍,很多任务能不能用 API 做取决于它)
  • Web 前端私有接口:https://cnb.cool/<path> 同源接口,需要浏览器 Cookie(CNBSESSION + csrfkey)+ 请求头 X-Csrftoken: <csrfkey值>
  • CNB CLI(可选辅助):npm i @cnbcool/cnb-cli,基于同一套 swagger,CNB_TOKEN 环境变量认证
  • Git 推拉认证:https://<username>:<token>@cnb.cool/<org>/<repo>.git

关键结论先行(避免走弯路):

能力 API token 能否做 说明
改签名 Bio 能 POST /api.cnb.cool/user
改用户名 不能直接改 需要 Web Cookie:POST <https://cnb.cool/user/rename_check/{name}> → POST <https://cnb.cool/user/rename/{name}>
昵称 谁都改不了 平台禁止,返回 403 Nickname cannot be changed
关注用户/关注仓库 不能直接改 需要 Web Cookie:PUT <https://cnb.cool/user/following/{username}、PUT> <https://cnb.cool/user/starred/{org}/{repo}>
仓库墙 Pin 需要 Web Cookie PUT <https://cnb.cool/user/pinned-repos,body> 为 ["org/repo"]
建仓库/建组织内资源 能 POST /{slug}/-/repos
保护分支 能 POST /{repo}/-/settings/branch-protections(body 必须全量给齐所有布尔字段,缺了报 400)
流水线 push/tag/PR 能 配好 .cnb.yml 后自动触发
web_trigger / tag_deploy API token 不行,Web Cookie 能 见 5.4 / 5.5
Docker 制品/知识库/NPC/任务集/工作空间 能 流水线或 API 完成

1. 准备阶段

# 1.1 拉 swagger,摸清能力边界
curl.exe -s <https://api.cnb.cool/swagger.json> -o swagger.json

# 1.2 验证 token
curl.exe -s -H "Authorization: Bearer <TOKEN>" <https://api.cnb.cool/user>

# 1.3 拉 CI 验证脚本(每关怎么验的,看了才知道往哪打)
curl.exe -s -o level1.yml <https://cnb.cool/cnb/tutorial/hello-cnb-ci/-/git/raw/main/level1.yml>
# level2~8 同理

通读 level*.yml 后得到的精确通关条件:

关 条件
L1 用户名非 cnb. + 11 位随机串;bio 非空;pinned 仓库 ≥1;follow_count ≥1;follow_repo_count ≥1
L2 源仓库有 ≥1 条保护分支规则;LICENSE 可识别(MIT 等);.cnb/settings.yml 含 workspace.launch.button 与 fork.button
L3 auto_trigger=true;push/pull_request/tag_push/web_trigger/tag_deploy 各有 ≥1 次 success 构建记录;存在 .cnb/tag_deploy.yml
L4 工作空间列表 ≥1;.cnb.yml 的 "$".vscode[].docker.image 非空;vscode service options 含 onlyPreview 与 launch
L5 list-packages --type docker total ≥1
L6 组织下任务集 ≥1
L7 repo flags 含 KnowledgeBase 与 NPC;仓库内有本人 author 的 commit
L8 以上 resolve key 全部 await 后跑 cnbcool/bind-genius

注意:仓库 README 里写的推荐关注对象与 CI 实际校验的名单不一致,且 CI 只看数量 ≥1,不用纠结具体关注谁。


2. 建闯关仓库(不用 Fork)

OpenAPI 没有 fork 接口,用「镜像 push」等效替代:

git clone <https://cnb.cool/cnb/tutorial/hello-cnb.git>
curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"name":"hello-cnb","visibility":"public","description":"CNB tutorial"}' `
  "<https://api.cnb.cool/><ORG>/-/repos"

cd hello-cnb
git push --mirror "<https://<user>:<token>@cnb.cool/><ORG>/hello-cnb.git"

要点:

  • 新建仓库 auto_trigger 默认已为 true(可用 GET /{repo}/-/settings/cloud-native-build 确认),任务 3.1 天然完成
  • mirror push 会带上上游的 tag,无副作用

3. 一次性写入全部配置(L2/L3/L4 的仓库文件部分)

在仓库根目录准备 4 个文件(完整示例见本文末尾附录):

  1. LICENSE — 标准 MIT 全文(2.2)
  2. .cnb/settings.yml — UI 定制 + NPC 角色(2.3 + 7.2 的角色定义部分)
  3. .cnb/tag_deploy.yml — 两个环境 development/staging(3.6)
  4. .cnb/web_trigger.yml — 一个按钮(3.5)
  5. .cnb.yml — 核心,见下

.cnb.yml 必须覆盖的事件(缺一个 L3 就红):

"$":
  vscode:            # L4.2/4.3:镜像 + options
    - docker:
        image: cnbcool/default-dev-env:latest
      services:
        - docker
        - name: vscode
          options:
            onlyPreview: true
            launch: python3 -m http.server 8686
            daemon: true
            keepAliveTimeout: 3600000
  web_trigger:       # L3.5
    - stages:
        - name: manual trigger ok
          script: echo ok

main:
  push:              # L3.2 + L7.1 知识库 + L5 Docker 制品
    - stages:
        - name: build knowledge base
          type: knowledge:update
          options: { include: "**/**.md" }
    - name: docker build & push
      services: [docker]
      stages:
        - name: docker image
          script: |
            docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}/hello:latest .
            docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}/hello:latest
  pull_request:      # L3.3
    - stages:
        - name: pr ok
          script: echo ok

"v*":                # L3.4:tag_push 挂在 tag 名模式下,不是分支名下!
  tag_push:
    - stages:
        - name: tag ok
          script: echo ok
  tag_deploy.development:   # L3.6
    - stages:
        - name: deploy dev
          script: echo ok
  tag_deploy.staging:
    - stages:
        - name: deploy staging
          script: echo ok

踩坑记录(全部实测撞过):

  • pull_request 必须挂在目标分支名(main)下面,挂顶层不触发
  • tag_push/tag_deploy 必须挂在 tag 名 glob("v*")下面,挂在 main 下不触发
  • vscode 镜像用 cnbcool/default-dev-env:latest;cnbcool/default 与 default-dev 不存在
  • onlyPreview: true 时 launch 必须真监听 8686 端口且要 daemon: true,否则 Prepare 超时报错
  • docker 构建用 services: [docker],普通镜像里没有 docker 命令
  • 知识库(L7.1)就是靠 push 流水线里的 knowledge:update 内置任务开启的,跑完一次 repo flags 自动变 KnowledgeBase;NPC(7.2)靠在 settings.yml 定义角色 + 在 Issue 里 @ 一次 NPC,跑完 flags 变 NPC(延迟约 1 分钟)

push 后逐项验证:

# 构建记录
curl.exe -s -H "Authorization: Bearer $t" "<https://api.cnb.cool/><ORG>/hello-cnb/-/build/logs?page_size=20"
# 单条构建各 stage 状态
curl.exe -s -H "Authorization: Bearer $t" "<https://api.cnb.cool/><ORG>/hello-cnb/-/build/status/<SN>"
# stage 日志(排障用)
curl.exe -s -H "Authorization: Bearer $t" "<https://api.cnb.cool/><ORG>/hello-cnb/-/build/logs/stage/<SN>/<PIPELINE_ID>/prepare"
# docker 制品(npm CLI)
npx @cnbcool/cnb-cli registries list-packages --slug "<ORG>/hello-cnb" --type docker --verbose

4. 纯 API 能搞定的设置项

4.1 签名(L1.3)

curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"bio":"..."}' <https://api.cnb.cool/user>

4.2 保护分支(L2.1)

body 必须给齐全部字段,只给 rule 会 400:

curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"rule":"main","allow_creation":false,"allow_deletions":false,"allow_force_pushes":false,"allow_master_creation":true,"allow_master_deletions":true,"allow_master_force_pushes":true,"allow_master_manual_merge":true,"allow_master_pushes":true,"allow_pushes":false,"required_approved_review_count":1,"required_approved_review_ratio":1,"required_linear_history":false,"required_master_approve":false,"required_must_auto_merge":false,"required_must_push_via_pull_request":false,"required_pull_request_reviews":false,"required_status_checks":false}' `
  "<https://api.cnb.cool/><ORG>/hello-cnb/-/settings/branch-protections"

4.3 任务集(L6)

curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"name":"dev-plan","description":"...","visibility":"public","repos":["<ORG>/hello-cnb"]}' `
  "<https://api.cnb.cool/><ORG>/-/missions"

4.4 NPC(L7.2)

settings.yml 定义角色 + push 后,建 Issue @ 自己的 NPC:

curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"title":"...","body":"@<ORG>/hello-cnb(expert) hi"}' `
  "<https://api.cnb.cool/><ORG>/hello-cnb/-/issues"
# 约 1 分钟后 GET /{repo} 的 flags 应含 NPC

4.5 个人 commit(L7.3)

正常 git push 即可(git 认证用 https://<user>:<token>@cnb.cool/...),author 用账号默认 noreply 邮箱。


要两条东西:浏览器里的 CNBSESSION Cookie 值和 csrfkey 值。前端 JS(_next/static/chunks/pages/_app.js)里能看到 axios baseURL 就是同源根路径,接口路径可从各页面 chunk 里 grep。

请求模板(CSRF 头必须带,否则可能 401):

$ck = "CNBSESSION=<session值>; csrfkey=<csrfkey值>"
curl.exe -s -X PUT -H "Cookie: $ck" -H "X-Csrftoken: <csrfkey值>" `
  -H "Accept: application/vnd.cnb.api+json" "<URL>"

5.1 改用户名(L1.1)

# 先查占用
POST <https://cnb.cool/user/rename_check/><新名字>     # 返回 {"result":true,...} 即可用
# 再改名
POST <https://cnb.cool/user/rename/><新名字>           # 200 即成功,token 不失效

5.2 关注用户(L1.5)

PUT <https://cnb.cool/user/following/><username>       # 200 空体即成功

5.3 Star 仓库 = 关注仓库(L1.6)

PUT <https://cnb.cool/user/starred/><org>/<repo>       # 200 即成功,follow_repo_count +1

5.4 仓库墙 Pin(L1.4)

PUT <https://cnb.cool/user/pinned-repos>
Content-Type: application/json
body: ["<ORG>/hello-cnb"]

5.5 web_trigger 手动触发(L3.5)

# 拿按钮 id(yml 里配置的按钮,id 形如 "0-0")
GET <https://cnb.cool/><ORG>/hello-cnb/-/build/web-trigger/config?refs=main

# 触发(注意 body 必须是合法 JSON,建议写临时文件避免 shell 转义/BOM 问题)
POST <https://cnb.cool/><ORG>/hello-cnb/-/build/start/web-trigger
body: {"ref":"main","env":{},"event":"web_trigger","id":"0-0","customTitle":"api trigger"}

5.6 tag_deploy 部署(L3.6)

# deployList 查询:ref 必须带 refs/tags/ 前缀(不带前缀报 DEPLOY_TYPE_ERROR)
GET <https://cnb.cool/><ORG>/hello-cnb/-/build/deploy/deploy-config?ref=refs/tags/v0.2.1

# 触发部署
POST <https://cnb.cool/><ORG>/hello-cnb/-/build/start/deploy
body: {"ref":"refs/tags/v0.2.1","environmentName":"development","sync":false}

踩坑:tag 指向的 commit 的 .cnb.yml 里必须有 tag_deploy.<环境名> 事件配置,且配置需先随 tag push 上去,否则构建报 CI config file not found。

5.7 云原生开发工作空间(L4.1,token 也能开)

POST <https://api.cnb.cool/><ORG>/hello-cnb/-/workspace/start
body: {"slug":"<ORG>/hello-cnb","branch":"main"}

失败会留 pending/error 记录,可用 POST /{repo}/-/build/stop/<SN> 停掉再重开。


6. 提交上游 PR 并让 CI 全绿

  1. 在闯关仓库建一个分支,加一个无关紧要的文件(如 hello.txt),push
  2. 跨仓 PR 用 API 直接建(不需要 fork 关系):
curl.exe -s -X POST -H "Authorization: Bearer $t" -H "Content-Type: application/json" `
  -H "Accept: application/vnd.cnb.api+json" `
  --data-raw '{"title":"天才程序员来报道!","head":"<分支名>","head_repo":"<ORG>/hello-cnb","base":"main","body":"..."}' `
  "<https://api.cnb.cool/cnb/tutorial/hello-cnb/-/pulls>"
  1. 查 CI 结果:
curl.exe -s -H "Authorization: Bearer $t" -H "Accept: application/vnd.cnb.api+json" `
  "<https://api.cnb.cool/cnb/tutorial/hello-cnb/-/pulls/><PR号>/commit-statuses"
  1. 重要:源分支后续 push 不会自动重跑上游 CI。需要重跑时,关闭再重开 PR(PATCH /pulls/<n> body {"state":"closed"} → {"state":"open"}),reopened 事件会触发 pull_request.target 流水线
  2. L1 的检查项全部就绪后重跑,8 条全绿,bind-genius 自动绑定身份

7. 多账号批量复现清单

对每个新账号,按顺序执行(约 15~20 分钟/个):

  • GET /user 验 token,记录 username
  • 镜像 push 建 <ORG>/hello-cnb
  • 写入 LICENSE、.cnb.yml、.cnb/settings.yml、.cnb/tag_deploy.yml、.cnb/web_trigger.yml,push main
  • 等 push 流水线跑完(KB+Docker),确认 flags=KnowledgeBase、docker 包存在
  • API:改 bio、建保护分支、建任务集
  • 建 Issue @ NPC,等 flags=KnowledgeBase,NPC
  • API:开工作空间(失败则 stop 后重试)
  • Web Cookie:改用户名 → 关注 2~3 人 → star 2 个仓库 → pin 仓库
  • 建 v* tag push(触发 tag_push)
  • Web Cookie:web-trigger 按钮(L3.5)、start/deploy(L3.6)
  • 建分支 hello.txt,push,API 建上游 PR
  • 查 commit-statuses,不绿则关闭重开 PR;全绿收工

附录 A:.cnb/settings.yml 完整示例

npc:
  roles:
    - name: expert
      slogan: Tutorial assistant
      prompt: |
        You are 'expert', a concise technical assistant for this CNB tutorial repo.

workspace:
  launch:
    button:
      name: Start Coding
      description: Launch cloud dev environment
      hover:
        - image: <https://cnb.cool/cnb/tutorial/hello-cnb/-/git/raw/main/assets/banner.svg>
        - title: Cloud Native Dev
          description: Full dev environment in browser
fork:
  button:
    name: Fork me
    description: Fork this tutorial repo
    hover:
      - image: <https://cnb.cool/cnb/tutorial/hello-cnb/-/git/raw/main/assets/banner.svg>
      - title: Hello CNB
        description: CNB onboarding tutorial

附录 B:.cnb/tag_deploy.yml

environments:
  - name: development
    description: Development environment
    env:
      name: development
      tag_name: $CNB_BRANCH
  - name: staging
    description: Staging environment
    env:
      name: staging
      tag_name: $CNB_BRANCH

附录 C:.cnb/web_trigger.yml

branch:
  - buttons:
      - name: Manual Build
        description: Trigger manual web_trigger pipeline
        event: web_trigger

附录 D:经验性结论

  • swagger.json 是唯一权威,OpenAPI 文档页只是入口
  • 前端私有接口的路径都在 Next.js 页面 chunk 里,_app.js + 对应页面 chunk grep 即可还原全部 Web API
  • 请求头缺 Accept: application/vnd.cnb.api+json 时 POST/DELETE 会 406(GET 不挑)
  • PowerShell 传 JSON body 建议 InFile(UTF8 无 BOM),-data-raw 的引号转义在 cmd/PS 下极易出错
  • 构建状态排障三板斧:build/logs 列表 → build/status/<SN> → build/logs/stage/<SN>/<PID>/<STAGE>
  • 删仓库接口被组织管理策略挡(root group management rules),需要网页操作
  • token 粒度:改用户资料需要 account-profile:rw,仓库设置需要 repo-manage:rw,给 token 勾权限时按需给

欢迎指出任何有错误或不够清晰的表达,可以在下面评论区评论。

赏

×

喜欢就点赞,疼爱就打赏

//