From f58137717ce6f4d3baf4ce808af6466f52576179 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 10 Aug 2026 11:39:42 +0800 Subject: [PATCH] =?UTF-8?q?ci(validate):=20CN=20=E9=95=9C=E5=83=8F?= =?UTF-8?q?=E5=8F=AF=E8=BE=BE=E6=80=A7=E5=8F=AA=E6=9F=A5=E6=9C=AC=E6=AC=A1?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E7=9A=84=E6=8F=8F=E8=BF=B0=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mirror-cn-reachable 此前每次运行都遍历全部 87 个描述符、105 个唯一 CN url,并且每个都是**整包下载**(`curl -o /dev/null` 拿的是 body —— 这是 故意的,gitcode 的 release 页面可以 200 而背后的资产已经没了)。而一个 PR 一次只镜像一个包的资产:其余 104 个都是更早的 PR 镜像时已经查过的,那时 是活的,现在挂掉只能是**之后**衰减的,与本次改动无关。 衰减是真实存在的,它本来就是每周 cron 的活:`select` 对 schedule/dispatch 回答 `__ALL__`,所以 105 个 url 的全量扫描照旧 —— 每周一次、外加手动触发,而不是每次 push。碰到 validate.yml 或共享测试 脚本(含本 job 读 url 用的 tests/list_cn_urls.lua)的 PR 也照旧全量, 理由和它们让 workspace 矩阵全量是同一个。 实现上复用 `select` 而不是在这里再 diff 一次:"这份 diff 能不能信" 在那里已经答过了,写两遍就是让两者迟早对不上。同一次遍历顺带收集改动 的描述符列表(`pkgs` 输出),删除的描述符不入列 —— 它的 CN url 随文件 一起没了,没有可达性可言。diff 里一个描述符都没有时(纯文档 / 纯 tools 改动)整个 job 跳过。 本地验证:选中 2 个描述符时查 2 个 url(实跑 curl 通过),`__ALL__` 时仍是 105 个;删除+编辑、纯文档、碰 validate.yml 三种 diff 的选择 结果均符合预期。 --- .github/workflows/validate.yml | 61 +++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 6917241..dcf6ec4 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -266,17 +266,50 @@ jobs: mirror-cn-reachable: # Closed-loop guard for the CN mirror: every CN url referenced by a # descriptor must be a live, downloadable gitcode release asset. + # + # ── Scoped to the CHANGED descriptors ───────────────────────────────── + # This used to walk all 87 descriptors on every run — 105 unique urls, + # each fetched in full (`curl -o /dev/null` downloads the body; that is + # the point, a gitcode release page can 200 while the asset behind it is + # gone) — while a PR mirrors one package's assets at a time. Everything + # else it re-downloaded was mirrored by an earlier PR that already + # checked it, and a url that was live then can only have gone dark + # SINCE, which is decay over time rather than something this PR did. + # + # Decay is real, and it is what the weekly cron below is for: `select` + # answers `__ALL__` for schedule/dispatch, so the full 105-url sweep + # still happens — once a week, and on demand — instead of on every push. + # It also still happens on any PR that touches this workflow file or a + # shared test script (including tests/list_cn_urls.lua, the extractor + # this job reads the urls with), because those widen `select` to a full + # run for the same reason they widen the workspace matrix. + # + # `needs: select` rather than a second diff here: the "can I trust this + # diff" question is already answered there, in one place. + needs: select + # Empty when the diff names no descriptor at all — a docs-only or + # tools-only PR mirrors nothing. + if: needs.select.outputs.pkgs != '' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install lua run: sudo apt-get install -y --no-install-recommends lua5.4 - name: Check CN mirror assets are reachable + env: + PKGS: ${{ needs.select.outputs.pkgs }} run: | fail=0 - # collect unique CN urls across all descriptors + if [ "$PKGS" = "__ALL__" ]; then + files=$(printf '%s\n' pkgs/*/*.lua) + echo "full sweep: every descriptor" + else + files=$PKGS + echo "changed descriptor(s): $files" + fi + # collect unique CN urls across the selected descriptors : > /tmp/cn.tsv - for f in pkgs/*/*.lua; do + for f in $files; do lua5.4 tests/list_cn_urls.lua "$f" >> /tmp/cn.tsv || true done sort -u /tmp/cn.tsv -o /tmp/cn.tsv @@ -324,6 +357,9 @@ jobs: members: ${{ steps.fanout.outputs.members }} matrix: ${{ steps.fanout.outputs.matrix }} plan: ${{ steps.plan_shards.outputs.plan }} + # The descriptors this change actually touches, for `mirror-cn-reachable`. + # `__ALL__` on a full run, empty when the diff names no descriptor at all. + pkgs: ${{ steps.plan.outputs.pkgs }} steps: - uses: actions/checkout@v4 with: @@ -344,11 +380,22 @@ jobs: # package), a non-member edit to the workspace manifest, or shared test # scripts. Docs-only and tools/-only changes select nothing. # Note: bash 3.2 on macOS runners — no associative arrays here. + # + # The same walk also collects the CHANGED DESCRIPTORS (`pkgs` output) for + # `mirror-cn-reachable`. Two selections, one classification: every reason + # to distrust the diff — this workflow file, a shared test script, an + # unclassified path, a push with no predecessor, cron/dispatch — has to + # widen both, and writing that decision twice is how the two drift. - name: Select affected workspace members id: plan shell: bash run: | - full() { echo "MEMBERS=__ALL__" >> "$GITHUB_ENV"; echo "full run: $1"; exit 0; } + full() { + echo "MEMBERS=__ALL__" >> "$GITHUB_ENV" + echo "pkgs=__ALL__" >> "$GITHUB_OUTPUT" + echo "full run: $1" + exit 0 + } # A push to main has a diff too — it was just never asked for. # @@ -388,7 +435,7 @@ jobs: esac changed=$(git diff --name-only $range) printf 'changed files vs %s:\n%s\n' "$base" "$changed" - sel="" + sel=""; pkgsel="" add() { case " $sel " in *" $1 "*) ;; *) sel="$sel $1" ;; esac; } while IFS= read -r f; do [ -n "$f" ] || continue @@ -413,6 +460,9 @@ jobs: # which already forces a full run above. [ -d "tests/examples/$m" ] && add "$m" ;; pkgs/*.lua|pkgs/*/*.lua) + # A DELETED descriptor is in the diff but not on disk, and its + # CN urls are gone with it — nothing left to reach. + if [ -f "$f" ]; then pkgsel="$pkgsel $f"; fi lib=$(basename "$f" .lua); lib=${lib#compat.} hit=0 for mt in tests/examples/*/mcpp.toml; do @@ -447,6 +497,9 @@ jobs: sel=${sel# } echo "MEMBERS=$sel" >> "$GITHUB_ENV" echo "selected members: ${sel:-}" + pkgsel=${pkgsel# } + echo "pkgs=$pkgsel" >> "$GITHUB_OUTPUT" + echo "changed descriptors: ${pkgsel:-}" # Sharding is for the FULL run only, and the shard count per platform is # that platform's RUNNER CONCURRENCY — not a round number. #