From 0925163989cbb993674101260f671836ea10bb97 Mon Sep 17 00:00:00 2001 From: cadamsdev Date: Wed, 14 Jan 2026 22:59:46 -0500 Subject: [PATCH] fix passing --access argument --- .changeset/brave-forks-prove.md | 5 ++ src/publish.test.ts | 95 +++++++++++++++++++++++++++++++++ src/publish.ts | 20 ++++--- 3 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 .changeset/brave-forks-prove.md diff --git a/.changeset/brave-forks-prove.md b/.changeset/brave-forks-prove.md new file mode 100644 index 0000000..b330e0b --- /dev/null +++ b/.changeset/brave-forks-prove.md @@ -0,0 +1,5 @@ +--- +"@lazy-release/changesets": fix +--- + +Fix passing --access argument to publish command. It now uses the publishConfig.access in the package.json. If that's not set then it uses the access in the changeset config. diff --git a/src/publish.test.ts b/src/publish.test.ts index 28b3c31..3b1893a 100644 --- a/src/publish.test.ts +++ b/src/publish.test.ts @@ -374,6 +374,7 @@ describe('publish command', () => { const calls = (childProcess.execSync as any).mock.calls; const publishCall = calls.find((call: any) => call[0].includes('npm publish')); expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access restricted'); }); test('should use yarn for publishing', async () => { @@ -393,6 +394,7 @@ describe('publish command', () => { const calls = (childProcess.execSync as any).mock.calls; const publishCall = calls.find((call: any) => call[0].includes('yarn publish')); expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access restricted'); }); test('should use pnpm for publishing', async () => { @@ -412,6 +414,7 @@ describe('publish command', () => { const calls = (childProcess.execSync as any).mock.calls; const publishCall = calls.find((call: any) => call[0].includes('pnpm publish')); expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access restricted'); }); test('should use bun for publishing', async () => { @@ -431,6 +434,98 @@ describe('publish command', () => { const calls = (childProcess.execSync as any).mock.calls; const publishCall = calls.find((call: any) => call[0].includes('bun publish')); expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access restricted'); + }); + + test('should use package publishConfig.access when available', async () => { + mock.module('./config.js', () => ({ + readConfig: () => ({ + access: 'restricted', + baseBranch: 'main', + updateInternalDependencies: 'patch', + ignore: [], + lazyChangesets: { + types: {}, + }, + }), + })); + spyOn(tinyglobby, 'globSync').mockReturnValue(['package.json']); + spyOn(fs, 'readFileSync').mockImplementation((path: any) => { + const pathStr = typeof path === 'string' ? path : path.toString(); + if (pathStr.includes('package.json')) { + return JSON.stringify({ + name: '@test/package', + version: '1.0.0', + publishConfig: { + access: 'public', + }, + }, null, 2); + } + if (pathStr.includes('CHANGELOG.md')) { + return `## 1.0.0\n\n### 🚀 feat\n- Test changeset`; + } + return ''; + }); + let execCallCount = 0; + spyOn(childProcess, 'execSync').mockImplementation((cmd: string) => { + execCallCount++; + if (cmd.includes('ls-remote')) { + throw new Error('Tag not found'); + } + return ''; + }); + spyOn(packageManagerDetector, 'detect').mockResolvedValue({ name: 'npm', agent: 'npm' }); + + await publish({ dryRun: false }); + + const calls = (childProcess.execSync as any).mock.calls; + const publishCall = calls.find((call: any) => call[0].includes('npm publish')); + expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access public'); + }); + + test('should publish with --access public when config access is public', async () => { + mock.module('./config.js', () => ({ + readConfig: () => ({ + access: 'public', + baseBranch: 'main', + updateInternalDependencies: 'patch', + ignore: [], + lazyChangesets: { + types: {}, + }, + }), + })); + spyOn(tinyglobby, 'globSync').mockReturnValue(['package.json']); + spyOn(fs, 'readFileSync').mockImplementation((path: any) => { + const pathStr = typeof path === 'string' ? path : path.toString(); + if (pathStr.includes('package.json')) { + return JSON.stringify({ + name: '@test/package', + version: '1.0.0', + }, null, 2); + } + if (pathStr.includes('CHANGELOG.md')) { + return `## 1.0.0\n\n### 🚀 feat\n- Test changeset`; + } + return ''; + }); + let execCallCount = 0; + spyOn(childProcess, 'execSync').mockImplementation((cmd: string) => { + execCallCount++; + if (cmd.includes('ls-remote')) { + throw new Error('Tag not found'); + } + return ''; + }); + spyOn(packageManagerDetector, 'detect').mockResolvedValue({ name: 'npm', agent: 'npm' }); + + await publish({ dryRun: false }); + + const calls = (childProcess.execSync as any).mock.calls; + const publishCall = calls.find((call: any) => call[0].includes('npm publish')); + expect(publishCall).toBeDefined(); + expect(publishCall[0]).toContain('--access public'); }); test('should warn for unsupported package manager', async () => { diff --git a/src/publish.ts b/src/publish.ts index ddbf542..fcde4d6 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -12,6 +12,7 @@ export interface PackageInfo { version: string; dir: string; isPrivate: boolean; + access?: 'public' | 'restricted'; } export async function publish({ dryRun = false } = {}) { @@ -30,7 +31,7 @@ export async function publish({ dryRun = false } = {}) { console.log(pc.dim('Found'), pc.cyan(`${packages.length} package(s)`)); for (const pkg of packages) { - await publishPackage(pkg, dryRun); + await publishPackage(pkg, dryRun, config); } if (dryRun) { @@ -68,13 +69,14 @@ async function findPackages(config: ChangesetConfig): Promise { version: packageVersion, dir: dirPath, isPrivate: packageJson.private === true, + access: packageJson.publishConfig?.access, }); } return packages; } -async function publishPackage(pkg: PackageInfo, dryRun: boolean) { +async function publishPackage(pkg: PackageInfo, dryRun: boolean, config: ChangesetConfig) { const isRoot = pkg.dir === '.' || pkg.dir === './'; const tag = isRoot ? `v${pkg.version}` : `${pkg.name}@${pkg.version}`; @@ -103,7 +105,7 @@ async function publishPackage(pkg: PackageInfo, dryRun: boolean) { } else if (dryRun) { console.log(pc.yellow('[DRY RUN]'), pc.dim('Would publish to npm')); } else { - await publishToNpm(pkg); + await publishToNpm(pkg, config); } if (dryRun) { @@ -135,7 +137,7 @@ async function tagExistsRemote(tag: string): Promise { } } -async function publishToNpm(pkg: PackageInfo) { +async function publishToNpm(pkg: PackageInfo, config: ChangesetConfig) { const detected = await detect(); if (!detected) { console.warn(pc.yellow('Could not detect package manager. Skipping npm publish.')); @@ -144,21 +146,23 @@ async function publishToNpm(pkg: PackageInfo) { const agent = detected.agent || detected.name; let publishCmd = ''; + const access = pkg.access || config.access; + const accessFlag = access === 'public' || access === 'restricted' ? `--access ${access}` : ''; switch (agent) { case 'npm': - publishCmd = 'npm publish'; + publishCmd = `npm publish ${accessFlag}`.trim(); break; case 'yarn': case 'yarn@berry': - publishCmd = 'yarn publish --non-interactive'; + publishCmd = `yarn publish --non-interactive ${accessFlag}`.trim(); break; case 'pnpm': case 'pnpm@6': - publishCmd = 'pnpm publish --no-git-checks'; + publishCmd = `pnpm publish --no-git-checks ${accessFlag}`.trim(); break; case 'bun': - publishCmd = 'bun publish'; + publishCmd = `bun publish ${accessFlag}`.trim(); break; default: console.warn(pc.yellow(`Unsupported package manager: ${agent}. Skipping npm publish.`));