@mnci/cli 1.15.0 → 1.15.2

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/README.md CHANGED
@@ -365,8 +365,12 @@ default `azure`): `azure` writes `azure-pipelines.yml`, `github` writes
365
365
  GitHub-hosted repo, or `both` while migrating between the two. Whichever
366
366
  provider(s), the pipeline does the **exact same thing**: both files are built
367
367
  from the same shared guard scripts (`overlay.ts`'s `PYTHON_INSTALL_GUARD`,
368
- `PACK_APPS_GUARD`, `releaseGuard`), so they can never drift on what CI
369
- actually runs — only the provider's own syntax differs.
368
+ `PACK_APPS_GUARD`, `releaseGuard`, `AFFECTED_OR_ALL_GUARD`), so they can never
369
+ drift on what CI actually runs — only the provider's own syntax differs. That
370
+ matters most for the last of those: the two providers detect a pull request
371
+ through different environment variables, so the guard reads both, and a
372
+ provider-specific copy would change _what CI verifies_ rather than merely how it
373
+ is spelled.
370
374
 
371
375
  The pipeline contains **no bash and no PowerShell**: every step is a built-in
372
376
  task/action or a single-line `git`/`npm`/`npx`/`node` command that `cmd.exe`
@@ -394,8 +398,29 @@ vulnerable transitive package) is exactly what this monorepo's own
394
398
  attempts automatically.
395
399
 
396
400
  Then `nx sync:check` (fails fast and clearly if the workspace wasn't
397
- synced+committed locally — see above), then one `nx run-many -t
398
- lint,test,build`. Pushes to `main` then:
401
+ synced+committed locally — see above), then `npm run format:check`, then **one
402
+ verify step** running `lint,typecheck,test,build`. `typecheck` is in that list
403
+ because a bundler-built project strips types without reading them, so `build`
404
+ passing proves nothing about type correctness.
405
+
406
+ That step verifies the **affected** projects on a pull request and **every**
407
+ project on anything else — including a push to `main`, so a release is always
408
+ verified in full. There is deliberately no separate `npm run lint` step: that is
409
+ `nx run-many -t lint`, a strict subset of the list above, and on an
410
+ affected-scoped PR it would re-lint every project and throw the benefit away.
411
+ `format:check` does stay workspace-wide, because `prettier --check .` is one
412
+ invocation over the whole tree rather than a per-project target, so there is
413
+ nothing to narrow.
414
+
415
+ Every fallback in that step verifies **everything**: no PR target branch, an
416
+ unresolvable merge-base (shallow clone, absent remote branch), any non-PR run.
417
+ That direction is deliberate — resolving the base too wide costs a few minutes,
418
+ while resolving it too narrow means CI runs almost nothing, reports green and has
419
+ verified nothing. The base is a `git merge-base`, not either provider's "base SHA"
420
+ field and not the GitHub-only `nrwl/nx-set-shas`, so one mechanism serves both
421
+ providers and is correct in each by construction.
422
+
423
+ Pushes to `main` then:
399
424
 
400
425
  - **Pack all apps** — each app's `package` target zips its build output into
401
426
  `dist/drop/<type>-<name>.zip` (e.g. `node-function-app-api.zip`,
package/dist/cli.js CHANGED
@@ -1506,6 +1506,8 @@ var FLUTTER_TOOL_PATH_AZURE = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}console.log(
1506
1506
  var FLUTTER_TOOL_PATH_GITHUB = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}if(!process.env.GITHUB_PATH){console.log('Not running in GitHub Actions - skipping.');process.exit(0)}fs.appendFileSync(process.env.GITHUB_PATH,bin+${String.raw`'\n'`})"`;
1507
1507
  var FLUTTER_PUB_GET_GUARD = `node -e "const fs=require('node:fs');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('flutter',['pub','get'],{stdio:'inherit',shell:process.platform==='win32'}).status ?? 1)"`;
1508
1508
  var NPM_AUDIT_STEP = "npm audit --audit-level=high || echo npm audit found vulnerabilities, see log above - non-blocking, run npm audit locally to inspect";
1509
+ var VERIFY_TARGETS = "lint,typecheck,test,build";
1510
+ 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)"`;
1509
1511
  var PACK_APPS_GUARD = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});if(fs.globSync('apps/*/project.json').length===0){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)"`;
1510
1512
  function releaseGuard(pythonPublishEnv) {
1511
1513
  return `node -e "const fs=require('node:fs'),cp=require('node:child_process');const hasNpm=fs.globSync('packages/*/package.json').length>0;const hasPython=fs.globSync('python-packages/*/pyproject.toml').length>0;if(!hasNpm&&!hasPython){console.log('Nothing to release - skipping.');process.exit(0)}const env={...process.env};${pythonPublishEnv}process.exit(cp.spawnSync('npx nx release --yes',{stdio:'inherit',shell:true,env}).status ?? 1)"`;
@@ -1674,27 +1676,28 @@ steps:
1674
1676
  - script: npx nx sync:check
1675
1677
  displayName: Verify the workspace is synced (run 'npx nx sync' locally and commit if this fails)
1676
1678
 
1677
- # One verify for every run (PR and main). Nx cache makes unchanged test/build
1678
- # projects instant.
1679
- - script: npm run lint
1680
- displayName: Lint
1681
-
1682
1679
  # Prettier owns ALL formatting in this workspace, so it needs a gate of its
1683
1680
  # own: ESLint is configured for correctness only and deliberately reports
1684
1681
  # nothing about formatting. Without this step the entire formatting opinion is
1685
1682
  # advisory, and a workspace drifts out of compliance with no signal anywhere.
1683
+ #
1684
+ # Stays workspace-wide even on a PR, unlike the verify step below: it is one
1685
+ # Prettier invocation over the whole tree, not a per-project Nx target, so
1686
+ # there is nothing to scope down and formatting is never partially checked.
1686
1687
  - script: npm run format:check
1687
1688
  displayName: Check formatting (run 'npm run format' locally to fix)
1688
- # \`lint\` here also runs any Nx lint targets \`npm run lint\` does not cover \u2014
1689
- # notably Python's ruff (every Python project owns a hand-authored \`lint\`
1690
- # target). The JS lint runs twice, but Nx caches the repeat instantly.
1689
+
1690
+ # The one verify step, and deliberately the only one: affected projects on a
1691
+ # pull request, EVERY project on anything else (a push to main included, so a
1692
+ # release is always verified in full). Every fallback \u2014 no target branch, an
1693
+ # unresolvable merge-base \u2014 takes the full path, because a run that verifies
1694
+ # too little still reports green.
1691
1695
  #
1692
- # \`typecheck\` is load-bearing and not covered by \`build\`: a bundler-built
1693
- # project (esbuild, swc) strips types without reading them, so a workspace can
1694
- # build, test and lint green while carrying real type errors. --preset=ts
1695
- # infers a typecheck target for every project, so this costs one target name.
1696
- - script: npx nx run-many -t lint,typecheck,test,build
1697
- displayName: Lint, typecheck, test and build everything
1696
+ # 'npm run lint' is 'nx run-many -t lint', a strict subset of the targets
1697
+ # below, so adding it back as its own step would only duplicate work \u2014 and on
1698
+ # a pull request it would re-lint every project, discarding the point of this.
1699
+ - script: ${AFFECTED_OR_ALL_GUARD}
1700
+ displayName: Verify (affected on a PR, every project on main)
1698
1701
 
1699
1702
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1700
1703
  # target. Portable guard: skip cleanly when the workspace has no apps yet.
@@ -1873,29 +1876,31 @@ jobs:
1873
1876
  - run: npx nx sync:check
1874
1877
  name: Verify the workspace is synced (run 'npx nx sync' locally and commit if this fails)
1875
1878
 
1876
- # One verify for every run (PR and main). Nx cache makes unchanged
1877
- # test/build projects instant.
1878
- - run: npm run lint
1879
- name: Lint
1880
-
1881
1879
  # Prettier owns ALL formatting in this workspace, so it needs a gate of
1882
1880
  # its own: ESLint is configured for correctness only and deliberately
1883
1881
  # reports nothing about formatting. Without this step the entire
1884
1882
  # formatting opinion is advisory, and a workspace drifts out of
1885
1883
  # compliance with no signal anywhere.
1884
+ #
1885
+ # Stays workspace-wide even on a PR, unlike the verify step below: it is
1886
+ # one Prettier invocation over the whole tree, not a per-project Nx
1887
+ # target, so there is nothing to scope down and formatting is never
1888
+ # partially checked.
1886
1889
  - run: npm run format:check
1887
1890
  name: Check formatting (run 'npm run format' locally to fix)
1888
- # \`lint\` here also runs any Nx lint targets \`npm run lint\` does not cover \u2014
1889
- # notably Python's ruff (every Python project owns a hand-authored \`lint\`
1890
- # target). The JS lint runs twice, but Nx caches the repeat instantly.
1891
+
1892
+ # The one verify step, and deliberately the only one: affected projects on
1893
+ # a pull request, EVERY project on anything else (a push to main included,
1894
+ # so a release is always verified in full). Every fallback \u2014 no target
1895
+ # branch, an unresolvable merge-base \u2014 takes the full path, because a run
1896
+ # that verifies too little still reports green.
1891
1897
  #
1892
- # \`typecheck\` is load-bearing and not covered by \`build\`: a bundler-built
1893
- # project (esbuild, swc) strips types without reading them, so a workspace
1894
- # can build, test and lint green while carrying real type errors.
1895
- # --preset=ts infers a typecheck target for every project, so this costs
1896
- # one target name.
1897
- - run: npx nx run-many -t lint,typecheck,test,build
1898
- name: Lint, typecheck, test and build everything
1898
+ # 'npm run lint' is 'nx run-many -t lint', a strict subset of the targets
1899
+ # below, so adding it back as its own step would only duplicate work \u2014 and
1900
+ # on a pull request it would re-lint every project, discarding the point
1901
+ # of this.
1902
+ - run: ${AFFECTED_OR_ALL_GUARD}
1903
+ name: Verify (affected on a PR, every project on main)
1899
1904
 
1900
1905
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1901
1906
  # target. Portable guard: skip cleanly when the workspace has no apps yet.
@@ -2543,7 +2548,7 @@ async function main() {
2543
2548
  }
2544
2549
  }
2545
2550
  if (require.main === module) {
2546
- main();
2551
+ void main();
2547
2552
  }
2548
2553
  // Annotate the CommonJS export names for ESM import in node:
2549
2554
  0 && (module.exports = {