Skip to content

Add WakaTime configuration to workflow #6

Add WakaTime configuration to workflow

Add WakaTime configuration to workflow #6

name: LLM Bot Runner
on:
workflow_dispatch:
inputs:
task:
description: 'LLM的任务描述'
required: true
type: string
context:
description: '任务的JSON上下文'
required: true
type: string
repository_dispatch:
types: [llm-task]
jobs:
prepare-context:
runs-on: ubuntu-latest
permissions:
issues: write
outputs:
issue_number: ${{ steps.prepare-context.outputs.issue_number }}
task_content: ${{ steps.prepare-context.outputs.task_content }}
steps:
- name: Prepare context
id: prepare-context
env:
GH_TOKEN: ${{ github.token }}
TASK_CONTENT: ${{ github.event.client_payload.task || inputs.task }}
CONTEXT_RAW: ${{ github.event.client_payload.context || inputs.context }}
ISSUE_NUMBER_FROM_PAYLOAD: ${{ github.event.client_payload.issue_number }}
GITHUB_RUN_ID: ${{ github.run_id }}
GITHUB_REPOSITORY: ${{ github.repository }}
EVENT_TYPE: ${{ github.event_name }}
run: |
echo "Event type: $EVENT_TYPE"
# 1. 从 repository_dispatch 或 workflow_dispatch 获取数据
if [ "$EVENT_TYPE" = "repository_dispatch" ]; then
echo "Using repository_dispatch payload"
# 检查是否需要从 issue 读取(如果 payload 中的 context 为空或太大)
if [ -z "$CONTEXT_RAW" ] || [ "${#CONTEXT_RAW}" -gt 50000 ]; then
echo "Context from payload is empty or too large, reading from issue..."
# 从 payload 的 issue_number 字段获取存储数据的 issue
if [ -n "$ISSUE_NUMBER_FROM_PAYLOAD" ]; then
echo "Reading context from issue #$ISSUE_NUMBER_FROM_PAYLOAD"
# 从 issue body 读取数据
ISSUE_BODY=$(gh issue view "$ISSUE_NUMBER_FROM_PAYLOAD" --repo "$GITHUB_REPOSITORY" --json body --jq '.body')
# 提取 TASK 和 CONTEXT
TASK_CONTENT=$(echo "$ISSUE_BODY" | sed -n 's/.*<!-- TASK_START -->\(.*\)<!-- TASK_END -->.*/\1/p')
CONTEXT_RAW=$(echo "$ISSUE_BODY" | sed -n 's/.*<!-- CONTEXT_START -->\(.*\)<!-- CONTEXT_END -->.*/\1/p')
fi
fi
else
echo "Using workflow_dispatch inputs"
fi
# 2. 格式化 Context
FORMATTED_CONTEXT=$(echo "$CONTEXT_RAW" | sed 's/^"//; s/"$//' | jq '.' 2>/dev/null || echo "$CONTEXT_RAW")
# 3. 构建 Markdown 正文
printf "[工作流运行 #$GITHUB_RUN_ID](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)\\n\\n## Task\\n%s\\n\\n## Context\\n\\`\\`\\`json\\n%s\\n\\`\\`\\`" \
"$TASK_CONTENT" "$FORMATTED_CONTEXT" > body.md
# 4. 创建 Issue(硬编码标签 workflow)
ISSUE_URL=$(gh issue create \
--repo "$GITHUB_REPOSITORY" \
--title "[工作流] Run $GITHUB_RUN_ID" \
--body-file body.md \
--label "workflow")
# 5. 提取 Issue 编号
ISSUE_NUMBER=${ISSUE_URL##*/}
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
echo "task_content=$TASK_CONTENT" >> "$GITHUB_OUTPUT"
echo "成功创建 Issue: $ISSUE_NUMBER"
run-llm-bot:
needs: prepare-context
runs-on: ubuntu-latest
env:
LLM_TASK: ${{ needs.prepare-context.outputs.task_content }}
LLM_CONTEXT: ${{ github.event.client_payload.context || inputs.context }}
LOG_ISSUE_NUMBER: ${{ needs.prepare-context.outputs.issue_number }}
# GitHub身份令牌(4个名称都设置)- 使用agent的token
GITHUB_TOKEN: ${{ secrets.WEINAR_API_KEY }}
GH_TOKEN: ${{ secrets.WEINAR_API_KEY }}
GITHUBTOKEN: ${{ secrets.WEINAR_API_KEY }}
GHTOKEN: ${{ secrets.WEINAR_API_KEY }}
# Claude Code环境变量配置
ANTHROPIC_API_KEY: ${{ secrets.MIMO_API_KEY }}
ANTHROPIC_AUTH_TOKEN: ${{ secrets.MIMO_API_KEY }}
ANTHROPIC_BASE_URL: "https://api.xiaomimimo.com/anthropic"
ANTHROPIC_DEFAULT_OPUS_MODEL: "mimo-v2-flash"
ANTHROPIC_DEFAULT_SONNET_MODEL: "mimo-v2-flash"
ANTHROPIC_DEFAULT_HAIKU_MODEL: "mimo-v2-flash"
# MCP服务器环境变量
CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }}
# 系统提示词
SYSTEM_PROMPT: ${{ vars.SYSTEM_PROMPT }}
# 其他令牌
MIMO_API_KEY: ${{ secrets.MIMO_API_KEY }}
WEINAR_API_KEY: ${{ secrets.WEINAR_API_KEY }}
permissions:
contents: write
pull-requests: write
issues: write
discussions: write
steps:
- name: Install Claude CLI
run: |
curl -fsSL https://claude.ai/install.sh | bash
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: false
- name: Validate tokens
run: |
echo "验证环境变量..."
# 验证GitHub令牌
if [ -z "$GITHUB_TOKEN" ]; then
echo "错误: GITHUB_TOKEN未设置"
exit 1
else
echo "GitHub令牌已设置"
fi
# 验证Anthropic认证令牌
if [ -z "$ANTHROPIC_AUTH_TOKEN" ]; then
echo "错误: ANTHROPIC_AUTH_TOKEN未设置"
exit 1
else
echo "Anthropic认证令牌已设置"
fi
# 验证系统提示词
if [ -z "$SYSTEM_PROMPT" ]; then
echo "错误: SYSTEM_PROMPT未设置"
exit 1
else
echo "系统提示词已设置"
fi
- name: Add MCP servers
run: |
# 添加DuckDuckGo搜索服务器
echo "添加DuckDuckGo搜索服务器..."
claude mcp add ddg-search -- uvx duckduckgo-mcp-server
# 添加Context7 HTTP服务器(如果CONTEXT7_API_KEY已设置)
if [ -n "$CONTEXT7_API_KEY" ]; then
echo "添加Context7 HTTP服务器..."
claude mcp add --transport http context7 https://mcp.context7.com/mcp \
--header "CONTEXT7_API_KEY: $CONTEXT7_API_KEY"
else
echo "警告: CONTEXT7_API_KEY未设置,跳过Context7服务器添加"
fi
env:
CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }}
- name: Configure WakaTime
run: |
echo "检查 WakaTime 配置..."
# 检查 WAKE_TIME_API_KEY 环境变量
if [ -z "$WAKE_TIME_API_KEY" ]; then
echo "警告: WAKE_TIME_API_KEY 未设置,跳过 WakaTime 配置"
exit 0
fi
echo "WAKE_TIME_API_KEY 已设置,开始配置 WakaTime..."
# 安装 WakaTime CLI
echo "安装 WakaTime CLI..."
pip install wakatime
# 创建 ~/.wakatime.cfg 配置文件
echo "创建 ~/.wakatime.cfg 配置文件..."
mkdir -p ~
cat > ~/.wakatime.cfg << CFGEOF
[settings]

Check failure on line 186 in .github/workflows/llm-bot-runner.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/llm-bot-runner.yml

Invalid workflow file

You have an error in your yaml syntax on line 186
api_key = $WAKE_TIME_API_KEY
CFGEOF
echo "WakaTime 配置文件已创建:"
cat ~/.wakatime.cfg
# 安装 claude-code-wakatime 插件
echo "安装 claude-code-wakatime 插件..."
claude plugin marketplace add https://github.com/wakatime/claude-code-wakatime.git
claude plugin i claude-code-wakatime@wakatime
echo "WakaTime 配置完成"
env:
WAKE_TIME_API_KEY: ${{ secrets.WAKE_TIME_API_KEY }}
- name: Pre-configure Git
run: |
echo "配置Git用户信息..."
git config --global user.name "WhiteElephantIsNotARobot"
git config --global user.email "257136373+WhiteElephantIsNotARobot@users.noreply.github.com"
echo "配置SSH认证..."
# 创建SSH目录
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 从环境变量写入SSH私钥(如果提供了SSH_PRIVATE_KEY)
if [ -n "$SSH_PRIVATE_KEY" ]; then
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "SSH私钥已写入 ~/.ssh/id_rsa"
# 启动ssh-agent并添加密钥
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
echo "SSH密钥已添加到ssh-agent"
else
echo "警告: SSH_PRIVATE_KEY环境变量未设置,跳过SSH配置"
fi
# 添加GitHub到known_hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null
chmod 644 ~/.ssh/known_hosts
echo "配置GPG签名..."
# 从环境变量写入GPG私钥(如果提供了GPG_PRIVATE_KEY)
if [ -n "$GPG_PRIVATE_KEY" ]; then
echo "$GPG_PRIVATE_KEY" | gpg --import --batch
echo "GPG私钥已导入"
# 获取GPG密钥ID
GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG "257136373+WhiteElephantIsNotARobot@users.noreply.github.com" 2>/dev/null | grep sec | awk '{print $2}' | cut -d'/' -f2)
if [ -n "$GPG_KEY_ID" ]; then
# 配置git使用GPG签名
git config --global user.signingkey "$GPG_KEY_ID"
git config --global commit.gpgsign true
git config --global gpg.program gpg
echo "GPG签名已配置,密钥ID: $GPG_KEY_ID"
else
echo "警告: 无法找到GPG密钥ID"
fi
else
echo "警告: GPG_PRIVATE_KEY环境变量未设置,跳过GPG配置"
fi
echo "Git预配置完成"
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
- name: Run Claude Code
run: |
# 使用bind mount将深层目录映射到根路径,避免软链接被解析
echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE"
# 创建/app目录并绑定挂载
sudo mkdir -p /app
sudo mount --bind "$GITHUB_WORKSPACE" /app
# 切换到简洁的/app目录运行Claude Code
cd /app
echo "当前工作目录: $(pwd)"
echo "运行Claude Code..."
echo "原始任务: $LLM_TASK"
echo "系统提示词长度: ${#SYSTEM_PROMPT} 字符"
# 将JSON上下文写入文件(保存到/app目录)
echo "$LLM_CONTEXT" > /app/context.json
CONTEXT_CHARS=$(wc -m < /app/context.json)
echo "上下文文件大小: $CONTEXT_CHARS 字符"
# 不直接cat内容,避免日志污染
echo ""
# 构建新任务字符串,包含读取context.json的指示
ENHANCED_TASK=$(printf "%s\\n\\n> 任务上下文已保存到/app/context.json,共%s字符。阅读该文件以了解上下文!" "$LLM_TASK" "$CONTEXT_CHARS")
echo "增强任务: $ENHANCED_TASK"
claude \
-p "$ENHANCED_TASK" \
--system-prompt "$SYSTEM_PROMPT" \
--allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \
--output-format=stream-json \
--verbose
# 自查
claude \
-p "请快速自查是否在 GitHub 留下回复,确认是否已有回复,避免重复回复,若无回复,才应当回复。!避免重复回复!另请快速检查工作区,确保所有更改都已经提交并推送(若修改了仓库文件),确保 PR 已存在(若修改了仓库文件),任何未推送的更改都将在此会话结束后被永久销毁!" \
--system-prompt "$SYSTEM_PROMPT" \
--allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \
--output-format=stream-json \
--verbose \
--continue
# 再次自查
claude \
-p "请再次确认:所有更改都已经提交并推送(若修改了文件),并且 PR 已存在(若修改了文件),任何未推送的更改都将在此会话结束后被永久销毁!" \
--system-prompt "$SYSTEM_PROMPT" \
--allowedTools "Bash,TaskOutput,Edit,ExitPlanMode,Glob,Grep,KillShell,MCPSearch,NotebookEdit,Read,Skill,Task,TaskCreate,TaskGet,TaskList,TaskUpdate,WebFetch,WebSearch,Write,mcp__ddg-search__*,mcp__context7__*" \
--output-format=stream-json \
--verbose \
--continue