mirror of
https://github.com/Tencent/teamai-cli.git
synced 2026-10-02 03:14:40 +08:00
Follow-up to #210. The MR-extract pipeline still failed at `teamai init`: a git.woa.com Personal Access Token authenticates git-over-HTTPS only with the username `private:` (an OAuth token uses `oauth2:`). The CLI hardcoded `oauth2:` and routed two-segment repos to `gf repo clone`, whose own API lookup can't use a PAT — so the existing knowledge repo was misread as "does not exist", then create failed with 400 "Path has already been taken". Verified live against git.woa.com. Changes: - rest-auth.ts: add tgitGitUser(scheme) (PAT→'private', OAuth→'oauth2') and tryGetTGitToken() (non-throwing token resolver). - gf-cli.ts gfRepoClone: when a token is available, clone every repo via `git clone https://<user>:<token>@…` with the scheme-derived username; fall back to `gf repo clone` only when no token exists (interactive path, unchanged). Sanitizer redacts both oauth2: and private:. - clone.ts: use the scheme-based username instead of hardcoded oauth2:. - init.ts: a "repo already exists" create error is no longer fatal — it falls through to retry the clone. - Tests for tgitGitUser and tryGetTGitToken. CI example (examples/ci/coding-ci-mr-extract.yaml), validated end-to-end against a live ZhiYan pipeline: - comment stage no longer runs `teamai init` (comment mode only fetches the MR and posts via REST — no team-repo clone, and init's member registration needs an interactive TTY unavailable in CI). - post-merge stage drops the redundant manual git config/commit/push block: `teamai ci extract-mr --write-mode direct` already commits and pushes with the git identity derived from TGIT_TOKEN's account (REST /user), which satisfies TGit's committer-check. The hardcoded `teamai-ci` committer was rejected. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
105 lines
4.9 KiB
YAML
105 lines
4.9 KiB
YAML
# TeamAI MR Knowledge Extract — 智研 / Coding CI(TGit / 工蜂)
|
||
#
|
||
# 在 MR 创建/更新时自动提炼知识建议并以 comment 贴到 MR 上;
|
||
# MR 合入后自动将 learning、codebase、图谱建议写入团队知识仓库。
|
||
#
|
||
# 使用前请配置:
|
||
# 1. 在智研 Web 端新建一条流水线:绑定本工蜂仓库 → CIfile 指向本文件路径 →
|
||
# 触发方式勾选 MR。注意:MR 触发规则**必须**在本 YAML 的 `mr:` 块声明,
|
||
# 仅在智研 UI 勾选无效。
|
||
# 2. Pipeline Secret:
|
||
# - TGIT_TOKEN:对团队知识仓库有 push 权限的 TGit Personal Access Token
|
||
# - ANTHROPIC_AUTH_TOKEN:AI 认证 Token
|
||
# 说明:teamai ci extract-mr 复用了 AI 提炼逻辑(callClaude),comment 与
|
||
# write 两种模式都会 spawn 本地 AI CLI,因此 AI CLI 与凭证是**必须**的,不是可选。
|
||
# 3. 把下方 env 中的占位符改成你的实际值:
|
||
# - TEAMAI_KNOWLEDGE_REPO 团队知识仓库路径(如 myteam/knowledge)
|
||
# - ANTHROPIC_BASE_URL AI 网关地址(如 https://api.anthropic.com)
|
||
|
||
version: 2
|
||
|
||
# ── MR 触发规则(必须在 YAML 中声明,UI 配置无效)────────────
|
||
mr:
|
||
action:
|
||
- open
|
||
- push-update
|
||
- merge
|
||
is_local_mr: true
|
||
is_block_mr: true
|
||
auto_cancel_same_merge_request: true
|
||
|
||
# ── 密钥与环境变量 ────────────────────────────────────────────
|
||
env:
|
||
TGIT_TOKEN:
|
||
secret: ${TGIT_TOKEN_SECRET}
|
||
ANTHROPIC_AUTH_TOKEN:
|
||
secret: ${ANTHROPIC_AUTH_TOKEN_SECRET}
|
||
TEAMAI_KNOWLEDGE_REPO: # 团队知识仓库路径(如 myteam/knowledge)
|
||
TEAMAI_KNOWLEDGE_BRANCH: main # 知识仓库默认分支
|
||
ANTHROPIC_BASE_URL: # AI API 基础地址(如 https://api.anthropic.com)
|
||
ANTHROPIC_DEFAULT_SONNET_MODEL: claude-sonnet-4-6
|
||
ANTHROPIC_DEFAULT_HAIKU_MODEL: claude-haiku-4-5
|
||
ANTHROPIC_DEFAULT_OPUS_MODEL: claude-opus-4-8
|
||
|
||
# ── 流水线阶段 ────────────────────────────────────────────────
|
||
stages:
|
||
|
||
# ── MR 创建/更新时:提炼知识并以 comment 形式展示 ──────────
|
||
- stage: teamai-extract-comment
|
||
tasks:
|
||
- task: extract-and-comment
|
||
cmds:
|
||
- plugin: cmds
|
||
params:
|
||
cmds:
|
||
- echo "=== [TeamAI] Installing CLI tools ==="
|
||
# 公网环境:npm 安装;内网无公网 npm 时改为本地 tarball,如:
|
||
# npm install -g ./teamai-cli-<version>.tgz @anthropic-ai/claude-code
|
||
- npm install -g teamai-cli @anthropic-ai/claude-code 2>&1 | tail -3
|
||
- |
|
||
echo "machine git.woa.com login private password ${TGIT_TOKEN}" > ~/.netrc
|
||
chmod 600 ~/.netrc
|
||
echo "=== [TeamAI] TGit auth configured ==="
|
||
# comment 模式仅通过 REST 拉取 MR 并回帖,无需克隆团队知识仓库,
|
||
# 因此不运行 `teamai init`(它需要交互式成员注册,在 CI 中不可用)。
|
||
- |
|
||
echo "=== [TeamAI] Trigger: ${QCI_TRIGGER_TYPE}, MR IID: ${QCI_MR_IID:-none} ==="
|
||
if [ "${QCI_TRIGGER_TYPE}" = "TRIGGER_MR" ] && [ -n "${QCI_MR_IID}" ] && [ "${QCI_MR_IID}" != "None" ]; then
|
||
MR_URL="${QCI_REPO%.git}/merge_requests/${QCI_MR_IID}"
|
||
else
|
||
echo "⏭ Not an MR trigger, skipping"
|
||
exit 0
|
||
fi
|
||
echo "=== [TeamAI] MR_URL=$MR_URL ==="
|
||
teamai ci extract-mr --url "$MR_URL" --mode comment --individual-comments
|
||
|
||
# ── MR 合入后:将知识写入团队知识仓库 ─────────────────────
|
||
- stage: teamai-post-merge-write
|
||
tasks:
|
||
- task: write-knowledge
|
||
cmds:
|
||
- plugin: cmds
|
||
params:
|
||
cmds:
|
||
- npm install -g teamai-cli @anthropic-ai/claude-code 2>&1 | tail -3
|
||
- |
|
||
if [ "${QCI_TRIGGER_TYPE}" != "TRIGGER_MR" ] || [ "${QCI_MR_ACTION}" != "merge" ]; then
|
||
echo "=== [TeamAI] SKIP: Not a merge event ==="
|
||
exit 0
|
||
fi
|
||
MR_URL="${QCI_REPO%.git}/merge_requests/${QCI_MR_IID}"
|
||
echo "=== [TeamAI] Writing knowledge for $MR_URL ==="
|
||
# 用 PAT 克隆团队知识仓库(PAT 的 git 用户名为 `private`)。
|
||
git clone -b "${TEAMAI_KNOWLEDGE_BRANCH}" "https://private:${TGIT_TOKEN}@git.woa.com/${TEAMAI_KNOWLEDGE_REPO}.git" team-repo
|
||
# --write-mode direct 让 CLI 自行 commit 并 push:git 身份由 TGIT_TOKEN
|
||
# 对应账号(REST /user)推导,满足工蜂 committer-check。无需手动 git config/commit/push。
|
||
teamai ci extract-mr --url "$MR_URL" --mode write --individual-comments --team-repo ./team-repo --write-mode direct
|
||
|
||
worker:
|
||
label: JOB_MATRIX_DEVCLOUD
|
||
tools: []
|
||
language: node_js-22.19.0
|
||
|
||
maximum_builds: 2
|
||
is_auto_cancel: false
|