Skip to content

ci(shard-timings-refresh): push and open the refresh PR as the fleet App so it runs CI - #26017

Merged
os-zhuang merged 2 commits into
mainfrom
claude/project-thread-czb0vs
Oct 26, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/project-thread-czb0vs

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Part of #25936. The card stays open for two readings this PR cannot take before it merges (see "What stays open").

维护者速读(草稿)

改了什么:每周一自动刷新 Test Core 分片计时数据的 workflow(shard-timings-refresh.yml),推分支、开 PR、打标签这三步改用 fleet App(objectstack-fleet[bot])的身份做。令牌在 runner 上现铸,只对本仓、只给 contents 和 pull-requests 两项写权限,用完即吊销。job 自己的 GITHUB_TOKEN 降为只读。

为什么改:以前用 Actions 自带的 GITHUB_TOKEN 开 PR(仓里没有配 RELEASE_PUSH_TOKEN),GitHub 对这种 PR 不启动任何 CI。结果每次刷新 PR 都要有人手动推一下才有检查:#24467 等了十天,今天的 #25960 是席位用中继 pr_update_branch 才跑起来的。刷新会改变分片切法,恰恰最需要 CI 读一遍。

风险与代价(含回滚):用的是 fleet-write 已在用的那对组织级凭据(OS_FLEET_APP_ID / OS_FLEET_PRIVATE_KEY),不引入 PAT。凭据不可见时这一步直接报红并点名缺哪一半,不会悄悄退回无 CI 的老路。PR 上跑这个 workflow 时照旧是演练,不铸令牌、不读密钥。回滚就是 revert 这一个文件。ui/ 的逐文件计时数据集这次没接上(见下文),它由 #25712 第 5 项承接。

席位意见:

你要做的:本 PR 是 Tier H(.github/workflows/**),需要一位 GOVERNED_APPROVERS 批准;批准后席位落地。

What changed

.github/workflows/shard-timings-refresh.yml only (+78 / −24):

  • Two new steps before the write step, both skipped on pull_request and when the dataset is byte-identical:
    • Check the fleet App credential is visible to this repository reads vars.OS_FLEET_APP_ID and secrets.OS_FLEET_PRIVATE_KEY as booleans (never printed) and reds with a message naming the missing half.
    • Mint the fleet App token, narrowed to this repository: actions/create-github-app-token@v3, the same action and credential pair fleet-write.yml mints with, and the route ui/'s refresh took in ci(test-shard-timings-refresh): push and open the refresh pull request as the fleet App so it runs CI objectui#13362. The grants are contents: write (push the bot branch) and pull-requests: write (open the PR, add skip-changeset). It has no workflows grant, because the branch is cut from the checked-out main plus one commit touching only the dataset.
  • Write step: GH_TOKEN is the minted token on a live run and the run's read-only token on a pull_request dry run, where outward hands it to nothing. A live run with no minted token arrives empty and the existing GH_TOKEN:? guard reds it. outward gh auth setup-git points git at that token for the push. The commit author is now objectstack-fleet[bot].
  • Job permissions drop from contents: write + pull-requests: write + actions: read to contents: read + actions: read. The checkout uses persist-credentials: false and no longer reads RELEASE_PUSH_TOKEN.
  • PR body: the "No checks will start on this PR by themselves" section and its USED_PAT switch are gone. It is replaced by one line saying the PR was opened as the fleet App and runs its own CI (the card's step 3).

The measurement this rests on

  1. The root refresh has the card's no-CI defect. chore(ci): refresh the Test Core shard-timings dataset #25960 (2026-10-26 05:47Z) is authored by github-actions[bot], and its body carries the USED_PAT != true section, so RELEASE_PUSH_TOKEN is not configured. It got CI only after a relay pr_update_branch. chore(ci): refresh the Test Core shard-timings dataset #24467 (2026-10-19) sat ten days the same way.
  2. The ui/ per-file dataset has no producer. ui/.github/workflows/test-shard-timings-refresh.yml is nested, so GitHub never runs it. Root ci.yml's Test UI (N/16) passes no timings reporter and uploads no test-file-timings-N artifact, and its own comment says so: the port belongs to the governance-workflow audit. That audit is tooling(ui-merge): governance in-repo — liveness evidence and spec tests stop citing objectui by commit, one sdui-parser, AGENTS.md / pm scripts drop objectui#, ui/AGENTS.md nests, 18 governance workflows merged or retired (parent #25677, 4b/6) #25712 item 5, which names test-shard-timings-refresh among the workflows to fold into the objectstack counterpart and widen to ui/**. tooling(ui-merge): governance in-repo — liveness evidence and spec tests stop citing objectui by commit, one sdui-parser, AGENTS.md / pm scripts drop objectui#, ui/AGENTS.md nests, 18 governance workflows merged or retired (parent #25677, 4b/6) #25712 is in flight under another seat's claim, so this PR does not build that half. The dataset today: ui/scripts/test-shard-timings.json was measured 2026-10-19T06:37Z over 6 runs and holds 5,547 keys. Of the 5,805 tracked *.test.* files under ui/ (excluding e2e/ and apps/site/), 290 have no key and are weighed at the median, and 32 keys name files that no longer exist. That count is from git ls-files and is an upper bound on what vitest collects.

Verification

Head cadda147 (50d4fffd plus a merge of origin/main a3e5bfa6, no conflict; this PR's diff against main is the one file).

  • The write step, driven as written. Its run: block was lifted out of the YAML and run under bash -e in a scratch repository:
    • Dry leg (DRY_RUN=true, pull_request, stand-in GH_TOKEN): exit 0. Every outward act printed DRY RUN, not executed:, including gh auth setup-git. The local commit was authored objectstack-fleet[bot], email 332303061+objectstack-fleet[bot]@users.noreply.github.com.
    • Live leg with an empty GH_TOKEN (a run where minting did not happen): exit 1 at the guard, GH_TOKEN: is not set; gh would run unauthenticated. Nothing was pushed.
  • The credential check, three legs. Both set: exit 0, and it writes repository=objectstack. App id missing: exit 1. Key missing: exit 1.
  • Derived gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 42 families. All 42 ran locally with exit 0, including select-shard-timings-run.mjs --self-test (it lifts and runs this workflow's selection step), measure-test-shard-timings.mjs --self-test, partition-test-shards.mjs --self-test, check-step-collectors, check-whole-set-label-write, check-workflow-step-name-quoting and check:pm-dispatch-gates (fast tier, 1917 cases). --ran reconciled: 42 run, 0 NOT MEASURED.
  • This PR's own pull_request run of the lane (the path filter includes the workflow) executes everything up to and including the write step's local commit, with the new env:. That is the on-runner proof of the dry leg; read it on the PR's checks.
  • check-governed-merges --branch HEAD: GOVERNED, .github/workflows/**, Tier H, 102 changed lines.

What stays open on the card

Acceptance notes

  • cut-rc.yml makes the same "PAT if present, Actions token otherwise" choice for the release-candidate PR. It is out of scope for this card and is noted only, not filed.
  • No changeset: this PR changes a workflow, which publishes nothing (skip-changeset).

🤖 Generated with Claude Code

https://claude.ai/code/session_014GRKsjPHqpppQDE1LMetJX

…App so it runs CI

The weekly refresh pushed its branch and opened its PR with the run's own
GITHUB_TOKEN (no RELEASE_PUSH_TOKEN is configured), and GitHub starts no
workflow for an event that token raised: #24467 waited ten days, #25960
got CI only after a relay pr_update_branch.

The write step now runs on a fleet App token minted on the runner from
OS_FLEET_APP_ID / OS_FLEET_PRIVATE_KEY (the pair fleet-write.yml mints
with, and the route ui/'s refresh took in objectui#13362), narrowed to
this repository and to contents + pull-requests. The job's own token
drops to contents/actions read, the checkout persists no credential, a
missing credential is a named red, and a pull_request run still mints
nothing and stays a dry run. The PR body's "no checks will start"
paragraph is replaced by a line saying the PR runs its own CI.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GRKsjPHqpppQDE1LMetJX
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review October 26, 2026 09:16
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

Verdict: ACCEPT at head cadda147e4c15efbb44a44a4bf366c4d05e3250e. Tier H (.github/workflows/shard-timings-refresh.yml). The PR lands after a GOVERNED_APPROVERS approval (hotlong / os-zhuang requested). After that, once every check on this head is green, the seat flips it.

Checklist

What the diff does (read line by line)

  • The job's own token drops to contents: read, and the checkout uses persist-credentials: false. The old RELEASE_PUSH_TOKEN || github.token fallback is gone.
  • On schedule / workflow_dispatch only, the job mints the fleet App token with actions/create-github-app-token@v3. The token is narrowed to this repository with permission-contents: write + permission-pull-requests: write only. It uses the same vars.OS_FLEET_APP_ID / secrets.OS_FLEET_PRIVATE_KEY pair fleet-write.yml already uses.
  • A pull_request run is a dry run that mints nothing (GH_TOKEN falls back to github.token there).
  • A missing credential is a loud ::error with nothing pushed, not a silent fallback to the Actions token.

⚠ For the governed approver: credential scope

  • This is the second workflow that mints the fleet App token. Until now only fleet-write.yml did. Scope is limited to:
    • this repository;
    • contents + pull-requests;
    • not pull_request events;
    • the scheduled or dispatched weekly lane.
  • That widening is the substance of this approval. If the maintainer would rather keep the App key in exactly one workflow, the alternative is for this lane to hand its PR to the relay's pr_create op. That route is heavier.

ui/ half, deliberately not built here

Gates

  • CI is converging: 12 success, 18 skipped, 13 in progress, 0 failed.
  • The dev's local derived set was 42/42 exit 0, --ran reconciled. The dev also ran the write and credential steps as written: dry leg exits 0, empty-token live leg exits 1, credential legs 0/1/1.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants