Skip to content

feat: release @decocms/tanstack and @decocms/nextjs in lockstep with blocks at 8.3.0 - #699

Draft
tlgimenes wants to merge 16 commits into
feat/nextjs-v8from
feat/release-8-3
Draft

tlgimenes wants to merge 16 commits into
feat/nextjs-v8from
feat/release-8-3

Conversation

@tlgimenes

@tlgimenes tlgimenes commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #697 (P5). Part 6 of the v8 framework packages stack: #693 → #694 → #695 → #696 → #697 → this.

What changes

  • Lockstep publish. .releaserc.json's publish allowlist is blocks tanstack nextjs plus the seven apps-*. Every release publishes all ten at one version, even a package with no change. @decocms/tanstack and @decocms/nextjs publish from main on latest.
  • Peer ranges. The apps-* took @decocms/blocks as workspace:* in dependencies, which publishes as an exact pin, so a blocks patch release put a second blocks next to an app. They now take it as a peer, ^8.3.0, with workspace:* in devDependencies, as the bindings already do.
  • scripts/sync-versions.mjs writes the release version, rewrites workspace: ranges only in devDependencies, and refuses to release when an in-repo package is a plain dependency or a peer floor is above the release version.
  • tests/release.test.ts (38 tests): allowlist = packages/, blocks then the bindings first; every dependent takes blocks as ^8.3.0 peer; the sync on a copy of the manifests (8.3.0, a later 8.4.1, refusing 8.2.4 and a plain dependency). New since the PO review: for each of the ten packages, every export target (through conditional branches) has the types + source + default shape (or is plain JS shipped from src, as @decocms/nextjs/config), and npm pack would ship each of those files and no test or fixture. That covers the clients' new helper subpaths, @decocms/apps-vtex/image and @decocms/apps-shopify/image (feat: @decocms/blocks/image (platform-neutral) with VTEX and Shopify image providers in their packages #694); a mutation that drops src/image.ts from apps-vtex's files fails it.
  • CI. The build job's plain-Node import of every built export already walks every subpath, so it imports the new /image subpaths; the job now also runs tests/release.test.ts against the dist it built.
  • Docs. CLAUDE.md (allowlist, peer-range rule), README (the packages publish tsc output in dist/ plus a source condition, not plain .ts), release workflow comment (ten packages).

Dry run (repeated after the PO review)

In a throwaway clone (deleted afterwards), origin/main plus this stack squashed into one feat: commit, with the real config (GitHub plugin included; dry run only):

  • semantic-release --dry-run --no-ci: "The next release version is 8.3.0" (last tag blocks-v8.2.3).
  • The prepare step (VERSION=8.3.0 node scripts/sync-versions.mjs && bun run build): all ten manifests at 8.3.0, no workspace: left; tanstack, nextjs and every apps-* have peerDependencies["@decocms/blocks"] = "^8.3.0".
  • The publish step rendered from the config, with npm publish --dry-run: + @decocms/blocks@8.3.0, + @decocms/tanstack@8.3.0, + @decocms/nextjs@8.3.0 and the seven apps, all "with tag latest". No test files in the binding tarballs.
  • The apps-vtex and apps-shopify tarballs hold dist/image.{js,d.ts} (+ maps) and src/image.ts; the blocks tarball has no studio module; the nextjs tarball has its own draft, studio and StudioBridge modules.
  • The ten tarballs installed together with npm: npm ls @decocms/blocks shows one copy, every other package deduped (one @decocms/blocks/package.json on disk). Plain Node imported all 38 exports of the installed packages, /image subpaths included, with no failure; @decocms/blocks exports neither STUDIO_ORIGINS nor DRAFT_PARAM, and @decocms/nextjs' and @decocms/tanstack's copies are equal. No package was published.

Dry run after the PO decisions of 2026-10-15

Re-run after merging #697 (with #693–#696's decisions: NODE_ENV dev mode, isNextDev removed, first-match multivariate, deco schema --check, leading asset-host strip, edit shortcut on by default). Throwaway local repos, deleted afterwards; nothing was pushed or published:

  • semantic-release --dry-run --no-ci (commit analyzer and release notes, against a local bare mirror of the repo with its tags): last tag blocks-v8.2.3, "The next release version is 8.3.0".
  • Prepare step: all ten manifests at 8.3.0, no workspace: left; build passes.
  • npm publish --dry-run --tag latest for all ten: each exits 0. The nextjs tarball (54 files) has no dev module.
  • blocks, tanstack, nextjs, apps-vtex and apps-shopify installed together: one @decocms/blocks (the others deduped); plain Node imported all 31 of their exports, and @decocms/nextjs exports no isNextDev.
  • tests/release.test.ts: 38/38.

Tests

  • bun run check, bun run build, skills:check, skills:readme:check: pass.
  • bun run test: 2,396 passed, 5 failed, all known or load timeouts: DS-2 in delivery.cli.test.ts, and timeouts under full-suite load in delivery.cli.test.ts DS-5, guides.cli.test.ts tr-13, protocol/storage/fs/git.test.ts and schema.test.ts. Rerun on their own: the first three files pass apart from DS-2, and schema.test.ts passes 58/58 alone.

For the PO: landing and npm commands (not run)

Landing as 8.3.0. semantic-release releases on every push to main. To ship all three at 8.3.0 together, land the stack as one commit on main: merge this PR into #697, #697 into #696, and so on down to #693, then squash #693 into main with a feat: title. If the PRs land on main one by one, P1 alone becomes 8.3.0 and the bindings first publish at a later minor (their ^8.3.0 peer would then also need raising to that version). If another feat: reaches main first, the release is 8.4.0: raise the peer floors in this PR to ^8.4.0 before landing.

Before landing (7.x). Merge #698 first (7.x branch). Today 7.x publishes both bindings with --tag latest, so the next 7.x release would take latest back from 8.3.0. #698 moves them to latest-7.

npm commands, run by the PO with an npm owner login, before the stack lands:

# 1. Keep v7 installable by tag. Use 7.79.6, or the newest 7.x if a 7.x release has run since
#    (merging #698 releases 7.79.7 and sets latest-7 itself; then skip this step).
npm dist-tag add @decocms/tanstack@7.79.6 latest-7
npm dist-tag add @decocms/nextjs@7.79.6 latest-7

# 2. Rewrite the 8.0.0 deprecation (it says "use @latest (7.x)", which is wrong once latest is 8.3.0).
npm deprecate @decocms/tanstack@8.0.0 "Published by mistake. Use ^8.3.0 for v8, or 7.x for v7."
npm deprecate @decocms/nextjs@8.0.0 "Published by mistake. Use ^8.3.0 for v8, or 7.x for v7."

# 3. Deprecate the two prereleases (not deprecated today).
npm deprecate @decocms/tanstack@"8.0.0-next.0 || 8.1.0-next.0" "Prerelease. Use ^8.3.0 for v8, or 7.x for v7."
npm deprecate @decocms/nextjs@"8.0.0-next.0 || 8.1.0-next.0" "Prerelease. Use ^8.3.0 for v8, or 7.x for v7."

latest moves to 8.3.0 by itself when the release publishes; no command is needed for it. Check afterwards:

npm view @decocms/tanstack dist-tags   # { latest: '8.3.0', 'latest-7': '7.79.x' }
npm view @decocms/nextjs dist-tags

Other things to know:

  • Trusted Publishing. The bindings were last published from the 7.x branch. npm's trusted publisher names the repo and the workflow file (release.yml), not a branch, so main should be accepted. If either package's trusted publisher is tied to a GitHub environment, add it for main before landing, or its publish fails while the other nine succeed.
  • No CI check against the oldest blocks in range yet. The plan lists one. It needs blocks 8.3.0 on npm first, so it's a follow-up. Until then, the rule (CLAUDE.md) is to raise every peer floor together when a package starts using a newer blocks API, and sync-versions.mjs refuses a floor above the release.
  • npm publish prints "repository.url was normalized" for every package, as it already does today. It's harmless.

https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig

Main refresh (2026-10-17, 6ce49dcf)

🤖 Generated with Claude Code

https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu

…tep with blocks, and take blocks as a caret peer

- .releaserc.json: the publish allowlist is blocks, tanstack, nextjs and the
  seven apps-*; every release publishes all ten at one version.
- apps-*: @decocms/blocks moves from dependencies (workspace:*, published as
  an exact pin) to peerDependencies "^8.3.0", with the workspace copy in
  devDependencies, as the bindings already have it.
- scripts/sync-versions.mjs rewrites only devDependencies' workspace:
  ranges and refuses an in-repo dependency or a peer floor above the release.
- tests/release.test.ts: allowlist = packages/, ranges, and the sync on a
  copy of the manifests.
- CLAUDE.md, README and the release workflow's comments name the ten
  packages and the dist + source format.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
tlgimenes and others added 13 commits October 14, 2026 16:13
Brings in the PO review down the stack: blocks without the draft names or
Studio's origins (#693), the platform-neutral @decocms/blocks/image with the
@decocms/apps-vtex/image and @decocms/apps-shopify/image helper subpaths
(#694), StudioBridge's required trustedOrigins (#695), and each binding's own
copy of the draft names and Studio's origins (#696, #697).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
tests/release.test.ts now also checks, for each of the ten published
packages, every export target through its conditional branches: types +
source + default under dist/ and src/ (or plain JS shipped from src, as
@decocms/nextjs/config), and that `npm pack` would ship each of those files
and no test or fixture. This covers the clients' new helper subpaths
(@decocms/apps-vtex/image, @decocms/apps-shopify/image). CI's build job runs
the file after the plain-Node import of every built export, which already
walks every subpath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Brings P1-P5's PO decisions (NODE_ENV dev mode and isNextDev removed,
first-match multivariate, deco schema --check, decoCdn leading strip,
edit shortcut on by default).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
tlgimenes added a commit that referenced this pull request Oct 17, 2026
#698)

## Why

From 8.3.0, `main` publishes `@decocms/tanstack` and `@decocms/nextjs`
v8 on npm's `latest` (#699's release mechanics). Today
this branch publishes both with `--tag latest`, so the first 7.x release
after 8.3.0 would take `latest` back to a 7.x version and new sites
would install v7.

## What changes

- `.releaserc.json`: `tanstack` and `nextjs` join `blocks` and the
shared apps in `V7_CHANNEL_PKGS`, so 7.x releases publish them on
`latest-7`. The other v7-only packages (`blocks-admin`, `blocks-cli`,
`eitri`, the v7-only apps) keep `latest`.
- `release.yml`'s comment and the install docs (`README.md`,
`packages/nextjs/README.md`) say `@decocms/tanstack@latest-7` /
`@decocms/nextjs@latest-7`.

Rendered publish step in dry-run mode (`DRY_RUN=true`):
`@decocms/tanstack@7.79.7 --tag latest-7`, `@decocms/nextjs@7.79.7 --tag
latest-7`, `@decocms/blocks-admin@7.79.7 --tag latest`, and the rest as
before.

## Order

Merge this before the v8 stack lands on `main`, or at the latest before
any other 7.x release after 8.3.0. Merging it releases 7.79.7 of the 7.x
packages (a `fix:`), which puts `latest-7` on 7.79.7 for both bindings;
the `npm dist-tag add … latest-7` commands in the v8 release PR are then
already done (don't move `latest-7` back to 7.79.6).

Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Stops the 7.x line from republishing `@decocms/tanstack` and
`@decocms/nextjs` on npm's `latest`, which has carried 8.x since 8.3.0.
Both bindings now publish on the `latest-7` dist-tag alongside
`@decocms/blocks` and the apps v8 also ships, so the first 7.x release
won't pull `latest` back to a 7.x version.

**Rollout**
- Merge before any other 7.x release after 8.3.0; the publish itself
moves `latest-7` to 7.79.7 for both bindings, which covers the `npm
dist-tag add` steps in the v8 release.

**Documentation**
- Install commands in `README.md` and `packages/nextjs/README.md` now
use `@latest-7` for both bindings.

<sup>Written for commit ccc4f72.
Summary will update on new commits.</sup>

<a href="https://cubic.dev/pr/decocms/blocks/pull/698?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/decocms/blocks/698?returnTo=https%3A%2F%2Fgithub.com%2Fdecocms%2Fblocks%2Fpull%2F698&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZsmzpZ2zahRBoATBb2tBu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant