From 0224a2adc40fc0fa17c4b4a1eee6a8176aa9e422 Mon Sep 17 00:00:00 2001 From: "Ricardo Q. Bazan" Date: Sun, 18 Oct 2026 12:08:36 -0500 Subject: [PATCH 1/2] fix: stop shipping Changesets in the vland monorepo template Every package in the monorepo template is private and it has no release workflow, so Changesets had nothing to version or publish. Only the library template ships ready to publish to npm. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EZVC7xzzsEmByszmfff4u2 --- .changeset/vland-monorepo-no-changesets.md | 5 +++++ .../test/integration/init-templates.test.ts | 22 ++++++++++++++++++- vland/templates/monorepo/.changeset/README.md | 3 --- .../templates/monorepo/.changeset/config.json | 12 ---------- vland/templates/monorepo/package.json | 2 -- 5 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 .changeset/vland-monorepo-no-changesets.md delete mode 100644 vland/templates/monorepo/.changeset/README.md delete mode 100644 vland/templates/monorepo/.changeset/config.json diff --git a/.changeset/vland-monorepo-no-changesets.md b/.changeset/vland-monorepo-no-changesets.md new file mode 100644 index 00000000..70fdc104 --- /dev/null +++ b/.changeset/vland-monorepo-no-changesets.md @@ -0,0 +1,5 @@ +--- +"@variablelab/vland": patch +--- + +`vland init -t monorepo` no longer ships Changesets (`.changeset/` and the `@changesets/*` devDependencies). Every package in the monorepo is private and it has no release workflow, so Changesets had nothing to version or publish. Only the `library` template ships ready to publish to npm. diff --git a/vland/cli/test/integration/init-templates.test.ts b/vland/cli/test/integration/init-templates.test.ts index b655b7c8..0e889df7 100644 --- a/vland/cli/test/integration/init-templates.test.ts +++ b/vland/cli/test/integration/init-templates.test.ts @@ -126,8 +126,28 @@ describe("vland init (template scaffolding)", () => { const typesPkg = JSON.parse(await readFile(path.join(projectDir, "packages", "types", "package.json"), "utf8")); expect(typesPkg.name).toBe(`@${name}/types`); + }); - expect(await readChangelogRepo(projectDir)).toBe(`variableland/${name}`); + test("monorepo: ships no Changesets, since every package is private and nothing publishes", async () => { + const name = "no-release"; + const r = cli(`init ${name} -t monorepo --no-install --no-git`, { cwd: fixture.dir }); + expect(r.status).toBe(0); + + // Changesets skips private packages, so a release setup here would have nothing to version or publish. + const projectDir = path.join(fixture.dir, name); + for (const dir of ["", "apps/api", "apps/web", "packages/types"]) { + const pkg = JSON.parse(await readFile(path.join(projectDir, dir, "package.json"), "utf8")); + expect(pkg.private, `${dir || "root"} package.json`).toBe(true); + } + + const mentions: string[] = []; + for (const entry of await readdir(projectDir, { recursive: true, withFileTypes: true })) { + if (!entry.isFile()) continue; + const file = path.join(entry.parentPath, entry.name); + const relative = path.relative(projectDir, file); + if (/changeset/i.test(relative) || /changeset/i.test(await readFile(file, "utf8"))) mentions.push(relative); + } + expect(mentions).toEqual([]); }); test.each(TEMPLATES)("%s: pins node and pnpm with mise and a lockfile", async (template) => { diff --git a/vland/templates/monorepo/.changeset/README.md b/vland/templates/monorepo/.changeset/README.md deleted file mode 100644 index f9634058..00000000 --- a/vland/templates/monorepo/.changeset/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Changesets - -This folder is managed by [changesets](https://github.com/changesets/changesets). Drop one Markdown file per user-facing change here. See the docs for the full lifecycle. diff --git a/vland/templates/monorepo/.changeset/config.json b/vland/templates/monorepo/.changeset/config.json deleted file mode 100644 index 0d9fa09e..00000000 --- a/vland/templates/monorepo/.changeset/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@4.0.1/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "{{githubOwner}}/{{projectName}}" }], - "commit": true, - "fixed": [], - "linked": [], - "access": "restricted", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": [], - "format": false -} diff --git a/vland/templates/monorepo/package.json b/vland/templates/monorepo/package.json index 70a0c1a1..bc1c05d4 100644 --- a/vland/templates/monorepo/package.json +++ b/vland/templates/monorepo/package.json @@ -12,8 +12,6 @@ "test": "turbo run test" }, "devDependencies": { - "@changesets/changelog-github": "1.0.1", - "@changesets/cli": "3.0.3", "@rrlab/cli": "^1.3.4", "@types/node": "^24.0.0", "lefthook": "2.1.1", From 5bbe2806380e1c240455a61bbd48bb8fdc44f406 Mon Sep 17 00:00:00 2001 From: "Ricardo Q. Bazan" Date: Sun, 18 Oct 2026 12:10:22 -0500 Subject: [PATCH 2/2] fix: allow lefthook's build with allowBuilds in the vland templates pnpm prefers allowBuilds since 10.26 and pnpm 11 removed onlyBuiltDependencies, so a generated project that moves to pnpm 11 fails its install on lefthook's build script and never gets the git hooks. The monorepo also drops @biomejs/biome, which has had no install script since Biome 2. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EZVC7xzzsEmByszmfff4u2 --- .changeset/vland-templates-allow-builds.md | 5 +++++ vland/cli/test/integration/init-templates.test.ts | 14 ++++++++++++++ vland/templates/backend/pnpm-workspace.yaml | 5 +++-- vland/templates/library/pnpm-workspace.yaml | 5 +++-- vland/templates/monorepo/pnpm-workspace.yaml | 7 ++++--- 5 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 .changeset/vland-templates-allow-builds.md diff --git a/.changeset/vland-templates-allow-builds.md b/.changeset/vland-templates-allow-builds.md new file mode 100644 index 00000000..c26f5381 --- /dev/null +++ b/.changeset/vland-templates-allow-builds.md @@ -0,0 +1,5 @@ +--- +"@variablelab/vland": patch +--- + +Projects from `vland init` let lefthook's install script run through pnpm's `allowBuilds` setting, which pnpm prefers since 10.26, instead of `onlyBuiltDependencies`, which pnpm 11 removed. A generated project that moved to pnpm 11 would have had its `onlyBuiltDependencies` ignored, so `pnpm install` failed with `ERR_PNPM_IGNORED_BUILDS` and the git hooks never got installed. The monorepo no longer lists `@biomejs/biome`, which has had no install script since Biome 2. diff --git a/vland/cli/test/integration/init-templates.test.ts b/vland/cli/test/integration/init-templates.test.ts index 0e889df7..e4534d40 100644 --- a/vland/cli/test/integration/init-templates.test.ts +++ b/vland/cli/test/integration/init-templates.test.ts @@ -173,6 +173,20 @@ describe("vland init (template scaffolding)", () => { } }); + test.each(TEMPLATES)("%s: lets lefthook's postinstall run with allowBuilds, which pnpm 11 still reads", async (template) => { + const name = `builds-${template}`; + const r = cli(`init ${name} -t ${template} --no-install --no-git`, { cwd: fixture.dir }); + expect(r.status).toBe(0); + + // pnpm 11 drops onlyBuiltDependencies, then fails the install on lefthook's unapproved build script. + const workspace = await readFile(path.join(fixture.dir, name, "pnpm-workspace.yaml"), "utf8"); + expect(workspace).toMatch(/^allowBuilds:\n {2}lefthook: true$/m); + expect(workspace).not.toContain("onlyBuiltDependencies"); + expect(workspace).not.toContain("@biomejs/biome"); + // A lefthook restored from the side-effects cache skips its postinstall, so no git hooks get installed. + expect(workspace).toMatch(/^sideEffectsCache: false$/m); + }); + test.each([ ["library", ""], ["library", "--visibility=private"], diff --git a/vland/templates/backend/pnpm-workspace.yaml b/vland/templates/backend/pnpm-workspace.yaml index 7630bb68..820589d1 100644 --- a/vland/templates/backend/pnpm-workspace.yaml +++ b/vland/templates/backend/pnpm-workspace.yaml @@ -1,5 +1,6 @@ -onlyBuiltDependencies: - - lefthook +# Dependencies whose build scripts pnpm runs on install; allowBuilds needs pnpm >= 10.26. +allowBuilds: + lefthook: true # lefthook's postinstall installs the git hooks, so it has to run on every install: # with the side-effects cache on, a lefthook already built for another project skips it. diff --git a/vland/templates/library/pnpm-workspace.yaml b/vland/templates/library/pnpm-workspace.yaml index 7630bb68..820589d1 100644 --- a/vland/templates/library/pnpm-workspace.yaml +++ b/vland/templates/library/pnpm-workspace.yaml @@ -1,5 +1,6 @@ -onlyBuiltDependencies: - - lefthook +# Dependencies whose build scripts pnpm runs on install; allowBuilds needs pnpm >= 10.26. +allowBuilds: + lefthook: true # lefthook's postinstall installs the git hooks, so it has to run on every install: # with the side-effects cache on, a lefthook already built for another project skips it. diff --git a/vland/templates/monorepo/pnpm-workspace.yaml b/vland/templates/monorepo/pnpm-workspace.yaml index 80432015..82da215f 100644 --- a/vland/templates/monorepo/pnpm-workspace.yaml +++ b/vland/templates/monorepo/pnpm-workspace.yaml @@ -1,9 +1,10 @@ packages: - apps/* - packages/* -onlyBuiltDependencies: - - "@biomejs/biome" - - lefthook + +# Dependencies whose build scripts pnpm runs on install; allowBuilds needs pnpm >= 10.26. +allowBuilds: + lefthook: true # lefthook's postinstall installs the git hooks, so it has to run on every install: # with the side-effects cache on, a lefthook already built for another project skips it.