@mnci/cli 4.9.0 → 4.10.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 +25 -0
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1015,6 +1015,10 @@ var NPM_AUTH_PREFLIGHT = `node -e "const fs=require('node:fs'),cp=require('node:
|
|
|
1015
1015
|
function npmAuthPreflight(registryKind) {
|
|
1016
1016
|
return registryKind === "npm" ? NPM_AUTH_PREFLIGHT : "";
|
|
1017
1017
|
}
|
|
1018
|
+
var PYPI_RELEASE_PREFLIGHT = String.raw`node -e "const fs=require('node:fs');const files=fs.globSync('python-packages/*/pyproject.toml');if(files.length===0){console.log('No Python packages to release - skipping.');process.exit(0)}if(!process.env.PYPI_TOKEN){console.error('PYPI_TOKEN is empty or unset, so the publish would fail AFTER nx release has already tagged. Add it as a repository secret named exactly PYPI_TOKEN - under Actions, not the Dependabot or Codespaces tab, and not an Environment secret.');process.exit(1)}if(!process.env.PYPI_TOKEN.startsWith('pypi-')){console.error('PYPI_TOKEN does not look like a PyPI API token - every one of them begins with pypi-. A password or a truncated paste is rejected only at upload time, which is AFTER nx release has tagged.');process.exit(1)}const names=files.map(f=>{const t=fs.readFileSync(f,'utf8');const b=t.slice(t.indexOf('[project]'));const l=b.split('\n').find(x=>x.trim().startsWith('name'));return l?l.split('=')[1].replace(/[^a-zA-Z0-9._-]/g,''):''}).filter(Boolean);(async()=>{const fresh=[];for(const n of names){try{const r=await fetch('https://pypi.org/pypi/'+n.toLowerCase().replace(/[-_.]+/g,'-')+'/json',{signal:AbortSignal.timeout(10000)});if(r.status===404)fresh.push(n)}catch{console.log('Could not reach PyPI to check '+n+' - continuing.')}}if(fresh.length===0){console.log('Every Python package already exists on PyPI - this release creates none.');return}console.log('NOTE - this release may CREATE '+fresh.length+' new PyPI project(s) - '+fresh.join(', ')+'. Project creation is rate limited per account, and a 429 there arrives AFTER nx release has tagged - leaving those versions tagged with nothing published, and skipped forever, because the next run resolves the current version from the newest tag. If that happens, delete the tags for the versions that did not publish before releasing again. PyPI offers no way to check the limit, or the token, in advance.')})()"`;
|
|
1019
|
+
function pypiReleasePreflight(registryKind) {
|
|
1020
|
+
return registryKind === "npm" ? PYPI_RELEASE_PREFLIGHT : "";
|
|
1021
|
+
}
|
|
1018
1022
|
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)}"`;
|
|
1019
1023
|
function releaseGuard(pythonPublishEnv, nugetPublishEnv) {
|
|
1020
1024
|
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)"`;
|
|
@@ -1317,6 +1321,16 @@ ${npmAuthPreflight(registryKind) ? `
|
|
|
1317
1321
|
condition: ${onMain}
|
|
1318
1322
|
env:
|
|
1319
1323
|
NODE_AUTH_TOKEN: $(NPM_TOKEN)
|
|
1324
|
+
` : ""}${pypiReleasePreflight(registryKind) ? `
|
|
1325
|
+
# PyPI cannot be asked whether a token is good - the only endpoint that
|
|
1326
|
+
# authenticates is the upload itself - so this checks the token's SHAPE and
|
|
1327
|
+
# names the projects this release would have to CREATE. Project creation is
|
|
1328
|
+
# rate limited per account, and a 429 arrives AFTER nx release has tagged.
|
|
1329
|
+
- script: ${pypiReleasePreflight(registryKind)}
|
|
1330
|
+
displayName: Preflight \u2014 name the PyPI projects this release would create
|
|
1331
|
+
condition: ${onMain}
|
|
1332
|
+
env:
|
|
1333
|
+
PYPI_TOKEN: $(PYPI_TOKEN)
|
|
1320
1334
|
` : ""}
|
|
1321
1335
|
# Version + tag + publish, in one release, for npm (packages/*), Python
|
|
1322
1336
|
# (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional commits,
|
|
@@ -1554,6 +1568,17 @@ ${npmAuthPreflight(registryKind) ? `
|
|
|
1554
1568
|
if: \${{ ${onMain} }}
|
|
1555
1569
|
env:
|
|
1556
1570
|
NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
|
|
1571
|
+
` : ""}${pypiReleasePreflight(registryKind) ? `
|
|
1572
|
+
# PyPI cannot be asked whether a token is good - the only endpoint that
|
|
1573
|
+
# authenticates is the upload itself - so this checks the token's SHAPE
|
|
1574
|
+
# and names the projects this release would have to CREATE. Project
|
|
1575
|
+
# creation is rate limited per account, and a 429 arrives AFTER nx
|
|
1576
|
+
# release has tagged.
|
|
1577
|
+
- run: ${pypiReleasePreflight(registryKind)}
|
|
1578
|
+
name: Preflight \u2014 name the PyPI projects this release would create
|
|
1579
|
+
if: \${{ ${onMain} }}
|
|
1580
|
+
env:
|
|
1581
|
+
PYPI_TOKEN: \${{ secrets.PYPI_TOKEN }}
|
|
1557
1582
|
` : ""}
|
|
1558
1583
|
# Version + tag + publish, in one release, for npm (packages/*), Python
|
|
1559
1584
|
# (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional
|