@@ -31,16 +31,6 @@ async function maybeRollbackGit(tag, skipGit, skipVersion) {
3131 ) ;
3232}
3333
34- async function bumpVersion ( pkg , publishDir , cwd ) {
35- const json = pkg ;
36- const pkgPath = path . join ( cwd , 'package.json' ) ;
37- await writeJson ( pkgPath , json ) ;
38-
39- if ( publishDir ) {
40- await createAltPublishDir ( { outDir : publishDir } ) ;
41- }
42- }
43-
4434async function getNextVersion ( version , currentVersion , preid ) {
4535 const patch = semver . inc ( currentVersion , 'patch' ) ;
4636 const minor = semver . inc ( currentVersion , 'minor' ) ;
@@ -112,6 +102,57 @@ async function getNextVersion(version, currentVersion, preid) {
112102 }
113103}
114104
105+ async function npmPublish (
106+ spinner ,
107+ pkgJson ,
108+ options ,
109+ otpMessage = 'Enter one time password:' ,
110+ ) {
111+ const { publishDir, otp, isPublic, tag } = options ;
112+ const args = [ 'publish' ] ;
113+
114+ if ( publishDir ) {
115+ args . push ( publishDir , '--ignore-scripts' ) ;
116+
117+ // We run the lifecycle scripts manually to ensure they run in
118+ // the package root, not the publish dir
119+ await runLifecycle ( 'prepublish' , pkgJson ) ;
120+ await runLifecycle ( 'prepare' , pkgJson ) ;
121+ await runLifecycle ( 'prepublishOnly' , pkgJson ) ;
122+
123+ // do this after lifecycle scripts in case they clean the publishDir
124+ await createAltPublishDir ( { outDir : publishDir } ) ;
125+ }
126+ if ( otp ) {
127+ args . push ( '--otp' , otp ) ;
128+ }
129+
130+ if ( tag !== 'latest' ) {
131+ args . push ( '--tag' , tag ) ;
132+ }
133+
134+ if ( isPublic != null ) {
135+ args . push ( '--access' , isPublic ? 'public' : 'restricted' ) ;
136+ }
137+
138+ try {
139+ return execa ( 'npm' , args , { stdio : [ 0 , 1 , 'pipe' ] } ) ;
140+ } catch ( err ) {
141+ if ( err . stderr . includes ( 'OTP' ) ) {
142+ spinner . stop ( ) ;
143+ const nextOtp = await PromptUtilities . input ( otpMessage ) ;
144+ spinner . start ( ) ;
145+ return npmPublish (
146+ spinner ,
147+ pkgJson ,
148+ { ...options , otp : nextOtp } ,
149+ 'One time password was incorrect, try again:' ,
150+ ) ;
151+ }
152+ throw err ;
153+ }
154+ }
155+
115156exports . command = '$0 [nextVersion]' ;
116157
117158exports . describe = 'Publish a new version' ;
@@ -129,8 +170,12 @@ exports.builder = _ =>
129170 type : 'bool' ,
130171 default : false ,
131172 } )
173+ . option ( 'otp' , {
174+ type : 'string' ,
175+ } )
132176 . option ( 'publish-dir' , {
133177 type : 'string' ,
178+ describe : 'Provide a two-factor authentication code for publishing' ,
134179 } )
135180 . option ( 'allow-branch' , {
136181 group : 'Command Options:' ,
@@ -172,6 +217,7 @@ exports.handler = async ({
172217 skipVersion,
173218 allowBranch,
174219 publishDir,
220+ otp,
175221 public : isPublic ,
176222} ) => {
177223 const cwd = process . cwd ( ) ;
@@ -209,7 +255,11 @@ exports.handler = async ({
209255 `Bumping version to: ${ chalk . bold ( nextVersion ) } (${ chalk . dim (
210256 `was ${ pkg . version } ` ,
211257 ) } )`,
212- ( ) => bumpVersion ( { ...pkg , version : nextVersion } , publishDir , cwd ) ,
258+ ( ) =>
259+ writeJson ( path . join ( cwd , 'package.json' ) , {
260+ ...pkg ,
261+ version : nextVersion ,
262+ } ) ,
213263 ) ;
214264 }
215265
@@ -238,24 +288,8 @@ exports.handler = async ({
238288 try {
239289 await ConsoleUtilities . step (
240290 'Publishing to npm' ,
241- async ( ) => {
242- const args = [ 'publish' ] ;
243- if ( publishDir ) {
244- args . push ( publishDir ) ;
245- // We run the lifecycle scripts manually to ensure they run in
246- // the package root, not the publish dir
247- await runLifecycle ( 'prepublish' , pkg ) ;
248- await runLifecycle ( 'prepare' , pkg ) ;
249- await runLifecycle ( 'prepublishOnly' , pkg ) ;
250- }
251- if ( tag !== 'latest' ) {
252- args . push ( '--tag' , tag ) ;
253- }
254-
255- if ( isPublic != null ) {
256- args . push ( '--access' , isPublic ? 'public' : 'restricted' ) ;
257- }
258- await execa ( 'npm' , args , { stdio : [ 0 , 1 , 'pipe' ] } ) ;
291+ async spinner => {
292+ await npmPublish ( spinner , pkg , { otp, publishDir, isPublic, tag } ) ;
259293
260294 try {
261295 if ( publishDir ) {
0 commit comments