@mnci/cli 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +45 -4
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -313,8 +313,24 @@ function npmrcContent(registry, scope) {
|
|
|
313
313
|
if (registry.kind === "npm") {
|
|
314
314
|
return `; Publish authentication for the public npm registry.
|
|
315
315
|
;
|
|
316
|
-
; NODE_AUTH_TOKEN is exported by the generated CI's release step
|
|
317
|
-
;
|
|
316
|
+
; NODE_AUTH_TOKEN is exported by the generated CI's release step. Nothing needs
|
|
317
|
+
; it for day-to-day work here - installing, building and testing never
|
|
318
|
+
; authenticate.
|
|
319
|
+
;
|
|
320
|
+
; It is NOT harmless the moment you DO want to authenticate from this directory,
|
|
321
|
+
; which an earlier version of this comment claimed. A project .npmrc wins over
|
|
322
|
+
; your user one, so with NODE_AUTH_TOKEN unset this line hands npm an empty
|
|
323
|
+
; token and overrides 'npm login': inside this repo 'npm whoami' fails with a
|
|
324
|
+
; 401 and any write is refused. The refusal is easy to misread, because for a
|
|
325
|
+
; scoped package the registry answers a write you are not allowed to make with
|
|
326
|
+
;
|
|
327
|
+
; npm error 404 Not Found - PUT https://registry.npmjs.org/@scope%2fthing
|
|
328
|
+
;
|
|
329
|
+
; and everything above it is npm listing what it intended to send, so a long
|
|
330
|
+
; healthy-looking run still changes nothing.
|
|
331
|
+
;
|
|
332
|
+
; To publish or deprecate by hand, run it from outside this directory, or export
|
|
333
|
+
; a real token first.
|
|
318
334
|
//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
|
|
319
335
|
|
|
320
336
|
; There is deliberately NO '${scope}:registry' line here. npmjs.org is already
|
|
@@ -873,6 +889,10 @@ var NPM_AUDIT_STEP = `node -e "const cp=require('node:child_process');const r=cp
|
|
|
873
889
|
var VERIFY_TARGETS = "lint,typecheck,test,build";
|
|
874
890
|
var AFFECTED_OR_ALL_GUARD = `node -e "const cp=require('node:child_process');const T='${VERIFY_TARGETS}';const all=()=>process.exit(cp.spawnSync('npx nx run-many -t '+T,{stdio:'inherit',shell:true}).status ?? 1);const ref=process.env.GITHUB_BASE_REF||process.env.SYSTEM_PULLREQUEST_TARGETBRANCH||'';if(!ref){console.log('Not a pull request - verifying EVERY project.');all()}const target=ref.replace('refs/heads/','');const mergeBase=r=>{const o=cp.spawnSync('git',['merge-base',r,'HEAD'],{encoding:'utf8'});return o.status===0?o.stdout.trim():''};let base=mergeBase('origin/'+target);if(!base){console.log('No origin/'+target+' ref - fetching it to resolve a merge-base.');cp.spawnSync('git',['fetch','--no-tags','origin',target],{stdio:'inherit'});base=mergeBase('FETCH_HEAD')}if(!base){console.log('Could not resolve a merge-base with '+target+' - verifying EVERY project.');all()}console.log('Pull request against '+target+' - verifying projects affected since '+base);process.exit(cp.spawnSync('npx nx affected -t '+T+' --base='+base,{stdio:'inherit',shell:true}).status ?? 1)"`;
|
|
875
891
|
var PACK_APPS_GUARD = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const hasProjectJson=fs.globSync('apps/*/project.json').length>0;const hasInlineNx=fs.globSync('apps/*/package.json').some((f)=>{try{return Boolean(JSON.parse(fs.readFileSync(f,'utf8')).nx)}catch{return false}});const hasCsproj=fs.globSync('apps/*/*.csproj').length>0;if(!hasProjectJson&&!hasInlineNx&&!hasCsproj){console.log('No apps to pack - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('npx nx run-many -t package',{stdio:'inherit',shell:true}).status ?? 1)"`;
|
|
892
|
+
var NPM_AUTH_PREFLIGHT = `node -e "const fs=require('node:fs'),cp=require('node:child_process');if(fs.globSync('packages/*/package.json').length===0){console.log('No npm packages to release - skipping.');process.exit(0)}if(!process.env.NODE_AUTH_TOKEN){console.error('NPM_TOKEN is empty or unset, so the publish would fail AFTER nx release has already tagged. Add it as a repository secret named exactly NPM_TOKEN - under Actions, not the Dependabot or Codespaces tab, and not an Environment secret. Use an npm Automation token - a Publish token is refused by 2FA in CI.');process.exit(1)}const r=cp.spawnSync('npm',['whoami','--registry=https://registry.npmjs.org/'],{encoding:'utf8',shell:process.platform==='win32'});if(r.status!==0){console.error('NPM_TOKEN is set but the registry rejected it - '+((r.stderr||'')+(r.stdout||'')).trim()+'. Check that it has not expired and that it grants publish rights on this scope.');process.exit(1)}console.log('npm auth OK as '+r.stdout.trim())"`;
|
|
893
|
+
function npmAuthPreflight(registryKind) {
|
|
894
|
+
return registryKind === "npm" ? NPM_AUTH_PREFLIGHT : "";
|
|
895
|
+
}
|
|
876
896
|
var SHALLOW_CLONE_GUARD = `node -e "const r=require('node:child_process').spawnSync('git',['rev-parse','--is-shallow-repository'],{encoding:'utf8'});if(r.status!==0){console.error('Could not determine whether this checkout has full history (git rev-parse --is-shallow-repository failed) - refusing to release. '+(r.stderr||'').trim());process.exit(1)}if(r.stdout.trim()==='true'){console.error('This checkout is a shallow clone. nx release resolves the current version of each package from its git tag, and silently falls back to the permanently-stale on-disk version when a tag cannot be found - which can propose, and publish, a version DOWNGRADE. Fetch full history before releasing - set fetchDepth (Azure) or fetch-depth (GitHub) to 0.');process.exit(1)}"`;
|
|
877
897
|
function releaseGuard(pythonPublishEnv, nugetPublishEnv) {
|
|
878
898
|
return String.raw`node -e "const fs=require('node:fs'),cp=require('node:child_process');const npmCount=fs.globSync('packages/*/package.json').length;const csharpCount=fs.globSync('packages/*/*.csproj').length;const pythonCount=fs.globSync('python-packages/*/pyproject.toml').length;const dartCount=fs.globSync('packages/*/pubspec.yaml').length;const hasNpm=npmCount>0;const hasPython=pythonCount>0;const hasCsharp=csharpCount>0;const hasDart=dartCount>0;if(!hasNpm&&!hasPython&&!hasCsharp&&!hasDart){console.log('Nothing to release - skipping.');process.exit(0)}const specifier=process.env.RELEASE_SPECIFIER||'';let releaseCmd='npx nx release --yes';if(specifier){if(!/^(major|minor|patch|\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?)$/.test(specifier)){console.error('RELEASE_SPECIFIER value \''+specifier+'\' is invalid - use major, minor, patch, or an exact version like 1.2.3.');process.exit(1)}const releaseProjectCount=npmCount+csharpCount+pythonCount+dartCount;if(/^(major|minor|patch)$/.test(specifier)&&releaseProjectCount>1){console.error('RELEASE_SPECIFIER is a keyword (\''+specifier+'\') but this workspace has '+releaseProjectCount+' releasable packages - a keyword under-bumps interdependent packages, because nx computes the dependency-bump pass from a stale cached version. Set RELEASE_SPECIFIER to an exact version instead, or clear it.');process.exit(1)}releaseCmd='npx nx release '+specifier+' --yes'}const env={...process.env};${pythonPublishEnv}${nugetPublishEnv}process.exit(cp.spawnSync(releaseCmd,{stdio:'inherit',shell:true,env}).status ?? 1)"`;
|
|
@@ -1148,7 +1168,17 @@ steps:
|
|
|
1148
1168
|
- script: ${SHALLOW_CLONE_GUARD}
|
|
1149
1169
|
displayName: Verify this is a full checkout (nx release needs the real tag history)
|
|
1150
1170
|
condition: ${onMain}
|
|
1151
|
-
|
|
1171
|
+
${npmAuthPreflight(registryKind) ? `
|
|
1172
|
+
# Prove npm will accept us BEFORE anything irreversible happens. nx release
|
|
1173
|
+
# tags first and publishes last, so a rejected token leaves a version tagged
|
|
1174
|
+
# with nothing on the registry - and that number is then skipped forever,
|
|
1175
|
+
# because the next run resolves the current version from the newest tag.
|
|
1176
|
+
- script: ${npmAuthPreflight(registryKind)}
|
|
1177
|
+
displayName: Preflight \u2014 npm must accept the token before anything is tagged
|
|
1178
|
+
condition: ${onMain}
|
|
1179
|
+
env:
|
|
1180
|
+
NODE_AUTH_TOKEN: $(NPM_TOKEN)
|
|
1181
|
+
` : ""}
|
|
1152
1182
|
# Version + tag + publish, in one release, for npm (packages/*), Python
|
|
1153
1183
|
# (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional commits,
|
|
1154
1184
|
# tag-only push. Portable guard: nx release errors on an empty scope, so
|
|
@@ -1374,7 +1404,18 @@ jobs:
|
|
|
1374
1404
|
- run: ${SHALLOW_CLONE_GUARD}
|
|
1375
1405
|
name: Verify this is a full checkout (nx release needs the real tag history)
|
|
1376
1406
|
if: \${{ ${onMain} }}
|
|
1377
|
-
|
|
1407
|
+
${npmAuthPreflight(registryKind) ? `
|
|
1408
|
+
# Prove npm will accept us BEFORE anything irreversible happens. nx
|
|
1409
|
+
# release tags first and publishes last, so a rejected token leaves a
|
|
1410
|
+
# version tagged with nothing on the registry - and that number is then
|
|
1411
|
+
# skipped forever, because the next run resolves the current version
|
|
1412
|
+
# from the newest tag.
|
|
1413
|
+
- run: ${npmAuthPreflight(registryKind)}
|
|
1414
|
+
name: Preflight \u2014 npm must accept the token before anything is tagged
|
|
1415
|
+
if: \${{ ${onMain} }}
|
|
1416
|
+
env:
|
|
1417
|
+
NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
|
|
1418
|
+
` : ""}
|
|
1378
1419
|
# Version + tag + publish, in one release, for npm (packages/*), Python
|
|
1379
1420
|
# (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional
|
|
1380
1421
|
# commits, tag-only push. Portable guard: nx release errors on an empty
|