@@ -84,6 +84,31 @@ function incompleteStateMessage(state) {
8484 return details . join ( '; ' ) ;
8585}
8686
87+ function repairMissingTags ( state , cwd , environment ) {
88+ if ( state . missingVersions . length > 0 || state . missingTags . length === 0 ) return ;
89+ for ( const tag of state . missingTags ) {
90+ const create = spawnSync ( 'git' , [ 'tag' , tag ] , {
91+ cwd,
92+ env : environment ,
93+ encoding : 'utf8' ,
94+ stdio : 'pipe' ,
95+ } ) ;
96+ if ( create . status !== 0 ) {
97+ throw new Error ( `Unable to create missing release tag ${ tag } : ${ create . stderr || create . error || 'git tag failed' } ` ) ;
98+ }
99+ const push = spawnSync ( 'git' , [ 'push' , 'origin' , `refs/tags/${ tag } ` ] , {
100+ cwd,
101+ env : environment ,
102+ encoding : 'utf8' ,
103+ stdio : 'pipe' ,
104+ } ) ;
105+ if ( push . status !== 0 ) {
106+ throw new Error ( `Unable to push missing release tag ${ tag } : ${ push . stderr || push . error || 'git push failed' } ` ) ;
107+ }
108+ process . stdout . write ( `Repaired missing release tag ${ tag } ; npm version already exists.\n` ) ;
109+ }
110+ }
111+
87112async function waitForCompleteState ( inspect , attempts , delayMs ) {
88113 let state ;
89114 for ( let attempt = 0 ; attempt < attempts ; attempt += 1 ) {
@@ -110,6 +135,18 @@ export async function publishPackages(options = {}) {
110135 process . stdout . write ( `All ${ packages . length } package versions and git tags already exist; skipping publish.\n` ) ;
111136 return ;
112137 }
138+ if ( initialState . missingVersions . length === 0 && initialState . missingTags . length > 0 ) {
139+ repairMissingTags ( initialState , cwd , environment ) ;
140+ const repairedState = await waitForCompleteState (
141+ inspect ,
142+ options . postconditionAttempts ?? 5 ,
143+ options . postconditionDelayMs ?? 2000 ,
144+ ) ;
145+ if ( ! repairedState . complete ) {
146+ throw new Error ( `Release tags were repaired but release is still incomplete: ${ incompleteStateMessage ( repairedState ) } ` ) ;
147+ }
148+ return ;
149+ }
113150
114151 const cliPath = options . cliPath ?? require . resolve ( '@changesets/cli/bin.js' ) ;
115152 const result = spawnSync ( process . execPath , [ cliPath , 'publish' ] , {
0 commit comments