From 77c91c87b818e40e014515dddf805c931c918528 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Wed, 20 May 2026 00:44:40 +0200 Subject: [PATCH] fix(ci): publish the pre-built tarball instead of re-packing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release workflow built the tarball twice — once via pnpm pack in artifacts:check (leaving it at dist/artifacts/npm/) and again inside @semantic-release/npm's prepare step, which then tried to fs-extra move npm pack's output into the same directory and crashed with "dest already exists". On top of being a publish blocker, that meant the published tarball was different from the one smoke-tested in artifacts:check. Drop @semantic-release/npm and publish the exact tarball that artifacts:check verified via an exec publishCmd: npm publish dist/artifacts/npm/kaelio-ktx-.tgz \ --tag --access public --provenance Auth uses OIDC trusted publishing — the workflow already grants id-token: write and setup-node configures the registry, and release-workflow.test.mjs asserts NODE_AUTH_TOKEN is not set. --- scripts/semantic-release-config.cjs | 17 ++++------------- scripts/semantic-release-config.test.mjs | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/scripts/semantic-release-config.cjs b/scripts/semantic-release-config.cjs index e9ec9cc5..fb1f959d 100644 --- a/scripts/semantic-release-config.cjs +++ b/scripts/semantic-release-config.cjs @@ -166,19 +166,10 @@ function createReleaseConfig(env = process.env) { 'pnpm run artifacts:check', 'pnpm run release:readiness', ].join(' && '), - }, - ], - [ - '@semantic-release/npm', - { - pkgRoot: 'dist/public-npm-package', - tarballDir: 'dist/artifacts/npm', - }, - ], - [ - '@semantic-release/exec', - { - publishCmd: 'pnpm run release:published-smoke', + publishCmd: [ + `npm publish dist/artifacts/npm/kaelio-ktx-\${nextRelease.version}.tgz --tag ${tag} --access public --provenance`, + 'pnpm run release:published-smoke', + ].join(' && '), }, ], ...releaseGitPlugins(kind), diff --git a/scripts/semantic-release-config.test.mjs b/scripts/semantic-release-config.test.mjs index 99cd53c4..c62f0fdf 100644 --- a/scripts/semantic-release-config.test.mjs +++ b/scripts/semantic-release-config.test.mjs @@ -27,20 +27,20 @@ describe('semantic-release config', () => { ]); const config = createReleaseConfig({ KTX_RELEASE_KIND: 'rc', GITHUB_REF_NAME: 'main' }); - assert.deepEqual( + assert.equal( config.plugins.find((plugin) => Array.isArray(plugin) && plugin[0] === '@semantic-release/npm'), - [ - '@semantic-release/npm', - { - pkgRoot: 'dist/public-npm-package', - tarballDir: 'dist/artifacts/npm', - }, - ], + undefined, + '@semantic-release/npm must not run; the exec publishCmd publishes the pre-built tarball', ); assert.match( releaseExecOptions(config).prepareCmd, /update-public-release-version\.mjs "\$\{nextRelease\.version\}" "next"/, ); + assert.match( + releaseExecOptions(config).publishCmd, + /^npm publish dist\/artifacts\/npm\/kaelio-ktx-\$\{nextRelease\.version\}\.tgz --tag next --access public --provenance/, + ); + assert.match(releaseExecOptions(config).publishCmd, /pnpm run release:published-smoke/); assert.doesNotMatch(JSON.stringify(config.plugins), /release:npm-publish/); const releaseFilePluginNames = pluginNames(config).filter( (plugin) => plugin === '@semantic-release/changelog' || plugin === '@semantic-release/git', @@ -62,6 +62,10 @@ describe('semantic-release config', () => { releaseExecOptions(config).prepareCmd, /update-public-release-version\.mjs "\$\{nextRelease\.version\}" "latest"/, ); + assert.match( + releaseExecOptions(config).publishCmd, + /^npm publish dist\/artifacts\/npm\/kaelio-ktx-\$\{nextRelease\.version\}\.tgz --tag latest --access public --provenance/, + ); assert.equal(config.plugins.includes('./scripts/semantic-release-version-policy.cjs'), false); });