Files
openless/.github/workflows/claude.yml
T
TRIPandbaiqing fe56eb3038 fix(ci): detach HEAD before claude-code-action on fork PR (#464)
PR #451 (来自 fork aeoform/openless, head ref 也叫 beta) 触发 @claude 时,
claude-code-action 执行 `git fetch origin pull/451/head:beta` 把 PR head
拉到本地 beta 分支,但此时 worktree 正 checkout 在 refs/heads/beta,
git 拒绝 fetch 到已 checkout 的分支:

    fatal: refusing to fetch into branch 'refs/heads/beta' checked out at ...
    Action failed with error: Command failed: git fetch origin --depth=20 pull/451/head:beta

修复: 在 actions/checkout 后立即 git checkout --detach,释放
refs/heads/<default-branch> 这个本地分支名,让 action 自己 fetch 不撞名.
仅在 fork head ref == base ref name 的 corner case 才会触发问题,
detach 对其他场景无副作用.

失败 run: https://github.com/Open-Less/openless/actions/runs/25978532215

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-17 14:09:58 +08:00

81 lines
3.8 KiB
YAML
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: Claude Code
# 触发策略:
# - 默认不主动 review;任何 PR 打开 / 同步都不会自动调用模型,避免烧 OAuth token 额度。
# - 评论 / review / issue 中出现 `@claude` 才触发,且发起者必须是 Open-Less 组织成员(OWNER 或 MEMBER)。
# - 模型默认 claude-sonnet-4-6(量大、成本低);评论里写 `--opus` 或包含 `claude-opus`
# 字样会切到 claude-opus-4-7(用于需要更深推理的任务)。
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
# 双重门禁:(1) 内容含 @claude (2) 触发者是 OWNER 或 MEMBER(Open-Less 组织成员)。
# 注:仓库已转入 Open-Less 组织后,author_association 对人类用户最高只会是 MEMBER,
# OWNER 此时只对个人账号下的同名仓库有效,这里保留是为了兼容仓库再次个人持有的情形。
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER","MEMBER"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER","MEMBER"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJson('["OWNER","MEMBER"]'), github.event.review.author_association)) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJson('["OWNER","MEMBER"]'), github.event.issue.author_association))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
# Detach HEAD 释放 refs/heads/<default-branch> 这个本地分支名。
# 背景:claude-code-action 在 fork PR 上会执行
# git fetch origin pull/<n>/head:<head-ref-name>
# 把 PR head 拉到与 fork 端 head 同名的本地分支。当 fork PR 的 head ref
# 与本仓库 base / 默认分支同名(例如 fork 也是 beta → beta)时,
# 上面那条 fetch 会撞上"当前已 checkout 的分支"而失败:
# fatal: refusing to fetch into branch 'refs/heads/beta' checked out at ...
# 提前 detach 让本地分支名可以被 action 重新使用。
- name: Detach HEAD to free local branch ref
run: git checkout --detach
- name: Pick model (default sonnet, opt-in opus)
id: pick_model
env:
COMMENT_BODY: ${{ github.event.comment.body }}
REVIEW_BODY: ${{ github.event.review.body }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_TITLE: ${{ github.event.issue.title }}
run: |
set -eu
body="${COMMENT_BODY}${REVIEW_BODY}${ISSUE_BODY}${ISSUE_TITLE}"
if [[ "$body" == *"--opus"* ]] || [[ "$body" == *"claude-opus"* ]]; then
echo "model=claude-opus-4-7" >> "$GITHUB_OUTPUT"
else
echo "model=claude-sonnet-4-6" >> "$GITHUB_OUTPUT"
fi
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# 让 Claude 能看 CI 结果
additional_permissions: |
actions: read
# 模型策略:默认 sonnet,评论里 --opus 才升级到 opus
claude_args: '--model ${{ steps.pick_model.outputs.model }}'