@localctl/cli 0.4.1 โ†’ 0.4.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
@@ -75,17 +75,19 @@ JSON file per app.
75
75
  |---|---|
76
76
  | **macOS** or **Windows** | Windows commands run in PowerShell. |
77
77
  | **Node.js 18+** | Needed to install the CLI from npm. |
78
- | **Container engine** | [Podman Desktop](https://podman-desktop.io/), running. See [supported container engines](#supported-container-engines). |
78
+ | **Container engine** | [Podman Desktop](https://podman-desktop.io/) (or Docker Desktop / Rancher Desktop), running. See [supported container engines](#supported-container-engines). |
79
79
  | **Homebrew** or **winget** | Used once by `localctl setup` to install missing tools. |
80
80
 
81
81
  `localctl setup` installs `k3d`, `kubectl`, `tilt`, `mkcert` and `helm` for you if they're missing.
82
+ On Windows, Tilt isn't on winget, so it's downloaded from its GitHub release into
83
+ `~.localctl ools` and added to your user PATH.
82
84
 
83
85
  ### Supported container engines
84
86
 
85
87
  | Engine | Status |
86
88
  |---|---|
87
89
  | [Podman Desktop](https://podman-desktop.io/) | โœ… Tested |
88
- | [Docker Desktop](https://www.docker.com/products/docker-desktop/) | ๐Ÿงช Experimental โ€” not yet tested |
90
+ | [Docker Desktop](https://www.docker.com/products/docker-desktop/) | ๐Ÿงช Experimental โ€” setup and app deploy verified on Windows |
89
91
  | [Rancher Desktop](https://rancherdesktop.io/) | ๐Ÿงช Experimental โ€” not yet tested |
90
92
 
91
93
  Experimental engines are detected and should work, since k3d only needs a Docker-compatible API,
@@ -106,7 +108,9 @@ the local image registry, trusts the `*.local.test` certificate, and updates you
106
108
  is idempotent: run it again any time to repair your environment.
107
109
 
108
110
  You'll see up to two one-time prompts during setup: **mkcert** asking to trust its local
109
- certificate authority, and **sudo/Administrator** to write the `*.local.test` hosts entries.
111
+ certificate authority, and **admin rights** to write the `*.local.test` hosts entries (your
112
+ `sudo` password on macOS, a UAC prompt on Windows). Approve both: without the hosts entries, apps
113
+ run but their addresses don't resolve.
110
114
 
111
115
  **Pre-releases** are published under the `beta` tag: `npm install -g @localctl/cli@beta`.
112
116
 
@@ -120,7 +124,8 @@ Update available: 0.2.0 -> 0.3.0
120
124
  Run npm install -g @localctl/cli to update.
121
125
  ```
122
126
 
123
- Update with `npm install -g @localctl/cli`. The check never slows a command down, is skipped in
127
+ Update with `npm install -g @localctl/cli`. On a pre-release you're also told about newer
128
+ versions on your own channel (e.g. `beta`). The check never slows a command down, is skipped in
124
129
  CI, and can be turned off with `LOCALCTL_NO_UPDATE_CHECK=1`.
125
130
 
126
131
  <details>
@@ -204,6 +209,16 @@ localctl app down
204
209
 
205
210
  This removes only that app. The shared cluster keeps running for everything else.
206
211
 
212
+ <details>
213
+ <summary><b>App is ready but <code>https://&lt;app&gt;.local.test</code> doesn't open?</b></summary>
214
+
215
+ If `localctl app status` shows `1/1` but the browser can't reach the address, the hosts file
216
+ entry is missing: the `sudo` or UAC prompt was declined or missed. Run `localctl hosts sync` and
217
+ approve the prompt. More cases, with cause and fix:
218
+ [**Troubleshooting**](https://psilvmoreira.github.io/localctl/troubleshooting/).
219
+
220
+ </details>
221
+
207
222
  > **Tip:** no app of your own yet? Clone the repo and try a ready-made example:
208
223
  > [`node-app`](https://github.com/psilvmoreira/localctl/tree/master/examples/node-app) (Node.js + Postgres),
209
224
  > [`python-app`](https://github.com/psilvmoreira/localctl/tree/master/examples/python-app) (Python + Redis), or
@@ -211,7 +226,8 @@ This removes only that app. The shared cluster keeps running for everything else
211
226
 
212
227
  ## Commands
213
228
 
214
- Run `localctl <command> --help` for every option.
229
+ Run `localctl <command> --help` for every option, or see the full
230
+ [**CLI reference**](https://psilvmoreira.github.io/localctl/cli-reference/).
215
231
 
216
232
  <details open>
217
233
  <summary><b>Machine setup</b></summary>
@@ -220,7 +236,7 @@ Run `localctl <command> --help` for every option.
220
236
  |---|---|
221
237
  | `localctl setup` | Install or repair the infrastructure: container engine, cluster, TLS, hosts. Idempotent. |
222
238
  | `localctl doctor` | Health check of the active project's environment. |
223
- | `localctl hosts sync` / `list` | Manage the `*.local.test` entries in your hosts file. |
239
+ | `localctl hosts sync` / `list` | Write or list the `*.local.test` entries in your hosts file. Asks for admin rights when needed. |
224
240
  | `localctl uninstall [-y]` | Remove every cluster, registry, hosts entry, certificate and state file `localctl` created. |
225
241
 
226
242
  </details>
@@ -235,7 +251,7 @@ Run `localctl <command> --help` for every option.
235
251
  | `localctl app down` | Stop the dev loop and remove the app. Keeps its data. |
236
252
  | `localctl app reload [-a <name>]` | Force a rebuild and redeploy without waiting for a file change. |
237
253
  | `localctl app status [-a <name>] [-A]` | One app's detail inside its repository, or a table of every app. |
238
- | `localctl app logs <name> [-f]` | Show or follow an app's logs. |
254
+ | `localctl app logs [name] [-f]` | Show or follow an app's logs. Inside its repository the name is optional. |
239
255
  | `localctl app exec [cmd...]` | Open a shell (default `sh`) in the app's pod. |
240
256
  | `localctl app prune [-y]` | Delete leftover data (volumes, secrets) of apps already taken down. |
241
257
  | `localctl app secrets set <KEY> [value]` | Store a secret as a Kubernetes Secret, never in `config.json`. |
@@ -324,6 +340,7 @@ The full documentation lives at **[psilvmoreira.github.io/localctl](https://psil
324
340
  | [Adding tools](https://psilvmoreira.github.io/localctl/adding-tools/) | Write your own per-app or cluster-wide addon |
325
341
  | [Troubleshooting](https://psilvmoreira.github.io/localctl/troubleshooting/) | Known issues, with cause and fix |
326
342
  | [Uninstalling](https://psilvmoreira.github.io/localctl/uninstalling/) | Full teardown reference |
343
+ | [Contributing](https://psilvmoreira.github.io/localctl/contributing/) | Local setup, tests, pull requests, dependency policy, docs site |
327
344
  | [Releasing](https://psilvmoreira.github.io/localctl/releasing/) | How versions are cut and published |
328
345
 
329
346
  ## Releases and versioning
@@ -334,16 +351,21 @@ The full documentation lives at **[psilvmoreira.github.io/localctl](https://psil
334
351
  with notes and the package tarball.
335
352
  - Versions follow [Semantic Versioning](https://semver.org). Before `1.0.0`, minor versions may
336
353
  contain breaking changes.
337
- - npm releases are published from GitHub Actions with
354
+ - Every pull request shows a **release preview**: the version that merging it would publish,
355
+ including any unreleased commits already on `master`.
356
+ - npm releases are published from GitHub Actions through
357
+ [trusted publishing](https://docs.npmjs.com/trusted-publishers) (no npm tokens) with
338
358
  [provenance](https://docs.npmjs.com/generating-provenance-statements). The npm package page links
339
359
  each version to the exact commit and workflow run that built it.
360
+ - Dependencies and GitHub Actions are kept up to date by Dependabot, with every action pinned to a
361
+ commit SHA.
340
362
 
341
363
  ## Contributing
342
364
 
343
365
  Issues and pull requests are welcome. The full guide (constraints, dependency policy, working on
344
366
  the docs site) is in [**Contributing**](https://psilvmoreira.github.io/localctl/contributing/).
345
367
 
346
- 1. Fork the repository and create a branch.
368
+ 1. Fork the repository and create a branch from an up-to-date `master`.
347
369
  2. Make your change and run the tests:
348
370
  ```sh
349
371
  cd cli
@@ -352,15 +374,19 @@ the docs site) is in [**Contributing**](https://psilvmoreira.github.io/localctl/
352
374
  npm run test:pack # the published package installs and runs
353
375
  ```
354
376
  3. Open a pull request with a [Conventional Commits](https://www.conventionalcommits.org/) title.
355
- The title decides the next version:
377
+ PRs are squash-merged, so the title decides the next version. GitHub pre-fills it from the
378
+ branch name, which fails the title check: edit it.
356
379
 
357
380
  | Title | Release |
358
381
  |---|---|
359
- | `fix: ...` | Patch (`0.2.0` โ†’ `0.2.1`) |
360
- | `feat: ...` | Minor (`0.2.1` โ†’ `0.3.0`) |
361
- | `feat!: ...` | Major (`0.3.0` โ†’ `1.0.0`) |
382
+ | `fix: ...`, `perf: ...` | Patch (`0.4.0` โ†’ `0.4.1`) |
383
+ | `feat: ...` | Minor (`0.4.1` โ†’ `0.5.0`) |
384
+ | `feat!: ...` | Major (`0.5.0` โ†’ `1.0.0`) |
362
385
  | `docs:` `chore:` `ci:` `refactor:` `test:` | No release |
363
386
 
387
+ 4. Check the **release preview** on the `pr-title` check and wait for every check to pass
388
+ (title, tests on Linux/macOS/Windows ร— Node 18/22, docs build, non-empty diff).
389
+
364
390
  <details>
365
391
  <summary><b>Repository layout</b></summary>
366
392
 
@@ -376,8 +402,10 @@ localctl/
376
402
  โ”œโ”€โ”€ cluster/manifests/ cluster-level manifests (TLS store, addon namespace)
377
403
  โ”œโ”€โ”€ schema/ JSON Schema for .local/config.json
378
404
  โ”œโ”€โ”€ examples/ ready-to-run sample apps
379
- โ”œโ”€โ”€ docs/ documentation site (MkDocs Material, deployed to GitHub Pages)
380
- โ””โ”€โ”€ bin/ bootstrap and uninstall scripts for source installs
405
+ โ”œโ”€โ”€ docs/ documentation pages (MkDocs Material, deployed to GitHub Pages)
406
+ โ”œโ”€โ”€ overrides/ docs site template overrides (landing page)
407
+ โ”œโ”€โ”€ bin/ bootstrap and uninstall scripts for source installs
408
+ โ””โ”€โ”€ .github/ CI, release and docs workflows, Dependabot config
381
409
  ```
382
410
 
383
411
  </details>
@@ -390,8 +418,10 @@ npm uninstall -g @localctl/cli # the CLI itself
390
418
  ```
391
419
 
392
420
  `localctl uninstall` asks for confirmation (skip with `-y`) and is safe to re-run. It leaves the
393
- shared tools (`k3d`, `kubectl`, `tilt`, `mkcert`, `node`) and mkcert's root CA installed, since
394
- other projects may use them. It prints the exact commands to remove them too. Installed from
421
+ shared tools (`k3d`, `kubectl`, `tilt`, `mkcert`, `helm`, `node`) and mkcert's root CA installed,
422
+ since other projects may use them. It prints the exact commands to remove them for your OS
423
+ (`brew uninstall ...` on macOS; `winget uninstall ...` plus the `~.localctl ools` folder for
424
+ Tilt on Windows). Installed from
395
425
  source with the bootstrap script? Use `./bin/uninstall.sh` or `./bin/uninstall.ps1` instead.
396
426
  Details: [**Uninstalling**](https://psilvmoreira.github.io/localctl/uninstalling/).
397
427
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localctl/cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "localctl - local Kubernetes dev platform CLI",
5
5
  "keywords": [
6
6
  "kubernetes",
@@ -24,6 +24,20 @@ function listApps() {
24
24
  return Object.keys(registry);
25
25
  }
26
26
 
27
+ // The Windows counterpart of `sudo cp`: copies src over the hosts file from an elevated
28
+ // PowerShell, which raises a UAC prompt. Returns false if the prompt is declined or the copy
29
+ // fails. The inner command goes through -EncodedCommand so paths need no nested quoting.
30
+ function copyElevatedWindows(src) {
31
+ const quote = (s) => `'${s.replace(/'/g, "''")}'`;
32
+ const inner = `Copy-Item -LiteralPath ${quote(src)} -Destination ${quote(HOSTS_PATH)} -Force`;
33
+ const encoded = Buffer.from(inner, 'utf16le').toString('base64');
34
+ const res = spawnSync('powershell', [
35
+ '-NoProfile', '-NonInteractive', '-Command',
36
+ `Start-Process powershell -Verb RunAs -Wait -WindowStyle Hidden -ArgumentList '-NoProfile','-NonInteractive','-EncodedCommand','${encoded}'`,
37
+ ], { stdio: 'ignore' });
38
+ return res.status === 0;
39
+ }
40
+
27
41
  function writeHosts(next, current) {
28
42
  if (next === current) {
29
43
  logger.info('Hosts file already up to date.');
@@ -38,8 +52,13 @@ function writeHosts(next, current) {
38
52
  const tmp = path.join(os.tmpdir(), 'localctl-hosts-new');
39
53
  fs.writeFileSync(tmp, next);
40
54
  if (process.platform === 'win32') {
41
- logger.warn('Need Administrator rights to update the hosts file. Run in an elevated PowerShell:');
42
- console.log(` Copy-Item "${tmp}" "${HOSTS_PATH}" -Force`);
55
+ logger.warn('Need Administrator rights to update the hosts file. Approve the Windows prompt to continue.');
56
+ if (copyElevatedWindows(tmp) && fs.readFileSync(HOSTS_PATH, 'utf8') === next) {
57
+ logger.success(`Updated ${HOSTS_PATH}`);
58
+ } else {
59
+ logger.warn('Hosts file not updated, so *.local.test addresses won\'t resolve. Run in an elevated PowerShell:');
60
+ console.log(` Copy-Item "${tmp}" "${HOSTS_PATH}" -Force`);
61
+ }
43
62
  } else {
44
63
  logger.warn('Need sudo to update the hosts file.');
45
64
  const res = spawnSync('sudo', ['cp', tmp, HOSTS_PATH], { stdio: 'inherit' });