Skip to content

Commit 5ce7ee5

Browse files
authored
ci: 合入 main 只跑对应的成员,全量退到每周 (#191)
每次合并都在重跑全部 67 个成员 × 三平台 —— 约 11 小时 runner 时间,用来复核 几分钟前那个 PR 已经绿过的同一批东西。 原因是 select 的第一行 `event != pull_request -> full`。它的前提是"push 没有 可 diff 的 base",而这个前提不成立:本仓的合并都是 squash,`github.event.before` 就是上一个 main,`before..HEAD` 复现出来的文件列表和 PR 当时看到的一模一样。 拿 698b95e 实测,两边都选出 `redis-plus-plus redis-plus-plus-v133`,十个改动 文件逐个对得上。 ## 事件分派 pull_request 三点 diff(自己的提交对 merge base) push 两点 diff(这条分支上真正落下的东西) 其他 全量 schedule 和 workflow_dispatch 保持全量:它们表达的不是"有改动落地",而是 "把所有东西查一遍",那正是下面那张网的意义。 push 的两个兜底都倒向全量:before 是全零(建分支)或那个对象不在历史里 (force-push 把它丢了)时,没有可 diff 的东西,重跑好过猜。 ## 定时从每天改成每周 选择性测试结构上看不到的只有一件事:两个改动各自绿、落在一起互相踩 —— 两个 PR 的 diff 都没提到那个坏掉的成员,所以两个都选不中它。全量是这件事的网。 这张网每天撒一次和每七天撒一次,抓到的是同一批交互;而全量已经不便宜了(加 了第二条 linux 工具链腿之后约 11 小时)。改成周日 06:00 UTC。手动触发本来就 在,想立刻验一遍不用等。 五条路径都验过:schedule / dispatch / before 全零 / before 不在历史 → 全量; before 正常 → 选择性。
1 parent 856ddc7 commit 5ce7ee5

1 file changed

Lines changed: 57 additions & 11 deletions

File tree

.github/workflows/validate.yml

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,18 @@ on:
99
push:
1010
branches: [main]
1111
schedule:
12-
# nightly full regression — exercises every workspace member regardless of diff
13-
- cron: "0 6 * * *"
12+
# WEEKLY full regression — every workspace member, regardless of diff.
13+
#
14+
# This is the safety net for the one thing selective testing structurally
15+
# cannot see: two changes that are each green on their own and break each
16+
# other once both have landed. Neither PR's diff names the member that
17+
# breaks, so neither PR selects it.
18+
#
19+
# Weekly rather than nightly because a full run is no longer cheap — with
20+
# the second linux toolchain leg it is ~11 hours of runner time — and the
21+
# net catches the same interactions whether it is cast every day or every
22+
# seven. Sunday 06:00 UTC.
23+
- cron: "0 6 * * 0"
1424
workflow_dispatch:
1525
inputs:
1626
cache:
@@ -326,21 +336,57 @@ jobs:
326336
# package. Map changed files → affected members and test only those:
327337
# pkgs/<x>/<lib>.lua → members whose mcpp.toml references <lib>
328338
# tests/examples/<m>/** → member <m>
329-
# Run the FULL workspace when the change can affect everything:
330-
# non-PR events (push to main, the nightly cron, dispatch), this
331-
# workflow file (it carries the mcpp version pins, so a version bump
332-
# always re-validates every package), a non-member edit to the
333-
# workspace manifest, or shared test scripts. Docs-only and tools/-only
334-
# changes select nothing.
339+
# A push to main is mapped the same way — the merge's own diff — so a
340+
# merge costs what its PR cost. Run the FULL workspace when the change
341+
# can affect everything: the weekly cron and manual dispatch (which mean
342+
# "check everything" by definition), this workflow file (it carries the
343+
# mcpp version pins, so a version bump always re-validates every
344+
# package), a non-member edit to the workspace manifest, or shared test
345+
# scripts. Docs-only and tools/-only changes select nothing.
335346
# Note: bash 3.2 on macOS runners — no associative arrays here.
336347
- name: Select affected workspace members
337348
id: plan
338349
shell: bash
339350
run: |
340351
full() { echo "MEMBERS=__ALL__" >> "$GITHUB_ENV"; echo "full run: $1"; exit 0; }
341-
[ "${{ github.event_name }}" = "pull_request" ] || full "event=${{ github.event_name }}"
342-
base="origin/${{ github.base_ref }}"
343-
changed=$(git diff --name-only "$base"...HEAD)
352+
353+
# A push to main has a diff too — it was just never asked for.
354+
#
355+
# This used to be `event != pull_request -> full`, so every merge
356+
# re-tested all 67 members on all three platforms: ~11 hours of
357+
# runner time to re-confirm what the PR had already gone green on
358+
# minutes earlier. The premise was that a push has no base to diff
359+
# against, and that is not true: merges here are squashes, so
360+
# `github.event.before` is the previous main and
361+
# `before..HEAD` reproduces exactly the file list the PR saw
362+
# (verified on 698b95ee — same ten paths).
363+
#
364+
# schedule and workflow_dispatch stay full. They are not "a change
365+
# landed", they are "check everything", which is the whole point of
366+
# the weekly net above.
367+
#
368+
# Two-dot for push, three-dot for pull_request, deliberately: a PR
369+
# wants its own commits against the merge base, while a push wants
370+
# what actually landed on this branch.
371+
case "${{ github.event_name }}" in
372+
pull_request)
373+
base="origin/${{ github.base_ref }}"; range="$base...HEAD" ;;
374+
push)
375+
base="${{ github.event.before }}"
376+
# All-zero on branch creation; absent object after a
377+
# force-push that dropped it. Either way there is nothing to
378+
# diff against, and guessing is worse than re-testing.
379+
case "$base" in
380+
""|0000000000000000000000000000000000000000)
381+
full "push with no predecessor" ;;
382+
esac
383+
git cat-file -e "$base^{commit}" 2>/dev/null \
384+
|| full "push predecessor $base not in history"
385+
range="$base..HEAD" ;;
386+
*)
387+
full "event=${{ github.event_name }}" ;;
388+
esac
389+
changed=$(git diff --name-only $range)
344390
printf 'changed files vs %s:\n%s\n' "$base" "$changed"
345391
sel=""
346392
add() { case " $sel " in *" $1 "*) ;; *) sel="$sel $1" ;; esac; }

0 commit comments

Comments
 (0)