diff --git a/scripts/release-vscode-extension.mjs b/scripts/release-vscode-extension.mjs index f26cf55..7aba4e1 100644 --- a/scripts/release-vscode-extension.mjs +++ b/scripts/release-vscode-extension.mjs @@ -20,6 +20,13 @@ export function setVersion(version) { // and Open VSX (the registry Cursor and other VS Code-compatible editors // use). Requires VSCE_PAT / OVSX_PAT in the environment. export function publish() { + const missing = [!process.env.VSCE_PAT && 'VSCE_PAT', !process.env.OVSX_PAT && 'OVSX_PAT'].filter(Boolean); + if (missing.length > 0) { + throw new Error( + `Cannot publish the VS Code extension: ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} not set. Configure ${missing.length > 1 ? 'them' : 'it'} as repository secret(s) (see RELEASING.md) before dispatching a release.`, + ); + } + execFileSync('pnpm', ['--filter', 'hdrify-vscode-extension', 'run', 'build'], { stdio: 'inherit' }); execFileSync('pnpm', ['--filter', 'hdrify-vscode-extension', 'exec', 'vsce', 'package', '--no-dependencies'], { stdio: 'inherit', @@ -28,6 +35,7 @@ export function publish() { extensionPath, `hdrify-vscode-extension-${JSON.parse(readFileSync(resolve(extensionPath, 'package.json'), 'utf8')).version}.vsix`, ); + execFileSync( 'pnpm', [ @@ -41,9 +49,7 @@ export function publish() { '--pat', process.env.VSCE_PAT, ], - { - stdio: 'inherit', - }, + { stdio: 'inherit' }, ); execFileSync('npx', ['ovsx', 'publish', vsix, '--pat', process.env.OVSX_PAT], { stdio: 'inherit' }); } diff --git a/scripts/release.test.mjs b/scripts/release.test.mjs index bf53593..831b012 100644 --- a/scripts/release.test.mjs +++ b/scripts/release.test.mjs @@ -4,6 +4,7 @@ import { resolve } from 'node:path'; import test from 'node:test'; import { analyzeCommits } from '@semantic-release/commit-analyzer'; import { checkPullRequest } from './check-pr.mjs'; +import { publish as publishExtension } from './release-vscode-extension.mjs'; // Published via pnpm publish directly (see release.config.js): pnpm rewrites // workspace:* deps and packs the `files` field natively, so these packages @@ -40,6 +41,18 @@ for (const [message, expected] of [ }); } +test('VS Code extension publish fails fast with a clear error when VSCE_PAT/OVSX_PAT are unset', () => { + const { VSCE_PAT, OVSX_PAT } = process.env; + delete process.env.VSCE_PAT; + delete process.env.OVSX_PAT; + try { + assert.throws(() => publishExtension(), /VSCE_PAT and OVSX_PAT are not set/); + } finally { + if (VSCE_PAT !== undefined) process.env.VSCE_PAT = VSCE_PAT; + if (OVSX_PAT !== undefined) process.env.OVSX_PAT = OVSX_PAT; + } +}); + test('PR policy enforces issue link and integration target, not branch name', () => { const pr = { base: { ref: 'main' },