From 1f6859ea1c6eec9fa61471e52a5bbf93b351bcf2 Mon Sep 17 00:00:00 2001 From: Lembot Date: Sat, 13 Dec 2025 00:31:15 -0500 Subject: [PATCH 1/2] feat: add postbuild script for auto-publish to local Verdaccio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Verdaccio is running at localhost:4873, the package is automatically published after each build. If Verdaccio isn't running, the build completes normally without error. Usage: 1. Start Verdaccio: docker compose up -d verdaccio (in ratings-stack) 2. First time only: npm adduser --registry http://localhost:4873 3. Build: npm run build (auto-publishes to Verdaccio) Closes #4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- package.json | 1 + scripts/publish-local.js | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 scripts/publish-local.js diff --git a/package.json b/package.json index 00ba3a7..3ddcad3 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ ], "scripts": { "build": "webpack --mode production && npm run build:types", + "postbuild": "node scripts/publish-local.js", "build:dev": "webpack --mode development && npm run build:types", "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap", "prepare": "npm run build", diff --git a/scripts/publish-local.js b/scripts/publish-local.js new file mode 100644 index 0000000..7fcf2dd --- /dev/null +++ b/scripts/publish-local.js @@ -0,0 +1,47 @@ +#!/usr/bin/env node +/** + * Auto-publish to local Verdaccio registry if available. + * This script is run automatically after `npm run build`. + * + * If Verdaccio is running at localhost:4873, the package will be published there. + * If Verdaccio is not running, the script silently exits (no error). + */ + +const { execSync } = require('child_process'); +const http = require('http'); + +const VERDACCIO_URL = process.env.VERDACCIO_URL || 'http://localhost:4873'; + +// Check if Verdaccio is running +const req = http.get(VERDACCIO_URL, { timeout: 2000 }, (res) => { + if (res.statusCode === 200) { + console.log('[publish-local] Verdaccio detected at', VERDACCIO_URL); + try { + // Use --ignore-scripts to prevent infinite loop (prepare -> build -> postbuild -> publish -> prepare...) + execSync(`npm publish --registry ${VERDACCIO_URL} --ignore-scripts`, { + stdio: 'inherit', + cwd: process.cwd() + }); + console.log('[publish-local] Successfully published to local Verdaccio'); + } catch (err) { + // Common case: version already exists, which is fine + if (err.status === 1) { + console.log('[publish-local] Package version may already exist in Verdaccio (this is OK)'); + } else { + console.warn('[publish-local] Publish failed:', err.message); + } + } + } else { + console.log('[publish-local] Verdaccio returned status', res.statusCode, '- skipping'); + } +}); + +req.on('error', () => { + // Verdaccio not running - silently skip + console.log('[publish-local] Verdaccio not running at', VERDACCIO_URL, '- skipping local publish'); +}); + +req.on('timeout', () => { + req.destroy(); + console.log('[publish-local] Verdaccio not responding - skipping local publish'); +}); -- GitLab From 1f69df39defe0576e70fd923ddeb2a15f9ba227f Mon Sep 17 00:00:00 2001 From: Lembot Date: Sun, 14 Dec 2025 20:25:28 -0500 Subject: [PATCH 2/2] feat: unpublish before publish to allow same-version updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When republishing the same version during local development, the script now unpublishes the existing version first. If the version doesn't exist in the registry yet, the unpublish gracefully fails and publish continues. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- scripts/publish-local.js | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/scripts/publish-local.js b/scripts/publish-local.js index 7fcf2dd..956574a 100644 --- a/scripts/publish-local.js +++ b/scripts/publish-local.js @@ -5,17 +5,42 @@ * * If Verdaccio is running at localhost:4873, the package will be published there. * If Verdaccio is not running, the script silently exits (no error). + * + * The script unpublishes the current version first (if it exists) to allow + * republishing the same version with updated code during local development. */ const { execSync } = require('child_process'); const http = require('http'); +const fs = require('fs'); +const path = require('path'); const VERDACCIO_URL = process.env.VERDACCIO_URL || 'http://localhost:4873'; +// Read package.json to get name and version +const packageJsonPath = path.join(process.cwd(), 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const packageSpec = `${packageJson.name}@${packageJson.version}`; + // Check if Verdaccio is running const req = http.get(VERDACCIO_URL, { timeout: 2000 }, (res) => { if (res.statusCode === 200) { console.log('[publish-local] Verdaccio detected at', VERDACCIO_URL); + + // First, try to unpublish the current version (ignore errors if it doesn't exist) + try { + console.log(`[publish-local] Unpublishing ${packageSpec} (if it exists)...`); + execSync(`npm unpublish ${packageSpec} --registry ${VERDACCIO_URL} --force`, { + stdio: 'pipe', + cwd: process.cwd() + }); + console.log(`[publish-local] Unpublished ${packageSpec}`); + } catch (err) { + // Package doesn't exist yet - that's fine, continue with publish + console.log(`[publish-local] ${packageSpec} not in registry (this is OK)`); + } + + // Now publish try { // Use --ignore-scripts to prevent infinite loop (prepare -> build -> postbuild -> publish -> prepare...) execSync(`npm publish --registry ${VERDACCIO_URL} --ignore-scripts`, { @@ -24,12 +49,7 @@ const req = http.get(VERDACCIO_URL, { timeout: 2000 }, (res) => { }); console.log('[publish-local] Successfully published to local Verdaccio'); } catch (err) { - // Common case: version already exists, which is fine - if (err.status === 1) { - console.log('[publish-local] Package version may already exist in Verdaccio (this is OK)'); - } else { - console.warn('[publish-local] Publish failed:', err.message); - } + console.warn('[publish-local] Publish failed:', err.message); } } else { console.log('[publish-local] Verdaccio returned status', res.statusCode, '- skipping'); -- GitLab