mirror of
https://git.openapi.site/https://github.com/desirecore/market.git
synced 2026-10-21 04:04:25 +08:00
## 背景 外部条目只存上游指针,上游仓库被删除、分支被重写或技能目录移动时,客户端安装会静默失败,目前没有任何机制能发现(例如 `dingtalk-cli` 的上游已 404,见修复 PR)。 ## 变更 - **`scripts/catalog/check_upstream_health.py`**:只读,逐个检查 `skills/`、`agents/`、`teams/` 下的 `entry.json`: - 失效(退出码 1):`gone` 上游不存在 · `bad-branch` 分支不存在 · `bad-ref` 固定提交无法获取 · `bad-path` `source.path`、根 `SKILL.md` 或 children 路径在分支最新提交下缺失 - 提示:`unreachable` 网络错误(不等于失效)· `new-skill` 集合有未声明子技能(发现规则直接复用 `gen-collection-children.py` 的 `discover_children`,两者结论一致)· `outdated` 固定 ref 落后于分支 · `unpinned` 未锁定 ref - 只稀疏检出 `SKILL.md`,39 个条目本地全量运行约 12 秒 - **`scripts/catalog/test_check_upstream_health.py`**:9 个基于本地 Git 仓库的单测,已加入 `i18n-validate.yml`。 - **`.github/workflows/upstream-health.yml`**:每周一 01:23 UTC 运行(可手动触发),仅在 `desirecore/market` 运行: - 报告写入 Job Summary,并维护唯一一个带 `upstream-health` 标签的 Issue:有待处理项时创建或更新,全部正常时评论并关闭 - 有失效条目时任务标红 - 权限仅 `contents: read` + `issues: write`,**不改写任何目录文件**;修复与 `source.ref` 更新仍通过评审 PR(与固定 ref 的审查语义一致) - README 中英文补充用法。 ## 当前主干的检查结果 - 失效 1:`dingtalk-cli`(已有修复 PR) - 未声明子技能 3:`khazix-skills`、`marketingskills`、`mattpocock-skills` - 可更新 21 个,未锁定 1 个 - `amap-jsapi-skill`、`luckin-my-coffee` 在本地因代理显示 `unreachable`,需要 CI 环境确认 ## 验证 ``` uv run scripts/catalog/test_check_upstream_health.py # Ran 9 tests OK uv run scripts/catalog/check_upstream_health.py # 如上 uv run scripts/i18n/validate-i18n.py # 0 error(s) ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0191D9g1FhRQzEGTefUn6mTb Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Yige <a@wyr.me>
88 lines
3.2 KiB
YAML
88 lines
3.2 KiB
YAML
name: Upstream Health
|
|
|
|
# Weekly check that every external pointer (skills/agents/teams entry.json)
|
|
# still resolves upstream. Results go to one tracking issue labelled
|
|
# `upstream-health`, which is updated in place and closed once nothing is
|
|
# actionable. Fixing an entry stays a normal reviewed PR; this workflow never
|
|
# rewrites catalog files.
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "23 1 * * 1" # Mondays 01:23 UTC
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
|
|
concurrency:
|
|
group: upstream-health
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
check:
|
|
if: github.repository == 'desirecore/market'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v3
|
|
|
|
- name: Check upstreams
|
|
id: check
|
|
run: |
|
|
set +e
|
|
uv run --quiet scripts/catalog/check_upstream_health.py --format markdown > report.md
|
|
code=$?
|
|
set -e
|
|
if [ "$code" -gt 1 ]; then
|
|
echo "health check crashed with exit code $code" >&2
|
|
exit "$code"
|
|
fi
|
|
echo "broken=$([ "$code" = 1 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
if grep -qE '^### (Broken|Undeclared upstream skills|Updates available) ' report.md; then
|
|
echo "actionable=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "actionable=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
cat report.md >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Update tracking issue
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
ACTIONABLE: ${{ steps.check.outputs.actionable }}
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: |
|
|
set -euo pipefail
|
|
label=upstream-health
|
|
gh label create "$label" --color D93F0B \
|
|
--description "Upstream availability of external catalog entries" 2>/dev/null || true
|
|
|
|
{
|
|
echo "_Updated by [Upstream Health]($RUN_URL) on $(date -u +%Y-%m-%d)._"
|
|
echo
|
|
echo "Fix entries through a normal PR: repoint or remove \`gone\` entries, correct \`bad-*\` paths, and review upstream changes before bumping \`source.ref\` for \`outdated\` entries (rerun \`scripts/gen-collection-children.py\` for collections). \`unreachable\` means a network error, not a confirmed failure."
|
|
echo
|
|
cat report.md
|
|
} > body.md
|
|
|
|
issue=$(gh issue list --label "$label" --state open --limit 1 --json number --jq '.[0].number // empty')
|
|
if [ "$ACTIONABLE" = "true" ]; then
|
|
if [ -n "$issue" ]; then
|
|
gh issue edit "$issue" --body-file body.md
|
|
else
|
|
gh issue create --title "Upstream health report" --label "$label" --body-file body.md
|
|
fi
|
|
elif [ -n "$issue" ]; then
|
|
gh issue comment "$issue" --body "All external entries resolve upstream and are current as of $RUN_URL. Closing."
|
|
gh issue close "$issue"
|
|
fi
|
|
|
|
- name: Fail when an entry is broken
|
|
if: steps.check.outputs.broken == 'true'
|
|
run: |
|
|
echo "::error::At least one external entry no longer resolves upstream; see the upstream-health issue."
|
|
exit 1
|