Skip to content

Commit f526e03

Browse files
committed
chore: verify npm auth token in prepublish script
1 parent ce45e31 commit f526e03

File tree

1 file changed

+44
-6
lines changed

1 file changed

+44
-6
lines changed

.ado/scripts/prepublish-check.mjs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as util from "node:util";
66
const ADO_PUBLISH_PIPELINE = ".ado/templates/npm-publish-steps.yml";
77
const NX_CONFIG_FILE = "nx.json";
88

9+
const NPM_DEFEAULT_REGISTRY = "https://registry.npmjs.org/"
910
const NPM_TAG_NEXT = "next";
1011
const NPM_TAG_NIGHTLY = "nightly";
1112
const RNMACOS_LATEST = "react-native-macos@latest";
@@ -80,6 +81,38 @@ function loadNxConfig(configFile) {
8081
return JSON.parse(nx);
8182
}
8283

84+
function verifyNpmAuth(registry = NPM_DEFEAULT_REGISTRY) {
85+
const npmErrorRegex = /npm error code (\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+
83116
/**
84117
* Returns a numerical value for a given version string.
85118
* @param {string} version
@@ -91,15 +124,18 @@ function versionToNumber(version) {
91124
}
92125

93126
/**
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+
*
96132
* @returns {string}
97133
*/
98134
function getCurrentBranch() {
99135
// 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(/^refs\/heads\//, "");
136+
const adoTargetBranchName = process.env["SYSTEM_PULLREQUEST_TARGETBRANCH"];
137+
if (adoTargetBranchName) {
138+
return adoTargetBranchName.replace(/^refs\/heads\//, "");
103139
}
104140

105141
// 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
252288
throw new Error("Nx Release is not correctly configured for the current branch");
253289
}
254290

291+
verifyNpmAuth();
292+
255293
verifyPublishPipeline(ADO_PUBLISH_PIPELINE, tag);
256294
enablePublishingOnAzurePipelines();
257295
}
@@ -263,7 +301,7 @@ function enablePublishing(config, currentBranch, { npmTag: tag, prerelease, isNe
263301
function main(options) {
264302
const branch = getCurrentBranch();
265303
if (!branch) {
266-
error("Could not get current branch");
304+
error("Could not get target branch");
267305
return 1;
268306
}
269307

0 commit comments

Comments
 (0)