Agentic Patrol #22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Agentic Patrol | |
| on: | |
| schedule: | |
| # 每 4 小时巡查一次 | |
| - cron: '7 */4 * * *' | |
| workflow_dispatch: | |
| env: | |
| NOTO_SANS_URL: https://github.com/notofonts/noto-cjk/releases/download/Sans2.004/03_NotoSansCJK-OTC.zip | |
| NOTO_SERIF_URL: https://github.com/notofonts/noto-cjk/releases/download/Serif2.002/04_NotoSerifCJKOTC.zip | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| patrol: | |
| runs-on: ubuntu-latest | |
| env: | |
| diffext: .diff | |
| diffexe: git diff --no-index --text -- | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.PAT_TOKEN || github.token }} | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config core.hooksPath .githooks | |
| - name: Install TeX Live | |
| timeout-minutes: 30 | |
| uses: TeX-Live/setup-texlive-action@v4 | |
| with: | |
| package-file: .github/tl_packages | |
| repository: https://ctan.math.illinois.edu/systems/texlive/tlnet | |
| update-all-packages: true | |
| - name: Install Noto fonts | |
| run: | | |
| curl -LO ${{ env.NOTO_SANS_URL }} | |
| curl -LO ${{ env.NOTO_SERIF_URL }} | |
| for f in *OTC.zip; do unzip -ojd /usr/share/fonts/truetype "$f" "*.ttc"; done | |
| fc-cache -f | |
| - name: Install Claude Code CLI | |
| id: setup_claude | |
| run: | | |
| CLAUDE_INSTALL_DIR="$RUNNER_TEMP/claude-code" | |
| rm -rf "$CLAUDE_INSTALL_DIR" | |
| npm install --prefix "$CLAUDE_INSTALL_DIR" @anthropic-ai/claude-code@2.1.80 | |
| CLAUDE_CODE_PATH="$CLAUDE_INSTALL_DIR/node_modules/.bin/claude" | |
| echo "path=$CLAUDE_CODE_PATH" >> $GITHUB_OUTPUT | |
| "$CLAUDE_CODE_PATH" --version | |
| - name: Run Patrol | |
| id: patrol | |
| timeout-minutes: 60 | |
| # claude-code-action v0.0.19 (pinned by commit hash) | |
| uses: anthropics/claude-code-action@e7b588b6eaa5263c2e7c6c7b34a29e190d32ee68 | |
| env: | |
| ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }} | |
| DISABLE_AUTOUPDATER: "1" | |
| with: | |
| github_token: ${{ secrets.PAT_TOKEN || github.token }} | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| path_to_claude_code_executable: ${{ steps.setup_claude.outputs.path }} | |
| prompt: | | |
| 仓库: ${{ github.repository }} | |
| 仓库 URL: https://github.com/${{ github.repository }} | |
| 使用 `patrol` skill 执行仓库定期巡查。 | |
| 本环境已安装完整 TeX Live 和 Noto CJK 字体,可运行 l3build check/save 等命令。 | |
| l3build 测试所需环境变量已配置(diffext=.diff, diffexe="git diff --no-index --text --")。 | |
| claude_args: | | |
| --model opus --allowedTools "Bash,Read,Write,Edit,Glob,Grep,Task,TodoWrite,Agent,Skill" | |
| --json-schema '{"type":"object","properties":{"description":{"type":"string","description":"巡查结果摘要"},"ci_status":{"type":"string","enum":["pass","fail","unknown"],"description":"CI 整体状态"},"issues_processed":{"type":"integer","description":"处理的 Issue 数"},"prs_created":{"type":"integer","description":"创建的 PR 数"},"actions_taken":{"type":"array","items":{"type":"string"},"description":"本次巡查采取的操作"}},"required":["description","ci_status","issues_processed"]}' | |
| - name: Output Result | |
| if: always() | |
| env: | |
| STRUCTURED_OUTPUT: ${{ steps.patrol.outputs.structured_output }} | |
| run: | | |
| echo "## Patrol Result" >> $GITHUB_STEP_SUMMARY | |
| echo '```json' >> $GITHUB_STEP_SUMMARY | |
| echo "$STRUCTURED_OUTPUT" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| - name: Parse Patrol Output | |
| if: always() | |
| id: parse | |
| env: | |
| STRUCTURED_OUTPUT: ${{ steps.patrol.outputs.structured_output }} | |
| JOB_STATUS: ${{ job.status }} | |
| run: | | |
| if [ -n "$STRUCTURED_OUTPUT" ] && [ "$STRUCTURED_OUTPUT" != "null" ]; then | |
| DESCRIPTION=$(echo "$STRUCTURED_OUTPUT" | jq -r '.description // "巡查完成"') | |
| CI_STATUS=$(echo "$STRUCTURED_OUTPUT" | jq -r '.ci_status // "unknown"') | |
| ISSUES=$(echo "$STRUCTURED_OUTPUT" | jq -r '.issues_processed // 0') | |
| PRS=$(echo "$STRUCTURED_OUTPUT" | jq -r '.prs_created // 0') | |
| case "$CI_STATUS" in | |
| "fail") STATUS="error" ;; | |
| "pass") STATUS="success" ;; | |
| *) STATUS="info" ;; | |
| esac | |
| TITLE="巡查: CI ${CI_STATUS}, ${ISSUES} issues, ${PRS} PRs" | |
| else | |
| TITLE="巡查完成" | |
| DESCRIPTION="未能获取结构化输出" | |
| STATUS="warning" | |
| ISSUES=0 | |
| PRS=0 | |
| CI_STATUS="unknown" | |
| fi | |
| if [ "$JOB_STATUS" != "success" ]; then | |
| STATUS="warning" | |
| DESCRIPTION="GitHub Action 执行失败" | |
| fi | |
| echo "status=${STATUS}" >> $GITHUB_OUTPUT | |
| echo "title=${TITLE}" >> $GITHUB_OUTPUT | |
| { | |
| echo 'description<<EOF' | |
| echo "**${{ github.repository }}**" | |
| echo "${DESCRIPTION}" | |
| echo 'EOF' | |
| } >> $GITHUB_OUTPUT | |
| # 判断是否需要通知(有实质操作时才通知) | |
| if [ "$ISSUES" -gt 0 ] || [ "$PRS" -gt 0 ] || [ "$CI_STATUS" = "fail" ] || [ "$STATUS" = "warning" ]; then | |
| echo "should_notify=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "should_notify=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Checkout Action | |
| if: always() && steps.parse.outputs.should_notify == 'true' | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: Lightspeed-Intelligence/agentic-workflow-template | |
| ref: main | |
| token: ${{ secrets.PAT_TOKEN || github.token }} | |
| path: .agentic-actions | |
| sparse-checkout: .github/actions | |
| sparse-checkout-cone-mode: false | |
| - name: Notify Feishu | |
| if: always() && steps.parse.outputs.should_notify == 'true' | |
| uses: ./.agentic-actions/.github/actions/feishu-notify | |
| with: | |
| webhook_token: ${{ secrets.FEISHU_WEBHOOK_TOKEN }} | |
| title: ${{ steps.parse.outputs.title }} | |
| description: ${{ steps.parse.outputs.description }} | |
| link_text: "🔗 查看运行" | |
| link_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| status: ${{ steps.parse.outputs.status }} |