mirror of
https://git.openapi.site/https://github.com/desirecore/market.git
synced 2026-10-21 07:24:00 +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>
91 lines
3.1 KiB
YAML
91 lines
3.1 KiB
YAML
name: i18n Validate
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Detect relevant changes
|
|
id: changes
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
PUSH_BEFORE: ${{ github.event.before }}
|
|
PUSH_AFTER: ${{ github.event.after }}
|
|
run: |
|
|
set -e
|
|
case "$EVENT_NAME" in
|
|
pull_request)
|
|
git fetch --no-tags --depth=1 origin "$BASE_SHA" 2>/dev/null || true
|
|
range="${BASE_SHA}...${HEAD_SHA}"
|
|
;;
|
|
push)
|
|
if [ -n "$PUSH_BEFORE" ] && [ "$PUSH_BEFORE" != "0000000000000000000000000000000000000000" ]; then
|
|
range="${PUSH_BEFORE}...${PUSH_AFTER}"
|
|
else
|
|
# initial push or unknown before — assume relevant
|
|
echo "relevant=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
;;
|
|
*)
|
|
echo "relevant=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
;;
|
|
esac
|
|
changed=$(git diff --name-only "$range" || true)
|
|
if echo "$changed" | grep -qE '^(skills/|agents/|teams/|schemas/|manifest\.json$|categories\.json$|scripts/i18n/|scripts/catalog/|scripts/gen-collection-children\.py$)'; then
|
|
echo "relevant=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "relevant=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Install uv
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
uses: astral-sh/setup-uv@v3
|
|
|
|
- name: Run validator unit tests
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: uv run --quiet scripts/i18n/test_validate_i18n.py
|
|
|
|
- name: Run catalog validator unit tests
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: |
|
|
uv run --quiet scripts/catalog/test_validate_catalog_metadata.py
|
|
uv run --quiet scripts/catalog/test_collection_generator.py
|
|
uv run --quiet scripts/catalog/test_check_upstream_health.py
|
|
|
|
- name: Validate catalog metadata
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: uv run --quiet scripts/catalog/validate_catalog_metadata.py --require-complete
|
|
|
|
- name: Validate i18n
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: uv run --quiet scripts/i18n/validate-i18n.py
|
|
|
|
- name: Check for stale translations
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: uv run --quiet scripts/i18n/translate.py --check
|
|
|
|
- name: Check generated collection children
|
|
if: steps.changes.outputs.relevant == 'true'
|
|
run: uv run --quiet scripts/gen-collection-children.py --check
|
|
|
|
- name: Skip notice
|
|
if: steps.changes.outputs.relevant != 'true'
|
|
run: echo "No i18n-relevant changes; validation skipped."
|