@@ -26,9 +26,9 @@ const CWD = process.cwd();
2626 * - `next`: Defaults to `false`.
2727 */
2828const argv = minimist ( process . argv . slice ( 2 ) , {
29- boolean : [ 'dry-run' , 'next' , 'build' , 'test' , 'release' ] ,
29+ boolean : [ 'dry-run' , 'next' , 'build' , 'test' , 'release' , 'publish' ] ,
3030 string : [ 'loglevel' ] ,
31- default : { 'dry-run' : false , next : false , build : false , test : false , release : false } ,
31+ default : { 'dry-run' : false , next : false , build : false , test : false , release : false , publish : false } ,
3232} ) ;
3333
3434/**
@@ -179,6 +179,26 @@ const release = () => {
179179 runCmd ( `git push origin ${ getCurrentBranch ( ) } --follow-tags` ) ;
180180} ;
181181
182+ /**
183+ * Publishes any package versions that are missing from the registry, without
184+ * versioning or creating tags.
185+ *
186+ * Uses `lerna publish from-package`, which inspects each package's current
187+ * version and publishes only those not already present on npm. This makes it
188+ * a safe, idempotent retry for a release where some packages published and
189+ * others failed (e.g. a transient provenance/transparency-log error): already
190+ * published packages are skipped and only the missing ones are published.
191+ *
192+ * Intended to be run from a branch/commit that already carries the intended
193+ * versions (typically `master` after a `lerna version` has run).
194+ */
195+ const publishMissing = ( ) => {
196+ log ( chalk . magenta ( '--- PUBLISH MISSING PACKAGES (from-package) ---' ) ) ;
197+ let releaseCmd = 'npx lerna publish from-package --yes' ;
198+ if ( argv . loglevel ) releaseCmd += ` --loglevel ${ argv . loglevel } ` ;
199+ runCmd ( releaseCmd ) ;
200+ } ;
201+
182202/**
183203 * Executes the build and release process.
184204 *
@@ -193,7 +213,7 @@ const release = () => {
193213const run = ( ) => {
194214 try {
195215 // If no specific flags, run full workflow
196- const anyFlag = argv . build || argv . test || argv . release ;
216+ const anyFlag = argv . build || argv . test || argv . release || argv . publish ;
197217 if ( ! anyFlag ) {
198218 build ( ) ;
199219 test ( ) ;
@@ -202,6 +222,7 @@ const run = () => {
202222 if ( argv . build ) build ( ) ;
203223 if ( argv . test ) test ( ) ;
204224 if ( argv . release ) release ( ) ;
225+ if ( argv . publish ) publishMissing ( ) ;
205226 }
206227 log ( chalk . green ( '✅ Tasks completed successfully.' ) ) ;
207228 } catch ( err ) {
0 commit comments