@mnci/cli 4.14.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 +138 -3
- package/dist/cli.js +688 -276
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
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
|
|
78
|
+
## Commands (deliberately just seven)
|
|
79
79
|
|
|
80
80
|
```sh
|
|
81
81
|
mnci new my-repo # create a monorepo (prompts scope + registry)
|
|
@@ -103,6 +103,7 @@ mnci add python-vendor shared --lib core # wire core's module into shared's bui
|
|
|
103
103
|
# Go (@nx-go/nx-go — one root go.mod, golangci-lint + go test)
|
|
104
104
|
mnci add go-app api # executable -> apps/ (binary, zipped into the drop)
|
|
105
105
|
mnci add go-app cli --release # ...released: tag + per-platform zips on the GitHub Release
|
|
106
|
+
mnci add go-app tray --cgo # needs a C toolchain: built on a runner of each OS
|
|
106
107
|
mnci add go-function-app fn # serverless handler -> apps/
|
|
107
108
|
mnci add go-lib core # publishable (by git tag) -> packages/
|
|
108
109
|
mnci add go-internal-lib util # private shared package -> libs/
|
|
@@ -122,6 +123,8 @@ mnci upgrade --agent windows-latest # ...with an explicit override
|
|
|
122
123
|
|
|
123
124
|
mnci doctor # check this workspace's invariants (read-only)
|
|
124
125
|
|
|
126
|
+
mnci ci verify # the pipeline's verify phase, run here: see `mnci ci` below
|
|
127
|
+
|
|
125
128
|
mnci sync # converge dependency ranges + nx sync (TS project refs)
|
|
126
129
|
mnci sync --check # ...report and exit non-zero, writing nothing
|
|
127
130
|
|
|
@@ -319,6 +322,35 @@ TTY, so a piped or CI run reports instead of hanging on a prompt), `-y/--yes`
|
|
|
319
322
|
(take everything), `--ecosystem`, and `--no-install` (edit the manifests but skip
|
|
320
323
|
the reinstall).
|
|
321
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
|
+
|
|
322
354
|
## `mnci doctor`: checking the invariants actually hold
|
|
323
355
|
|
|
324
356
|
Read-only — it never edits the workspace. Every failing finding names the command
|
|
@@ -688,6 +720,64 @@ the generated tree, so it runs afterwards, but still before the first write:
|
|
|
688
720
|
a refusal leaves the target byte-identical to how it was found, and the staging
|
|
689
721
|
copy is discarded.
|
|
690
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
|
+
|
|
691
781
|
## Layout convention = release scoping
|
|
692
782
|
|
|
693
783
|
| Directory | Contents | Released? |
|
|
@@ -1439,6 +1529,51 @@ pipeline installs `golangci-lint` itself (see below).
|
|
|
1439
1529
|
`nx-release-publish` target is written: there is nothing to push. The only
|
|
1440
1530
|
real difference between `go-lib` and `go-internal-lib` is intent, recorded
|
|
1441
1531
|
in the `type:go-lib` tag and the `packages/` location.
|
|
1532
|
+
- **Pure-Go apps are cross-compiled; an app that needs a C toolchain is not
|
|
1533
|
+
(`mnci add go-app <name> --cgo`).** `build-all` builds six static binaries from
|
|
1534
|
+
one machine with `CGO_ENABLED=0`, which is right until the app needs cgo: a
|
|
1535
|
+
system-tray icon (Cocoa on macOS, GTK on Linux), a native GUI toolkit, a cgo
|
|
1536
|
+
database driver. Those can only be built where the C toolchain and the target
|
|
1537
|
+
OS's libraries are, so a `--cgo` app is tagged `build:cgo` and gets
|
|
1538
|
+
`build-native` and `package-native` (this machine only, `CGO_ENABLED=1`, the
|
|
1539
|
+
same `VERSION` stamp and `-trimpath`, the zip named as `package-all` names a
|
|
1540
|
+
platform's) **instead of** `package`, `build-all` and `package-all`. It keeps
|
|
1541
|
+
`build`, `test`, `lint` and `start` for local work.
|
|
1542
|
+
- **A `native` job, only when such an app exists.** The generated pipeline
|
|
1543
|
+
gains a job with one leg each on `windows-latest`, `macos-latest` and
|
|
1544
|
+
`ubuntu-latest` (GitHub Actions: a matrix; Azure Pipelines: a matrix of
|
|
1545
|
+
`vmImage`s, with the original job moved under `jobs:`). Each leg lints,
|
|
1546
|
+
tests, builds and packages the native apps and publishes its zips as an
|
|
1547
|
+
artifact. The single-agent verify excludes them (`--exclude=tag:build:cgo`),
|
|
1548
|
+
because it cannot build them. A workspace with no native app keeps a
|
|
1549
|
+
pipeline byte-identical to the one it had: the job is decided when the file is
|
|
1550
|
+
written, since neither provider can skip a whole job on a file's existence.
|
|
1551
|
+
- **Run `mnci upgrade` after adding one.** `add` does not rewrite the
|
|
1552
|
+
pipeline files, so until then CI would verify the app on the one agent that
|
|
1553
|
+
cannot build it. `mnci add` says so, and `mnci doctor` fails while a
|
|
1554
|
+
pipeline lacks the job, and while no C compiler is installed on the machine
|
|
1555
|
+
(it reads `CC`, then `gcc`, `clang`, `cc`).
|
|
1556
|
+
- **Linux prerequisites are yours to finish.** The leg installs a C compiler
|
|
1557
|
+
and `pkg-config`, which is all mnci can know. The `-dev` packages your app
|
|
1558
|
+
links (`libgtk-3-dev` and `libayatana-appindicator3-dev` for a tray icon) go
|
|
1559
|
+
on that one marked line in the pipeline. The macOS runner ships Xcode's tools,
|
|
1560
|
+
and the Windows leg relies on the hosted image's MinGW-w64 `gcc`: the nightly
|
|
1561
|
+
e2e builds a cgo app on `windows-latest`, and says so loudly if it finds no
|
|
1562
|
+
compiler there rather than passing.
|
|
1563
|
+
- **Architectures: one per OS, the runner's own.** `windows-latest` and
|
|
1564
|
+
`ubuntu-latest` are amd64 and `macos-latest` is arm64, so a native app ships
|
|
1565
|
+
`windows-amd64`, `linux-amd64` and `darwin-arm64`. `darwin-amd64`,
|
|
1566
|
+
`linux-arm64` and `windows-arm64` are not built: they need an Intel macOS
|
|
1567
|
+
runner, an arm Linux runner or a cross-compiler. The legs are fixed in the
|
|
1568
|
+
generated pipeline today, so adding one means editing a file `mnci upgrade`
|
|
1569
|
+
rewrites (russoedu/MoNecromanCi#269 is about giving that a safe place).
|
|
1570
|
+
- **Releasing one.** With `--release` as well, each leg, on a push to main and
|
|
1571
|
+
after the `ci` job has tagged, runs
|
|
1572
|
+
`node tools/go-app-release.cjs assets --native`, which builds
|
|
1573
|
+
`package-native` with `VERSION` set to the tag's version and uploads that
|
|
1574
|
+
OS's zip to the same GitHub Release, so one release collects a zip from every
|
|
1575
|
+
runner. Azure Pipelines has no GitHub Release to attach to and stops at the
|
|
1576
|
+
artifact.
|
|
1442
1577
|
- **Releasing a Go app is an opt-in: `mnci add go-app <name> --release`.** The
|
|
1443
1578
|
app is tagged `release:go`, which `release.projects` selects by tag (as it
|
|
1444
1579
|
does for a VS Code extension, so `mnci upgrade` keeps it). Without the flag
|
|
@@ -1472,8 +1607,8 @@ pipeline installs `golangci-lint` itself (see below).
|
|
|
1472
1607
|
commits that touch an app's dependencies, not only its own folder (measured:
|
|
1473
1608
|
a `fix:` touching only an imported `go-internal-lib` produced a patch
|
|
1474
1609
|
release of the app), which is right for a binary that links the library in.
|
|
1475
|
-
-
|
|
1476
|
-
|
|
1610
|
+
- An app that needs a C toolchain is released from several runners instead:
|
|
1611
|
+
see _Pure-Go apps are cross-compiled_ above. This step builds all six
|
|
1477
1612
|
platforms on one runner, which is what `CGO_ENABLED=0` allows.
|
|
1478
1613
|
- **No publish-time dependency injection**, unlike Python's vendoring: `go
|
|
1479
1614
|
build` links statically, so the binary in the drop already contains
|