Repository navigation
fix(release): the publish lane pushes the version's git tags and creates its GitHub Releases itself — changesets/action@v1 finds no New tag: line under CLI v3 (objectui#11596) - #11597
Merged
Conversation
… the console and runner sheets take source(none), and two censuses exclude it (objectui#11586) The 17.7.0 release head (#5400) was red in four Test shards while main was green. All four failures come from the CHANGELOG.md files that `pnpm changeset:version` writes: - `apps/console/src/index.css` and `packages/runner/src/index.css` still left Tailwind's automatic source detection on. Detection scans prose in the package directory, CHANGELOG.md included. On the release head it compiled 11 rules into the console sheet and 5 into the runner sheet out of changelog text. Both entries now take `source(none)`, as `packages/components` did in objectui#9569. An ablation on main finds that every rule detection alone supplied came from a .md file: `.w-100` from a console docs proposal, and `.flex-shrink-0` and `.isolate` from the runner changelog. - The `AppComponentSchema.actions` census and the single-`bind` census `git grep` over CHANGELOG.md. They now exclude it with `:!*CHANGELOG.md`, the spelling the sibling censuses already use. Each stylesheet test gains a pin that compiles the entry from the package root and from an empty directory and requires the same rules. The runner test also pins that its changelog-only `flex-shrink-0` stays out. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
…lusion — the retired 8800 spelling must appear nowhere (objectui#11586) The census comment added in the previous commit named the retired symbol's own pin by file name. objectui#8800's spelling census allows that spelling in nothing but its listed exclusions, so the citation tripped it. The comment now cites a sibling census that uses the same `:!*CHANGELOG.md` spelling. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
…e a CHANGELOG — the runner pin reads it as a control, the 7344 census only excludes it (objectui#11586) `markdown-test-inputs` audits every test that resolves a markdown path. This change made two tests new candidates: - `published-stylesheet-sources.test.ts` reads `packages/runner/CHANGELOG.md` to prove its prose-only probe still exists. It gets the same entry as the components scan test (objectui#9569). - `handler-keys-string-any-mirrors-7344.test.ts` reads no markdown. Its only `.md` literal is the `:!*CHANGELOG.md` pathspec, and its walk lists the zod mirror sources. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
…lease-steps-ynhz3j
…elease #5400 already consumed it The branch's earlier PR (#11587) was squash-merged and its changeset was consumed by the 17.7.0 release commit (b493919, #5400). Merging origin/main into this branch kept the branch-side copy, which would re-announce an already-published change in the next release. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
…e GitHub Release per public package, bodies truncated to the API limit, plus a tag list for the push step (objectui#11596) Ported from objectstack's scripts/release-github-releases.mjs (at 7d0781482): idempotent create-or-update by tag, convergence on a racing writer's 422 already_exists, a duplicate-Release audit that never deletes, and every body truncated to the Releases API's 125,000-character limit with a link to the full CHANGELOG entry. Adapted to this workspace: - package enumeration reads pnpm-workspace.yaml through the existing workspacePackageDirs (check-side-effects-array.mjs); private packages (the vscode extension, the site, the examples) are never targets; - `--print-tags` prints the `<pkg>@<version>` tags the release owes, for the workflow's tag-push step; - an empty release set is an error, not a quiet no-op; - `--dry-run` prints the planned tag -> Release list with body sizes and calls no API. The self-test's oversized repro is real: @object-ui/types' 17.7.0 entry. scripts/__tests__/release-github-releases.test.ts runs the self-test and the dry-run (no token, unreachable API URL) and pins the workflow wiring the next commit adds. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
…its GitHub Releases itself — changesets/action@v1 finds no `New tag:` line under CLI v3 (objectui#11596) changesets/action@v1 pushes a tag and creates a Release only for the packages whose `New tag: <pkg>@<version>` line it parses from the publish script's stdout. @changesets/cli v3 (objectui#5296) prints none, so 17.6.0 and 17.7.0 reached npm with no git tag and no GitHub Release while every step stayed green. Two steps after "Verify the release reached npm", on the publish lane only (`push`, gated on the publish step's and the npm check's outcome, under `!cancelled()`): - "Push the release tags": pushes exactly the `<pkg>@<version>` tags `changeset publish` created on the runner (the list `release-github-releases.mjs --print-tags` prints), in one push, and fails naming any that is missing; - "Create GitHub Releases": runs scripts/release-github-releases.mjs with RELEASE_VERSION = needs.lane.outputs.manifest_version. changesets/action stays at @v1. The workflow's comments that said v1 creates the tags and Releases now say what happens, and the CI guide's Changeset Release section documents both steps. Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL Co-authored-by: Claude <noreply@anthropic.com>
hotlong
marked this pull request as ready for review
October 4, 2026 05:34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #11596.
What was wrong
changeset-release.ymlpublishes throughchangesets/action@v1, and v1'srunPublish(read at v1.9.0,src/run.ts) pushes a tag and creates a GitHub Release only for the packages whoseNew tag: PKG@VERSIONline it parses out of the publish script's stdout.@changesets/cliv3 (objectui#5296) prints no such line. Itschangeset publishstill creates the annotatedPKG@VERSIONtags on the runner (createGitTagsin itspublish), and those tags were never pushed.git ls-remote --tags originlists no@17.6.0or@17.7.0tag, andGET /repos/objectstack-ai/objectui/releases/tags/%40object-ui%2Fcore%4017.7.0answers 404 (17.5.0 answers 200).@object-ui/app-shell@17.5.0has a tag but no Release (38 of the 39 17.5.0 Releases exist). Its 17.5.0 CHANGELOG entry is 158,203 characters, over the Releases API's 125,000-character limit. objectstack hit the same limit (objectstack#4900), and the ported script was written for it.What this PR changes
scripts/release-github-releases.mjs, ported from objectstack's script of the same name at7d0781482. It creates one Release per public package from that package's CHANGELOG entry. It looks the Release up by tag first, so a re-run updates instead of re-creating. It converges when a concurrent writer's POST answers 422already_exists, and its duplicate-Release audit never deletes anything. Bodies are truncated at a line boundary to the API limit, with fences balanced and a link to the full entry. Adapted to this repo:pnpm-workspace.yamlthrough the existingworkspacePackageDirs, and private packages are skipped. The self-test checks the release set against.changeset/config.json'sfixedgroup minus its private members, comparing both ways.--print-tagsprints thePKG@VERSIONtags owed, one per line. The push step reads this list.--dry-runprints the planned tag → Release list with body sizes and makes no API call.@object-ui/types17.7.0 entry, over 1,000,000 characters. It has 15 batteries with per-battery floors..github/workflows/changeset-release.ymlgets two new steps afterVerify the release reached npm(which now hasid: verify-npm). Both steps have the same condition:${{ !cancelled() && github.event_name == 'push' && steps.changesets-publish.outcome == 'success' && steps.verify-npm.outcome == 'success' }}.On
schedule/workflow_dispatchboth outcomes areskipped, so neither step can run there. A version already on npm never reaches the job (the existing job guard). Both steps takeRELEASE_VERSION: ${{ needs.lane.outputs.manifest_version }}.--print-tagsnames that exist locally, in onegit push origin refs/tags/...(objectstack#2191). If any owed tag is missing locally, the step fails and names it.node scripts/release-github-releases.mjswithGITHUB_TOKEN. It runs after the tag push. A Release POSTed for a tag missing from the remote makes the API create that tag as a lightweight tag attarget_commitish.releasejob declares nopermissions:of its own, so it inherits the workflow-levelcontents: write. That covers both the tag push and the Release create.changesets/actionstays at@v1, andcreateGithubReleasesstays at its default. Under CLI v3 the action's own Release path never runs. If it ever does again, the script updates the Releases it finds instead of failing.gitsweep (now listinggit rev-parseandgit push), theid:note, property (2) of the@v1pin, the feat: persist ViewConfigPanel draft to backend via DataSource.updateViewConfig #678 item and the clear-step paragraph. Line addresses were not rewritten.content/docs/guide/ci-cd-pipeline.md: new "Tags and GitHub Releases" subsection under Changeset Release. The command-parity pin needs the section to name the script, and it does.scripts/__tests__/release-github-releases.test.ts(10 tests):--self-test.--print-tagsand--dry-runfor the anchor's current version, with no token and an unreachableGITHUB_API_URL. The plan must equal the tag list.Publish to npm→ npm check → tag push → Releases; every condition clause, with no||,schedule,workflow_dispatchoralways();RELEASE_VERSIONfrom the lane output; the Release step running the script bare (not--dry-run); one tag-ref push with no--tags,--force,--deleteorHEAD; effectivecontents: write; and the job's npm guard.Deviations from the suggested route, with reasons
git config user.*in the push step. The tags are created inside the action step, after v1's defaultsetupGitUserhas configured the identity. A push creates no object, so an identity set in the push step would never be used. objectstack configures one because it runschangeset publishitself.git push origin --tags. The step pushes only this version's tags, and it fails loudly whenchangeset publishleft one out. A bare--tagspush answersEverything up-to-dateeither way.RELEASE_VERSIONwould let the step report success having done nothing.--dry-runfor 17.7.0GITHUB_REPOSITORY=objectstack-ai/objectui GITHUB_SHA=b493919c7 RELEASE_VERSION=17.7.0 node scripts/release-github-releases.mjs --dry-run, with no token in the environment:RELEASE_VERSION=17.7.0 node scripts/release-github-releases.mjs --print-tagsprints 39 tags, one for each line above, and exits 0. For comparison, the same dry-run plans 39 Releases with 1 truncated for 17.6.0, and 39 with 1 truncated for 17.5.0 (the truncated one is@object-ui/app-shell@17.5.0, 158,203 → 123,973 characters).Verification (at
ae09c39a3)node scripts/release-github-releases.mjs --self-test✓ ... 93 assertions(15 batteries, each at its floor)pnpm exec vitest run scripts/__tests__/release-github-releases.test.tsbash ../objectstack/scripts/pm/os-verify-lock.sh -c 'pnpm exec vitest run scripts/__tests__ --maxWorkers=2'Test Files 179 passed, 2 skipped (181),Tests 5452 passed, 2 skipped (5454),VERDICT command-exit 0node scripts/check-changeset-presence.mjsnode scripts/check-governed-queue-guard.mjs --testwith the 4 changed pathsNOT GOVERNEDpnpm check:entry-guard/check:new-line-citations/check:control-bytes/check:pre-install-import-graph/check:bash32-floor/check:action-ref-convention/check:shell-escape-residue/check:test-path-rootspnpm type-check:scripts--listFilesOnlyincludes the new test fileeslint --no-inline-configon the 2 new files.mjsgets none, because the repo's eslint config givesscripts/*.mjsno rules.Mutation check (one-off, not committed): I changed
if (targets.length === 0)toif (false && targets.length === 0)withobjectstack/scripts/ablation-replace.mjs. The self-test went red, with 1 of 93 failing: "with no RELEASE_VERSION the tag list refuses instead of printing nothing (exit 0)". The file was restored byte-for-byte to the HEAD blob083b5ea38, andgit diff HEADwas empty afterwards.Not verified:
actionlintis not available in this container. The workflow was checked by YAML parse and by the pin tests only.Notes for the backfill (not done here)
b65fe911de22c7e3a573b669c4cd5efbe34758f2(run 32739909630), 17.7.0b493919c71dc915afeb26c96338263f368e95c79(chore: release packages #5400 merge).RELEASE_VERSION=that version andGITHUB_SHA=that commit, sotarget_commitishand the CHANGELOG links point at it. A Release for a tag that is not on the remote yet makes the API create a lightweight tag atGITHUB_SHA.RELEASE_VERSION=17.5.0updates the 38 existing 17.5.0 Releases and creates the missing@object-ui/app-shell@17.5.0one.Branch housekeeping
This branch was reused from #11587, which was squash-merged. Merging
maininto it brought back.changeset/11586-tailwind-source-none-console-runner.md, which the 17.7.0 release commit had already consumed. A branch commit deletes it again, so it does not appear in this PR's diff.🤖 Generated with Claude Code
https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL
Generated by Claude Code