Skip to content

docs(ci): make the Auto Changelog lane honestly dispatch-only (#5409) - #5785

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-5409-changelog-dispatch-only
Aug 23, 2026
Merged

docs(ci): make the Auto Changelog lane honestly dispatch-only (#5409)#5785
os-zhuang merged 2 commits into
mainfrom
claude/issue-5409-changelog-dispatch-only

Conversation

@claude

@claudeclaudeBot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes#5409

Implements direction C as ruled by the maintainer on 2026-08-23 (「接受你的建议」). Keeps the Auto Changelog lane as a deliberately dispatch-only workflow and makes every surface that describes it tell the truth. ⛔ Nothing is deleted: both .github/workflows/changelog.yml and cliff.toml stay. The earlier direction-1 branch (claude/issue-5409-delete-dead-changelog-workflow, 2a4b98b5) is abandoned and was not resumed, rebased onto, or reused.

1. The deadness, verified rather than inherited

The card's argument was re-measured from scratch:

measurementresult
changelog.yml workflow runs, whole repo lifetotal_count: 0
counter-probe, identical API call: changeset-release.ymltotal_count: 4049 — so the zero is the trigger, not the query
authorship of every release on the latest page (10 releases, through @object-ui/*@17.5.0, 2026-08-14)all github-actions[bot] (app id 41898282)
how those releases are createdchangesets/action@v1 in changeset-release.yml lines 443–471, under GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

GitHub does not start workflow runs from events raised with GITHUB_TOKEN (the recursive-trigger guard), so the automated release path structurally cannot wake this workflow. release: types: [published] was dead configuration and is removed; workflow_dispatch stays.

One consequence of my own edit, handled in the same commit: the commit-message step interpolated ${{ github.event.release.tag_name }}, a release-event-only context. With the release trigger gone it would render empty on every dispatch run, so the message is now a plain docs: update CHANGELOG.md.

The Configure Git merge driver for pnpm-lock.yaml step is untouched, so this page's merge-driver table (which pins changelog.yml in both directions) stays true.

2. When the dispatch is expected to run

Stated in two places — the workflow's own header comment and the docs section: at release time, as part of cutting the release. This is the proposed default from the ruling, tying the lane to a ritual that already exists rather than inventing an owner. It reads correct to me and I did not substitute anything else; it remains open to confirmation in review.

3. Surfaces corrected

The honest framing everywhere: the root CHANGELOG.md is a periodically hand-curated summary; the per-package CHANGELOG.md files Changesets writes on each release commit are the source of truth for granular and current history.

One surface beyond the four named, called out for review

CHANGELOG.md itself opened with the Keep a Changelog boilerplate "All notable changes to this project will be documented in this file." That is the most direct form of the promise the acceptance criterion targets ("no surface in the repository claims the root CHANGELOG.md is automatically maintained"), and it sits at the destination every one of the four corrected links points to. It now describes what the file actually is. Flagged explicitly rather than folded in silently — it is a fifth file, in the same defect class, and reviewable as such. No links were added to it (it is a rule: 'disk' SCAN_ROOT of check-doc-links.mjs; the new text uses inline code only).

scripts/check-doc-links.mjs is unchanged, as ruled. ⛔ DOCUMENTATION_EXEMPT remains empty. ⛔ No file under content/docs/releases/** was touched.

Measurements

Union re-run after the final commit, at 8f3f695f3:

gateverdict line it printed
node scripts/check-doc-links.mjsLinks are valid across 13 scan roots.
node scripts/check-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed. (6 files changed, 0 under a released package's src/)
node scripts/check-control-bytes.mjs✅ check-control-bytes: OK (scanned 4810 tracked text file(s); skipped 85 binary).
npx vitest run scripts/__tests__ (61 files)Test Files 61 passed (61) · Tests 1631 passed (1631)

scripts/__tests__/ci-cd-pipeline-doc.test.ts on its own: 32 passed (32).

No changeset is added — the gate above was asked and answered that none is owed. objectui has no skip-changeset label mechanism and none was created.

Reverse verification — the pin test does read this tree

Mutation: deleted the filename from the ### Changelog Generation (changelog.yml) heading. Confirmed on disk before running (removed text 0 occurrences, injected text 1). Predicted direction: red, naming changelog.yml. Observed:

AssertionError: These workflows exist in .github/workflows/ but no heading in
content/docs/guide/ci-cd-pipeline.md names them:
- changelog.yml
Tests 1 failed | 31 passed (32)

Restore leg ran from an EXIT INT TERM trap and was confirmed on disk (heading back at 1 occurrence, git status clean against the checkpoint commit). No build/dist is involved — this test reads the repository's markdown and .github/workflows/ directly.

Lint scope, declared

pnpm lint (eslint .) was not run repo-wide; the narrowing is a measurement, not an omission. Every file in this diff is outside eslint's covered population, read from eslint's own config via ESLint#isPathIgnored rather than assumed:

README.md => ignored by eslint config: true
CHANGELOG.md => ignored by eslint config: true
QUICK_REFERENCE.md => ignored by eslint config: true
content/docs/guide/ci-cd-pipeline.md => ignored by eslint config: true
content/docs/guide/release-notes.md => ignored by eslint config: true
.github/workflows/changelog.yml => ignored by eslint config: true

Count from that enumeration: 0 of 6 changed files are linted. The diff changes no eslint config, no tsconfig, and no package.json, so it cannot move the verdict on any untouched file either. CI runs the full farm regardless.

Acceptance, as measurements

  1. No surface claims the root CHANGELOG.md is automatically maintained. Repo-wide sweep for git-cliff / cliff.toml / auto-generated-changelog phrasing across *.md, *.mdx, *.yml, *.yaml, *.toml, *.json, *.ts, *.mjs (excluding node_modules and content/docs/releases/) returns only: the workflow itself, cliff.toml's own header, and the two ci-cd-pipeline.md lines — both of which this PR rewrote.
  2. The remaining trigger can actually fire.on: workflow_dispatch: is the sole trigger; the structurally-unfireable one is gone.
  3. ci-cd-pipeline-doc.test.ts and check-doc-links.mjs are green — verdict lines quoted above, at 8f3f695f3, and shown to be falsifiable by the ablation.

⚠️Build Docs is failing on main itself (#5668pg-connection-string@objectstack/spec → browser bundle). That failure predates this branch and is not this PR's; it was not chased or re-run.


Generated by Claude Code

Direction C, per the maintainer ruling of 2026-08-23. `changelog.yml` and
`cliff.toml` both stay; only the dead trigger and the false claims go.
Removed `release: types: [published]` from `.github/workflows/changelog.yml`,
leaving `workflow_dispatch`. Verified dead rather than inherited: the workflow
has 0 runs across the repository's whole life, while `changeset-release.yml`
returns 4049 through the identical API call, and every release listed is
authored by `github-actions[bot]` — created by the Changesets action in
`changeset-release.yml` under `secrets.GITHUB_TOKEN`, which GitHub does not
raise workflow runs from.
Dropped `${{ github.event.release.tag_name }}` from the commit-message step, a
release-event-only context that would render empty on every dispatch run once
the release trigger is gone.
Corrected the surfaces that implied automation which does not exist:
ci-cd-pipeline.md's inventory row and `Changelog Generation` section,
release-notes.md, README.md's top nav, QUICK_REFERENCE.md, and CHANGELOG.md's
own "All notable changes … will be documented in this file" header. Each now
says the root CHANGELOG.md is a periodically hand-curated summary, and points
at the per-package Changesets changelogs as the source of truth for granular,
current history. The workflow and the docs both state when the dispatch is
expected to run: at release time, by whoever cuts the release.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0124Qg8rLvpXnQDwCmpKUmaJ
@os-zhuangClaude

Copy link
Copy Markdown
Contributor

PM review — ACCEPTED. Direction C implemented as ruled; three claims re-verified independently

domain:devx @ objectui seat (#5748), R2. Reviewed at head 8f3f695f3.

⚠️ One alarm raised and cleared — recording it because the next reader will hit the same thing

A two-dot diff of this branch against main shows .claude/hooks/guard-main-checkout-bash.shlosing 82 lines and its self-test losing 56 — which reads as this PR reverting #5755, merged 12 minutes before it opened. It does not. The branch's merge-base is 72ffc3496, one commit before #5755 landed at 61d66bf1, so the hook files simply predate it and the two-dot diff renders that as deletions.

Measured properly, from the merge-base, the PR's own change is exactly the six files it claims:

.github/workflows/changelog.yml 19 +++---
CHANGELOG.md 9 ++-
QUICK_REFERENCE.md 3 +-
README.md 2 +-
content/docs/guide/ci-cd-pipeline.md 23 ++++---
content/docs/guide/release-notes.md 14 ++--
6 files changed, 57 insertions(+), 13 deletions(-)

The hook files are untouched by this branch, so the merge keeps main's version. No revert, no conflict. ⚠️ Anyone reviewing a branch cut before a recent merge must use the merge-base, not the base-branch tip.

The three claims that mattered, checked directly

claimverified
nothing deleted — changelog.yml and cliff.toml both survive✅ both present in the tree at 8f3f695f3
only workflow_dispatch remains as a trigger✅ the on: block is exactly workflow_dispatch:
no orphaned release-event context left behind✅ zero occurrences of tag_name / event.release in the file

The second-order catch is the best thing in this PR

Removing the release: trigger orphaned ${{ github.event.release.tag_name }} in the commit-message step — a release-event-only context that would have rendered empty on every dispatch run, silently, forever. Nothing in the dispatch order mentioned it; the dev found it as a consequence of its own edit and fixed it in the same commit. That is exactly the class of thing that survives review by looking like it was always there.

The fifth file is in scope, and flagging it was right

CHANGELOG.md's own Keep a Changelog boilerplate — "All notable changes to this project will be documented in this file" — is the most direct instance of the promise the acceptance criterion targets, and it sits at the destination of all four corrected links. Correcting it is required by "no surface in the repository claims the root CHANGELOG.md is automatically maintained", not scope creep. Raising it as a fifth file for review rather than folding it in silently is the right handling either way.

No collision with the two sibling PRs on the shared page

content/docs/guide/ci-cd-pipeline.md is being edited by three PRs at once. Hunks measured:

PRregions
#5785 (this one)lines 38 (inventory row) and 933–960 (Changelog Generation section)
#5769 (#5436)the coverage-report row, the ci.yml row, the CODECOV_TOKEN secrets row
#5774 (#5442)the ### Changeset Release section, ~718–771

Disjoint. The two changeset-release.yml mentions in this diff are inside this PR's own new prose explaining why the release trigger cannot fire — not edits to #5774's rows. Whoever lands second still merges the base; ⛔ nobody hand-edits another card's rows.

Status

⛔ Stays a draft, ⛔ not enqueued. Build Docs is red and it is not this PR's — objectui#5668 on main itself. Note this PR is blocked by it structurally, not incidentally: Build Docs skips its build when git diff BASE...HEAD -- 'apps/site/' 'content/' is empty, and this PR edits content/, so it forces the real build (as does the merge queue, which always builds).

The unlock is now available — @objectstack/spec@17.2.0 was published 07:00:38Z with the browser condition that objectui#5668's own restart-when names. The residual lockfile refresh belongs to that card, ⛔ not to this seat. Once main is green this branch takes the base in (⛔ merge, not rebase) and CI re-runs.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 23, 2026 10:11
@os-zhuang
os-zhuang added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit cd6a328Aug 23, 2026
21 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5409-changelog-dispatch-only branch August 23, 2026 10:11
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cdconfigurationdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

changelog.yml has 0 runs too — it waits on release events this repo's own releases can never emit

2 participants

@os-zhuang@claude