@@ -6,6 +6,7 @@ import * as util from "node:util";
6
6
const ADO_PUBLISH_PIPELINE = ".ado/templates/npm-publish-steps.yml" ;
7
7
const NX_CONFIG_FILE = "nx.json" ;
8
8
9
+ const NPM_DEFEAULT_REGISTRY = "https://registry.npmjs.org/"
9
10
const NPM_TAG_NEXT = "next" ;
10
11
const NPM_TAG_NIGHTLY = "nightly" ;
11
12
const RNMACOS_LATEST = "react-native-macos@latest" ;
@@ -80,6 +81,38 @@ function loadNxConfig(configFile) {
80
81
return JSON . parse ( nx ) ;
81
82
}
82
83
84
+ function verifyNpmAuth ( registry = NPM_DEFEAULT_REGISTRY ) {
85
+ const npmErrorRegex = / n p m e r r o r c o d e ( \w + ) / ;
86
+ const spawnOptions = {
87
+ stdio : /** @type {const } */ ( "pipe" ) ,
88
+ shell : true ,
89
+ windowsVerbatimArguments : true ,
90
+ } ;
91
+
92
+ const whoamiArgs = [ "whoami" , "--registry" , registry ] ;
93
+ const whoami = spawnSync ( "npm" , whoamiArgs , spawnOptions ) ;
94
+ if ( whoami . status !== 0 ) {
95
+ const error = whoami . stderr . toString ( ) ;
96
+ const m = error . match ( npmErrorRegex ) ;
97
+ switch ( m && m [ 1 ] ) {
98
+ case "EINVALIDNPMTOKEN" :
99
+ throw new Error ( `Invalid auth token for npm registry: ${ registry } ` ) ;
100
+ case "ENEEDAUTH" :
101
+ throw new Error ( `Missing auth token for npm registry: ${ registry } ` ) ;
102
+ default :
103
+ throw new Error ( error ) ;
104
+ }
105
+ }
106
+
107
+ const tokenArgs = [ "token" , "list" , "--registry" , registry ] ;
108
+ const token = spawnSync ( "npm" , tokenArgs , spawnOptions ) ;
109
+ if ( token . status !== 0 ) {
110
+ const error = token . stderr . toString ( ) ;
111
+ const m = error . match ( npmErrorRegex ) ;
112
+ throw new Error ( m ? `Auth token for '${ registry } ' returned error code ${ m [ 1 ] } ` : error ) ;
113
+ }
114
+ }
115
+
83
116
/**
84
117
* Returns a numerical value for a given version string.
85
118
* @param {string } version
@@ -91,15 +124,18 @@ function versionToNumber(version) {
91
124
}
92
125
93
126
/**
94
- * Returns the currently checked out branch. Note that this function prefers
95
- * predefined CI environment variables over local clone.
127
+ * Returns the target branch. If not targetting any branches (e.g., when
128
+ * executing this script locally), the current branch is returned.
129
+ *
130
+ * @note This function prefers predefined CI environment variables over local clone.
131
+ *
96
132
* @returns {string }
97
133
*/
98
134
function getCurrentBranch ( ) {
99
135
// https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services
100
- const adoSourceBranchName = process . env [ "BUILD_SOURCEBRANCHNAME " ] ;
101
- if ( adoSourceBranchName ) {
102
- return adoSourceBranchName . replace ( / ^ r e f s \/ h e a d s \/ / , "" ) ;
136
+ const adoTargetBranchName = process . env [ "SYSTEM_PULLREQUEST_TARGETBRANCH " ] ;
137
+ if ( adoTargetBranchName ) {
138
+ return adoTargetBranchName . replace ( / ^ r e f s \/ h e a d s \/ / , "" ) ;
103
139
}
104
140
105
141
// Depending on how the repo was cloned, HEAD may not exist. We only use this
@@ -252,6 +288,8 @@ function enablePublishing(config, currentBranch, { npmTag: tag, prerelease, isNe
252
288
throw new Error ( "Nx Release is not correctly configured for the current branch" ) ;
253
289
}
254
290
291
+ verifyNpmAuth ( ) ;
292
+
255
293
verifyPublishPipeline ( ADO_PUBLISH_PIPELINE , tag ) ;
256
294
enablePublishingOnAzurePipelines ( ) ;
257
295
}
@@ -263,7 +301,7 @@ function enablePublishing(config, currentBranch, { npmTag: tag, prerelease, isNe
263
301
function main ( options ) {
264
302
const branch = getCurrentBranch ( ) ;
265
303
if ( ! branch ) {
266
- error ( "Could not get current branch" ) ;
304
+ error ( "Could not get target branch" ) ;
267
305
return 1 ;
268
306
}
269
307
0 commit comments