@mnci/cli 4.15.0 → 4.16.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/README.md CHANGED
@@ -75,7 +75,7 @@ helpers — they have no interest in adding a project. The concept now sits in i
75
75
  own slice that depends on nothing above it (`file-system` alone), and all three
76
76
  consumers point at it.
77
77
 
78
- ## Commands (deliberately just six)
78
+ ## Commands (deliberately just seven)
79
79
 
80
80
  ```sh
81
81
  mnci new my-repo # create a monorepo (prompts scope + registry)
@@ -123,6 +123,8 @@ mnci upgrade --agent windows-latest # ...with an explicit override
123
123
 
124
124
  mnci doctor # check this workspace's invariants (read-only)
125
125
 
126
+ mnci ci verify # the pipeline's verify phase, run here: see `mnci ci` below
127
+
126
128
  mnci sync # converge dependency ranges + nx sync (TS project refs)
127
129
  mnci sync --check # ...report and exit non-zero, writing nothing
128
130
 
@@ -320,6 +322,35 @@ TTY, so a piped or CI run reports instead of hanging on a prompt), `-y/--yes`
320
322
  (take everything), `--ecosystem`, and `--no-install` (edit the manifests but skip
321
323
  the reinstall).
322
324
 
325
+ ## `mnci ci`: the pipeline's phases, as a command
326
+
327
+ `mnci ci verify` runs the pipeline's verify phase on your machine: `nx sync:check`, then
328
+ every project (or, when a pull request's target branch is set, only the projects affected
329
+ since the merge-base with it) through `lint`, `typecheck`, `test` and `build`. It exits with
330
+ the failing command's own status, so it can stand in for the pipeline's step.
331
+
332
+ It is not a shortcut for those Nx targets, and the CLI still has no wrapper for `nx test`.
333
+ It is the pipeline's own logic, which until now lived as a `node -e` one-liner inside the
334
+ generated YAML, ported to tested code, so a laptop and a pipeline run the same thing. The
335
+ design (one `npx mnci ci` call in the pipeline, with room for your own steps around it) is
336
+ tracked in #269, and this is its first phase: **the generated pipelines do not call it yet**
337
+ and are unchanged, so nothing about an existing workspace changes. Phases follow as their
338
+ guards are ported.
339
+
340
+ - **Same scoping as the guard.** No pull-request target means every project, so a push to
341
+ main verifies in full. A pull request verifies what is affected since the merge-base with
342
+ `origin/<target>`, fetching the target once if that ref is missing, and falls back to every
343
+ project when no merge-base can be found, since a run that verifies too little still reports
344
+ green. The target comes from `GITHUB_BASE_REF` or `SYSTEM_PULLREQUEST_TARGETBRANCH`, so to
345
+ reproduce a pull request run locally, set one: `GITHUB_BASE_REF=main mnci ci verify`.
346
+ - **Native (cgo) apps are left out**, as in the pipeline, since one agent cannot build them.
347
+ - **Log groups.** Under GitHub Actions and Azure Pipelines each part is a collapsible group
348
+ (`::group::`, `##[group]`); locally it is a plain heading.
349
+ - **Checked against the guard it replaces.** An integration spec runs the inline guard and
350
+ this command against the same real git repository, with a recording stand-in for `npx`,
351
+ across a push, a pull request, Azure's `refs/heads/` form, a missing `origin/<target>` and
352
+ an unresolvable one, and requires the same Nx commands in each.
353
+
323
354
  ## `mnci doctor`: checking the invariants actually hold
324
355
 
325
356
  Read-only — it never edits the workspace. Every failing finding names the command
@@ -689,6 +720,64 @@ the generated tree, so it runs afterwards, but still before the first write:
689
720
  a refusal leaves the target byte-identical to how it was found, and the staging
690
721
  copy is discarded.
691
722
 
723
+ ### Adopting a flat Go module
724
+
725
+ A repository with its own `go.mod`, a root `main.go` and `internal/` packages is the
726
+ other common starting point, and `--into` takes it as it is. Measured on a clone of a
727
+ real one (twelve `internal/` packages, its own `release.yml`):
728
+
729
+ - **`go.mod` and `go.sum` are never touched.** `add go-*` skips the module bootstrap
730
+ when a `go.mod` exists, so the module path, the `require` lines and the Go version
731
+ survive byte for byte, and no `go.work` is created.
732
+ - **The Go plugin is registered anyway.** The bootstrap that registers it in `nx.json`
733
+ is the one that is skipped, which used to leave the plugin installed and unlisted:
734
+ every target worked, and Nx had **no Go project graph**, so `nx affected` skipped an
735
+ app that imports a changed library, silently. `add go-*` now registers it, `mnci
736
+ upgrade` repairs a workspace that adopted before, and `mnci doctor` fails while Go
737
+ projects exist and it is missing.
738
+ - **Your own workflow coexists.** A release workflow that fires on `v*` tags and the
739
+ generated `ci.yml`, which fires on pushes and pull requests to `main`, do not overlap.
740
+ mnci tags a released app `<name>@<version>`, so once `--release` and its GitHub
741
+ Release assets do what yours did, delete the old workflow.
742
+ - **The format step can fail on a file you already had**, and says so without failing
743
+ the run: a UTF-16 `.json` at the root made `eslint .` report a parse error. The root
744
+ lint covers root-level files, so a repository's existing JSON, Markdown and YAML are
745
+ now inside it; fix or delete what it names.
746
+
747
+ Landing the code is mechanical, so it is a recipe, not a command (`git mv` and one
748
+ import rewrite are the whole job, and a command would have to guess your layout). With
749
+ `youtube-downloader` as the module path, `mvd-cli` as the app and `mvd-core` as the
750
+ library:
751
+
752
+ ```sh
753
+ mnci add go-app mvd-cli
754
+ mnci add go-internal-lib mvd-core
755
+
756
+ # The generated starters are placeholders: drop them.
757
+ rm apps/mvd-cli/main.go apps/mvd-cli/main_test.go
758
+ rm -r libs/mvd-core/mvdcore
759
+
760
+ # git mv, not mv, so `git log --follow` reaches the history before the move.
761
+ git mv main.go apps/mvd-cli/main.go
762
+ for slice in internal/*/; do git mv "$slice" "libs/mvd-core/$(basename "$slice")"; done
763
+
764
+ # Rewrite the import paths (macOS: sed -i '').
765
+ grep -rl 'youtube-downloader/internal/' --include=*.go apps libs \
766
+ | xargs sed -i 's#youtube-downloader/internal/#youtube-downloader/libs/mvd-core/#g'
767
+
768
+ npx nx run-many -t test,build --projects=mvd-cli,mvd-core
769
+ ```
770
+
771
+ Use `nx` and not a bare `go test ./...` from the root: `./...` also walks
772
+ `node_modules`, where npm packages that contain Go code sit (one did here). On the
773
+ repository measured, this left `go build` clean, every test passing, 62 renames
774
+ detected by git, and the app depending on the library in the project graph. The e2e
775
+ (`go adoption`) runs this recipe on a fixture and asserts each of those.
776
+
777
+ Not measured here: whether `golangci-lint`, which is what each Go project's `lint`
778
+ runs, passes on a codebase that has never been linted. Run `nx run <lib>:lint` before
779
+ relying on it, and expect to fix or silence what it reports.
780
+
692
781
  ## Layout convention = release scoping
693
782
 
694
783
  | Directory | Contents | Released? |