redkite 0.1.9 → 0.1.10
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 +131 -11
- package/dist/build.d.ts +1 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +7 -1
- package/dist/build.js.map +1 -1
- package/dist/cli/agent.js +2 -2
- package/dist/cli/agent.js.map +1 -1
- package/dist/cli/config.d.ts +1 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +67 -14
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/dotenv.d.ts +2 -0
- package/dist/cli/dotenv.d.ts.map +1 -0
- package/dist/cli/dotenv.js +30 -0
- package/dist/cli/dotenv.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +11 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/screen.d.ts +10 -3
- package/dist/cli/screen.d.ts.map +1 -1
- package/dist/cli/screen.js +153 -36
- package/dist/cli/screen.js.map +1 -1
- package/dist/cli/viewer.d.ts.map +1 -1
- package/dist/cli/viewer.js +36 -4
- package/dist/cli/viewer.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +12 -2
- package/dist/deploy.js.map +1 -1
- package/dist/docker.d.ts +1 -0
- package/dist/docker.d.ts.map +1 -1
- package/dist/docker.js +3 -0
- package/dist/docker.js.map +1 -1
- package/dist/dockerfile.d.ts +1 -0
- package/dist/dockerfile.d.ts.map +1 -1
- package/dist/dockerfile.js +16 -3
- package/dist/dockerfile.js.map +1 -1
- package/dist/environment.d.ts +2 -0
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +56 -1
- package/dist/environment.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +1 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +1 -0
- package/dist/log.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +3 -0
- package/dist/pipeline.js.map +1 -1
- package/dist/plugins/bitwarden.d.ts.map +1 -1
- package/dist/plugins/bitwarden.js +25 -6
- package/dist/plugins/bitwarden.js.map +1 -1
- package/dist/presets/nextApp.d.ts.map +1 -1
- package/dist/presets/nextApp.js +5 -4
- package/dist/presets/nextApp.js.map +1 -1
- package/dist/presets/nodeApp.d.ts.map +1 -1
- package/dist/presets/nodeApp.js +15 -6
- package/dist/presets/nodeApp.js.map +1 -1
- package/dist/secrets/manager.d.ts +9 -0
- package/dist/secrets/manager.d.ts.map +1 -0
- package/dist/secrets/manager.js +130 -0
- package/dist/secrets/manager.js.map +1 -0
- package/dist/secrets/store.d.ts.map +1 -1
- package/dist/secrets/store.js +46 -12
- package/dist/secrets/store.js.map +1 -1
- package/dist/services/ensure.js +1 -1
- package/dist/services/ensure.js.map +1 -1
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +11 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/planned.d.ts +0 -1
- package/dist/services/planned.d.ts.map +1 -1
- package/dist/services/planned.js +3 -12
- package/dist/services/planned.js.map +1 -1
- package/dist/services/proxy.d.ts +7 -0
- package/dist/services/proxy.d.ts.map +1 -0
- package/dist/services/proxy.js +103 -0
- package/dist/services/proxy.js.map +1 -0
- package/dist/source.d.ts +1 -0
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +5 -5
- package/dist/source.js.map +1 -1
- package/dist/steps.d.ts +1 -6
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +3 -3
- package/dist/steps.js.map +1 -1
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/build.ts +10 -1
- package/src/cli/agent.ts +2 -2
- package/src/cli/config.ts +77 -13
- package/src/cli/dotenv.ts +35 -0
- package/src/cli/index.ts +11 -5
- package/src/cli/screen.ts +193 -43
- package/src/cli/viewer.ts +41 -4
- package/src/config.ts +11 -0
- package/src/deploy.ts +14 -2
- package/src/docker.ts +5 -0
- package/src/dockerfile.ts +23 -3
- package/src/environment.ts +71 -1
- package/src/index.ts +2 -1
- package/src/log.ts +4 -0
- package/src/pipeline.ts +4 -0
- package/src/plugins/bitwarden.ts +38 -11
- package/src/presets/nextApp.ts +5 -4
- package/src/presets/nodeApp.ts +15 -6
- package/src/secrets/manager.ts +172 -0
- package/src/secrets/store.ts +51 -16
- package/src/services/ensure.ts +1 -1
- package/src/services/index.ts +13 -1
- package/src/services/planned.ts +3 -13
- package/src/services/proxy.ts +126 -0
- package/src/source.ts +13 -4
- package/src/steps.ts +7 -7
- package/src/types.ts +19 -4
- package/dist/nginx.d.ts +0 -4
- package/dist/nginx.d.ts.map +0 -1
- package/dist/nginx.js +0 -53
- package/dist/nginx.js.map +0 -1
- package/src/nginx.ts +0 -63
package/README.md
CHANGED
|
@@ -224,6 +224,12 @@ find them. `package.json` is where a repository says otherwise:
|
|
|
224
224
|
}
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
+
The deployment does not have to be one of them. A repository that keeps
|
|
228
|
+
`redkite.config.ts` at its root and the environment files together under
|
|
229
|
+
`deploy/` works the same way: the directory is read for environments whether or
|
|
230
|
+
not the deployment turned out to be in it. Naming a directory that is not there
|
|
231
|
+
is still refused, and one environment defined in both places is too.
|
|
232
|
+
|
|
227
233
|
Then `deploy/redkite.config.ts` and `deploy/redkite.production.config.ts`. If
|
|
228
234
|
that directory holds no config, redkite stops and says so rather than carrying
|
|
229
235
|
on up the tree: naming a directory and not putting the files there is a mistake,
|
|
@@ -343,6 +349,22 @@ When the deploy host is another machine, an app built from a path forces the
|
|
|
343
349
|
build to happen here and the image to be shipped, the same as `--local`. The
|
|
344
350
|
source is on this machine, so the builder is too.
|
|
345
351
|
|
|
352
|
+
#### Dependencies fetched over ssh
|
|
353
|
+
|
|
354
|
+
A `git+ssh` entry in a manifest is resolved during the install, inside the
|
|
355
|
+
build, long after the checkout on the host is finished. That needs three things
|
|
356
|
+
the checkout does not, and redkite arranges all of them when this process holds
|
|
357
|
+
an agent: `openssh-client` in the builder, the agent forwarded in as a
|
|
358
|
+
`--mount=type=ssh`, and `GIT_SSH_COMMAND` set to accept a host on first sight.
|
|
359
|
+
|
|
360
|
+
A run with no agent asks for none of it, because a mount with nothing behind it
|
|
361
|
+
fails the build outright. Whether it was forwarded is part of what the image is
|
|
362
|
+
tagged by, so an image built without one is never mistaken for an image built
|
|
363
|
+
with one.
|
|
364
|
+
|
|
365
|
+
Nothing else is needed: the same agent that lets the deploy host clone the
|
|
366
|
+
repository is what the build reaches through.
|
|
367
|
+
|
|
346
368
|
### Build presets
|
|
347
369
|
|
|
348
370
|
`nodeApp` and `nextApp` describe a two-stage build: a fat builder image with
|
|
@@ -365,6 +387,13 @@ The dependency install is not one of the `steps`. The preset copies
|
|
|
365
387
|
alone, so a commit that changes only source code reuses the layer. That is the
|
|
366
388
|
difference between a deploy and a cold build.
|
|
367
389
|
|
|
390
|
+
The package manager's download cache is a cache mount; `node_modules` is a
|
|
391
|
+
layer. They are not interchangeable, because a cache mount is evicted on its
|
|
392
|
+
own schedule and the layer that filled it is not: once the two disagree, the
|
|
393
|
+
install is cached, the mount is empty, and the build runs against no
|
|
394
|
+
dependencies at all. `caches` therefore defaults to the download caches only,
|
|
395
|
+
and what a build needs on disk is written into the image.
|
|
396
|
+
|
|
368
397
|
#### What a build is allowed not to produce
|
|
369
398
|
|
|
370
399
|
A `COPY` whose source is missing fails the build. That is right for the output,
|
|
@@ -437,6 +466,34 @@ prompt nobody is there to answer is a deploy that hangs rather than one that
|
|
|
437
466
|
fails. Cloning is separate and always `accept-new`, because the deploy host
|
|
438
467
|
reaches GitHub rather than reaching you.
|
|
439
468
|
|
|
469
|
+
### The proxy
|
|
470
|
+
|
|
471
|
+
Apps carry routes and routes need something to resolve them, so redkite derives
|
|
472
|
+
exactly one proxy. It is not listed under `services`, and a service by that
|
|
473
|
+
name is refused. What it runs and what goes around the block redkite renders is
|
|
474
|
+
`proxy`:
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
proxy: nginx({
|
|
478
|
+
maxBodySize: "1024M",
|
|
479
|
+
server: ["server_tokens off;", "add_header X-Frame-Options SAMEORIGIN;"],
|
|
480
|
+
location: ["proxy_read_timeout 300s;", "proxy_set_header Upgrade $http_upgrade;"],
|
|
481
|
+
}),
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
`server` lines go inside the server block above the locations, `location` lines
|
|
485
|
+
inside every location. Both are written as nginx sees them, semicolons and all.
|
|
486
|
+
|
|
487
|
+
**A line replaces rather than repeats.** nginx refuses a second
|
|
488
|
+
`proxy_read_timeout` outright instead of letting the later one win, so
|
|
489
|
+
`proxy_read_timeout 300s;` takes the place of the 30s redkite would have set. A
|
|
490
|
+
header keeps its own name as part of that, so `proxy_set_header Host $host;`
|
|
491
|
+
replaces only the Host header and leaves the other three alone.
|
|
492
|
+
|
|
493
|
+
The upstreams, the location per route, the failover and `listen` stay derived.
|
|
494
|
+
A `listen` in the server block is refused: the published port maps onto the one
|
|
495
|
+
inside the container, so only one side of that may say it.
|
|
496
|
+
|
|
440
497
|
### Services
|
|
441
498
|
|
|
442
499
|
Long-lived containers shared by the apps. The proxy is not one of them: apps
|
|
@@ -513,6 +570,17 @@ The same is true of the migrations and checks that run in the builder image:
|
|
|
513
570
|
they are given `--env-file` too, rather than finding a file the build left
|
|
514
571
|
behind.
|
|
515
572
|
|
|
573
|
+
A vault holds dotenv, and docker's env file is a different format wearing the
|
|
574
|
+
same clothes: a quote there is part of the value, not around it. So the file
|
|
575
|
+
handed to `--env-file` is the parsed values rather than the text that held them,
|
|
576
|
+
and `DATABASE_URL="postgres://..."` reaches the process without the quotes it
|
|
577
|
+
was stored with. The `.env` mounted during the build stays exactly as the vault
|
|
578
|
+
wrote it, because the thing reading it there is a dotenv parser.
|
|
579
|
+
|
|
580
|
+
A value spanning several lines has no spelling docker would read back, so one is
|
|
581
|
+
refused by name rather than truncated. Anything shaped like that is a
|
|
582
|
+
[file secret](#a-secret-the-app-needs-as-a-file).
|
|
583
|
+
|
|
516
584
|
If you do want one in the image, say so, in a build step where the mount is
|
|
517
585
|
still there:
|
|
518
586
|
|
|
@@ -520,13 +588,28 @@ still there:
|
|
|
520
588
|
steps: ["yarn build", "cp .env dist/.env"],
|
|
521
589
|
```
|
|
522
590
|
|
|
523
|
-
|
|
524
|
-
|
|
591
|
+
#### A secret the app needs as a file
|
|
592
|
+
|
|
593
|
+
`files` maps a container path to the item whose contents land there, for a
|
|
594
|
+
credential that has to be a file rather than a variable:
|
|
525
595
|
|
|
526
596
|
```ts
|
|
527
|
-
files: {
|
|
597
|
+
files: {
|
|
598
|
+
"/etc/creds/service-account.json": bitwarden.item("..."),
|
|
599
|
+
"/app/private.pem": bitwarden.item("..."),
|
|
600
|
+
},
|
|
528
601
|
```
|
|
529
602
|
|
|
603
|
+
It is copied into the runtime image, after the output has landed, so it is
|
|
604
|
+
there before the process starts and survives a restart. The directory is made
|
|
605
|
+
first, so the path does not have to be one the image already has. Each one is
|
|
606
|
+
mounted as its own build secret, and lands `-r--------` owned by root.
|
|
607
|
+
|
|
608
|
+
This is the deliberate exception to nothing-from-a-vault-in-an-image: it is
|
|
609
|
+
named, at a path the config chose, and anyone who can pull the image can read
|
|
610
|
+
it. For a credential that should not be in a layer, put it in the environment
|
|
611
|
+
instead and have the app write it out itself.
|
|
612
|
+
|
|
530
613
|
## Hooks
|
|
531
614
|
|
|
532
615
|
A run is one list of steps, each handed what the one before it answered with.
|
|
@@ -619,6 +702,24 @@ there is nothing to set before a step can use it.
|
|
|
619
702
|
A step naming an app the deployment does not have fails before the run starts
|
|
620
703
|
rather than half way through it.
|
|
621
704
|
|
|
705
|
+
#### Saying which machine the migration goes through
|
|
706
|
+
|
|
707
|
+
A migration reaches its database through one particular machine, and the step
|
|
708
|
+
runs on whatever host the environment deploys to. Naming that machine turns a
|
|
709
|
+
move nobody rechecked into a refusal:
|
|
710
|
+
|
|
711
|
+
```ts
|
|
712
|
+
migrate({
|
|
713
|
+
app: "backend",
|
|
714
|
+
command: "yarn db:migrate",
|
|
715
|
+
through: "deploy@staging.acme.example",
|
|
716
|
+
})
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
Deploy that environment to any other host and the run stops before it touches
|
|
720
|
+
anything. It is optional, and a deployment that leaves it out simply runs the
|
|
721
|
+
migration wherever it deploys.
|
|
722
|
+
|
|
622
723
|
#### The network a step runs on
|
|
623
724
|
|
|
624
725
|
A migration defaults to `host`: the deploy host's own network stack, which is
|
|
@@ -919,16 +1020,23 @@ open and its output rolls under a title that stays put; a step that finishes
|
|
|
919
1020
|
shuts to a single line carrying what it cost.
|
|
920
1021
|
|
|
921
1022
|
```
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1023
|
+
00:04 ✔ setup 4s
|
|
1024
|
+
00:13 ✔ build 13s
|
|
1025
|
+
01:18 ⠙ ▾ Building web: yarn build quiet 8s 1m05s
|
|
925
1026
|
│ #15 [builder 10/10] RUN yarn build
|
|
926
1027
|
│ ▲ Next.js 15.1.6
|
|
927
1028
|
│ Creating an optimized production build ...
|
|
1029
|
+
· verify
|
|
1030
|
+
· swap
|
|
1031
|
+
· cleanup
|
|
928
1032
|
|
|
929
|
-
↑↓ move · enter open · shift+↑ latest ·
|
|
1033
|
+
↑↓ move · enter open · shift+↑ latest · +/- all · w wrap · q quit
|
|
930
1034
|
```
|
|
931
1035
|
|
|
1036
|
+
The points under the open step are the ones the run will still walk. A deploy
|
|
1037
|
+
knows its whole list before it starts, so how much is left is on screen from the
|
|
1038
|
+
first frame rather than only at the end.
|
|
1039
|
+
|
|
932
1040
|
| Key | What it does |
|
|
933
1041
|
| --- | --- |
|
|
934
1042
|
| `↑` `↓` | Scroll the open step's output, then move between steps once it runs out |
|
|
@@ -937,11 +1045,20 @@ shuts to a single line carrying what it cost.
|
|
|
937
1045
|
| `shift+↓` | Jump to the first step |
|
|
938
1046
|
| `+` | Open the step running now, from anywhere, and keep opening the ones after it |
|
|
939
1047
|
| `-` | Shut everything, and stop opening what comes next |
|
|
1048
|
+
| `w` | Wrap long lines instead of cutting them, for reading an error that does not fit |
|
|
940
1049
|
| `q` | Stop the deploy. Press again to kill it |
|
|
941
1050
|
|
|
942
1051
|
The gutter counts the whole run; the number on the right counts the step, and
|
|
943
|
-
freezes at what it cost the moment it finishes.
|
|
944
|
-
|
|
1052
|
+
freezes at what it cost the moment it finishes. A spinner turns beside the step
|
|
1053
|
+
running now, and stops with it, which is how a slow step is told from a wedged
|
|
1054
|
+
one at a glance. When that step has said nothing for a while the row says
|
|
1055
|
+
`quiet 45s`, because a build that has stopped talking looks exactly like a build
|
|
1056
|
+
that has stopped.
|
|
1057
|
+
|
|
1058
|
+
Nothing drawn on the alternate screen survives it, so the run is written out
|
|
1059
|
+
again on the way out. A step that failed has the end of its own output written
|
|
1060
|
+
with it, since the reason it stopped is in there and the frames carrying it are
|
|
1061
|
+
gone.
|
|
945
1062
|
|
|
946
1063
|
Colour separates where you are from what is happening. The step under the
|
|
947
1064
|
cursor is cyan, the step running now is yellow, and a failed one is red and
|
|
@@ -955,8 +1072,11 @@ wide, and a row measured with one in it is a row that wraps.
|
|
|
955
1072
|
|
|
956
1073
|
Every row is one terminal line. A line too long for the width is cut with an
|
|
957
1074
|
ellipsis rather than wrapped, because a wrapped row pushes everything under it
|
|
958
|
-
out of a frame counted in rows.
|
|
959
|
-
|
|
1075
|
+
out of a frame counted in rows. `w` turns wrapping on for the times that trade
|
|
1076
|
+
is worth making, and the space a step is given is then counted in rows rather
|
|
1077
|
+
than lines, so a wrapped line gets the rows it needs. `--full` is the way to
|
|
1078
|
+
read the untrimmed thing: no view, no collapsing, every line of every step
|
|
1079
|
+
streamed in full as it arrives.
|
|
960
1080
|
|
|
961
1081
|
A pipe, a CI log or `REDKITE_PLAIN=1` gets that same streamed form, with
|
|
962
1082
|
`--verbose` adding every host command beside it.
|
package/dist/build.d.ts
CHANGED
package/dist/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAM1C,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzC,GAAG,EAAE,MAAM,CAAC;IAEZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAM1C,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzC,GAAG,EAAE,MAAM,CAAC;IAEZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IAGpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAOF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAEhB,WAAW,EAAE,MAAM,CAAC;IAEpB,GAAG,EAAE,MAAM,CAAC;IAIZ,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAKF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CAKvD;AAED,wBAAsB,KAAK,CACzB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC,CA0FtB"}
|
package/dist/build.js
CHANGED
|
@@ -5,7 +5,7 @@ import { prepareSource } from "./source.js";
|
|
|
5
5
|
// Bumped when the pipeline changes shape without the config changing. The tag
|
|
6
6
|
// below is what tells a host it already holds an image, and a host that trusts
|
|
7
7
|
// the commit alone serves the last pipeline's output forever
|
|
8
|
-
const PIPELINE = "
|
|
8
|
+
const PIPELINE = "6";
|
|
9
9
|
// The app's own, or the environment's branch when it names none. A branch is
|
|
10
10
|
// the only thing an environment can say, because a tag or a commit is a claim
|
|
11
11
|
// about one repository and an environment spans every app
|
|
@@ -28,6 +28,7 @@ export async function build(app, topology, context) {
|
|
|
28
28
|
path: app.path && resolve(app.path),
|
|
29
29
|
include: app.include,
|
|
30
30
|
ref: refOf(app, context.branch),
|
|
31
|
+
output: context.output,
|
|
31
32
|
submodules: spec.submodules,
|
|
32
33
|
detail,
|
|
33
34
|
});
|
|
@@ -57,12 +58,14 @@ export async function build(app, topology, context) {
|
|
|
57
58
|
envSecret: secrets.env.id,
|
|
58
59
|
fileSecrets: Object.fromEntries(secrets.files.map((file) => [file.path, file.id])),
|
|
59
60
|
dir: app.dir,
|
|
61
|
+
agent: context.agent,
|
|
60
62
|
}));
|
|
61
63
|
// BuildKit reads this beside the Dockerfile rather than inside the context,
|
|
62
64
|
// which is what lets the checkout stay a checkout: the repository keeps its
|
|
63
65
|
// own .dockerignore, and .git never enters the build
|
|
64
66
|
await host.write(`${app.name}.Dockerfile.dockerignore`, renderDockerignore(app.include));
|
|
65
67
|
const invocation = {
|
|
68
|
+
ssh: context.agent,
|
|
66
69
|
context: source.tree,
|
|
67
70
|
dockerfile,
|
|
68
71
|
secrets: Object.fromEntries([secrets.env, ...secrets.files].map((secret) => [secret.id, secret.src])),
|
|
@@ -133,6 +136,9 @@ function fingerprintOf(app, context, release) {
|
|
|
133
136
|
.update(PIPELINE)
|
|
134
137
|
.update(release)
|
|
135
138
|
.update(app.dir ?? "")
|
|
139
|
+
// It changes the Dockerfile, so an image built without one is not the
|
|
140
|
+
// image a build with one would produce
|
|
141
|
+
.update(String(context.agent ?? false))
|
|
136
142
|
.update(JSON.stringify(app.build))
|
|
137
143
|
.update(context.env)
|
|
138
144
|
.update(JSON.stringify(Object.entries(context.files).sort()))
|
package/dist/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGtF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/agent.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { environmentOf } from "../config.js";
|
|
3
|
-
// Cloning private repositories and
|
|
4
|
-
// agent, so a deploy without one fails halfway rather than at the start
|
|
3
|
+
// Cloning private repositories and reaching the deploy host both go through
|
|
4
|
+
// the agent, so a deploy without one fails halfway rather than at the start
|
|
5
5
|
// Asked before one is demanded. A runner has no keys and no way to be prompted
|
|
6
6
|
// for one, and a deployment that reaches no other machine and clones nothing
|
|
7
7
|
// has no use for an agent: insisting on one there is a green run turned red
|
package/dist/cli/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/cli/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/cli/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,4EAA4E;AAC5E,4EAA4E;AAE5E,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,MAAkB,EAAE,WAAmB;IAChE,IAAI,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IAEnE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,6EAA6E;AAC7E,mEAAmE;AACnE,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,uEAAuE;AACvE,4BAA4B;AAC5B,MAAM,UAAU,YAAY,CAAC,IAA+B;IAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAEnC,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAExD,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC;IACtC,IAAI,GAAG;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC;IAE5C,wEAAwE;IACxE,IAAI,CAAC;QACH,YAAY,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,wEAAwE;YACtE,wEAAwE;YACxE,qEAAqE;YACrE,aAAa,CAChB,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ import type { Deployment, Environment } from "../types.js";
|
|
|
2
2
|
export declare function loadConfig(explicit?: string): Promise<Deployment>;
|
|
3
3
|
export declare function discover(from: string): string;
|
|
4
4
|
export declare function loadEnvironments(directory: string): Promise<Record<string, Environment>>;
|
|
5
|
+
export declare function projectRoot(explicit?: string): string;
|
|
5
6
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/cli/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmC3D,wBAAsB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmC3D,wBAAsB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAmCvE;AA4CD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4C7C;AAcD,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,wCA4BvD;AA2CD,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,UAG5C"}
|
package/dist/cli/config.js
CHANGED
|
@@ -32,21 +32,36 @@ const LOADER = new Set([
|
|
|
32
32
|
export async function loadConfig(explicit) {
|
|
33
33
|
const path = explicit ? resolve(explicit) : discover(process.cwd());
|
|
34
34
|
const config = defaultOf(await load(path), path);
|
|
35
|
+
const manifest = manifestOf(explicit ? dirname(path) : process.cwd());
|
|
35
36
|
const beside = await loadEnvironments(dirname(path));
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
// The directory package.json names is read whether or not the deployment
|
|
38
|
+
// turned out to be in it, so environments may sit together under one roof
|
|
39
|
+
// with the deployment at the root above them
|
|
40
|
+
const declared = directoryOf(manifest);
|
|
41
|
+
const under = declared && declared !== dirname(path) ? await loadEnvironments(declared) : {};
|
|
42
|
+
const named = await loadNamed(manifest);
|
|
43
|
+
const found = { ...beside, ...under };
|
|
44
|
+
for (const name of Object.keys(under)) {
|
|
38
45
|
if (!beside[name])
|
|
39
46
|
continue;
|
|
47
|
+
throw new Error(`${name} sits both beside the deployment and in ${declared}, ` +
|
|
48
|
+
"and an environment comes from one place or the other");
|
|
49
|
+
}
|
|
50
|
+
for (const name of Object.keys(named)) {
|
|
51
|
+
if (!found[name])
|
|
52
|
+
continue;
|
|
40
53
|
throw new Error(`${name} is named by package.json and also sits beside the deployment. ` +
|
|
41
54
|
"An environment comes from one place or the other");
|
|
42
55
|
}
|
|
43
|
-
return { ...rooted(config, dirname(path)), environments: { ...
|
|
56
|
+
return { ...rooted(config, dirname(path)), environments: { ...found, ...named } };
|
|
44
57
|
}
|
|
45
58
|
// A source path belongs to the file that named it, not to wherever the command
|
|
46
59
|
// was run. Resolving it here is what lets a deploy from a workspace and one
|
|
47
60
|
// from the root build the same tree
|
|
48
61
|
function rooted(config, directory) {
|
|
49
|
-
|
|
62
|
+
// A file that never called defineDeployment can export anything, and the
|
|
63
|
+
// message worth getting is the one topologyFor gives rather than a TypeError
|
|
64
|
+
if (!(config.apps ?? []).some((app) => app.path))
|
|
50
65
|
return config;
|
|
51
66
|
return {
|
|
52
67
|
...config,
|
|
@@ -76,24 +91,51 @@ async function loadNamed(manifest) {
|
|
|
76
91
|
// likely to be run from a workspace inside it as from there
|
|
77
92
|
export function discover(from) {
|
|
78
93
|
let directory = from;
|
|
94
|
+
// Where something addressed to redkite was seen but no deployment. Naming it
|
|
95
|
+
// is the difference between "there is nothing here" and "the file you have
|
|
96
|
+
// is an environment, and an environment is not a deployment"
|
|
97
|
+
const nearby = [];
|
|
79
98
|
for (;;) {
|
|
80
99
|
const declared = directoryFrom(directory);
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
// Naming a directory that is not there is a mistake worth stopping for.
|
|
101
|
+
// One that is there and holds no deployment is not: it may hold only the
|
|
102
|
+
// environments, and the deployment may sit at the root above them
|
|
103
|
+
if (declared && !existsSync(declared))
|
|
104
|
+
missing(declared, directory);
|
|
105
|
+
const there = declared && found(declared);
|
|
106
|
+
if (there)
|
|
107
|
+
return there;
|
|
85
108
|
const here = found(directory);
|
|
86
109
|
if (here)
|
|
87
110
|
return here;
|
|
111
|
+
for (const place of declared ? [declared, directory] : [directory]) {
|
|
112
|
+
for (const entry of environmentsAt(place))
|
|
113
|
+
nearby.push(join(place, entry));
|
|
114
|
+
}
|
|
88
115
|
const parent = dirname(directory);
|
|
89
116
|
if (parent === directory)
|
|
90
117
|
break;
|
|
91
118
|
directory = parent;
|
|
92
119
|
}
|
|
120
|
+
if (nearby.length > 0) {
|
|
121
|
+
throw new Error(`No deployment found, but ${nearby.join(" and ")} reads as an environment. ` +
|
|
122
|
+
"An environment says which branch and which subnet; the deployment says " +
|
|
123
|
+
"the project, the apps and the services, and is redkite.config.ts");
|
|
124
|
+
}
|
|
93
125
|
throw new Error(`No redkite.config.ts found in ${from} or any directory above it. A deployment ` +
|
|
94
126
|
'is one file at the root of the project, or wherever package.json\'s ' +
|
|
95
127
|
'"redkite": { "directory": … } says it is');
|
|
96
128
|
}
|
|
129
|
+
// The names beside a deployment that would be read as environments, for a
|
|
130
|
+
// message that can say what was there instead of what was not
|
|
131
|
+
function environmentsAt(directory) {
|
|
132
|
+
if (!existsSync(directory))
|
|
133
|
+
return [];
|
|
134
|
+
return readdirSync(directory)
|
|
135
|
+
.filter((entry) => !CANDIDATES.includes(entry))
|
|
136
|
+
.filter((entry) => PER_ENVIRONMENT.test(entry))
|
|
137
|
+
.sort();
|
|
138
|
+
}
|
|
97
139
|
// Every environment that lives in a file of its own, keyed by the name in it
|
|
98
140
|
export async function loadEnvironments(directory) {
|
|
99
141
|
const environments = {};
|
|
@@ -127,8 +169,7 @@ function found(directory) {
|
|
|
127
169
|
return undefined;
|
|
128
170
|
}
|
|
129
171
|
function missing(declared, from) {
|
|
130
|
-
throw new Error(`${join(from, "package.json")} points redkite at ${declared}, which
|
|
131
|
-
`redkite.config.${EXTENSIONS.join(", redkite.config.")}`);
|
|
172
|
+
throw new Error(`${join(from, "package.json")} points redkite at ${declared}, which is not there`);
|
|
132
173
|
}
|
|
133
174
|
function manifestAt(directory) {
|
|
134
175
|
const path = join(directory, "package.json");
|
|
@@ -143,6 +184,13 @@ function manifestAt(directory) {
|
|
|
143
184
|
return undefined;
|
|
144
185
|
}
|
|
145
186
|
}
|
|
187
|
+
// Where the project starts, which is where a .env belongs. The nearest
|
|
188
|
+
// package.json above wherever this was run, and the directory itself when
|
|
189
|
+
// there is none
|
|
190
|
+
export function projectRoot(explicit) {
|
|
191
|
+
const from = explicit ? dirname(resolve(explicit)) : process.cwd();
|
|
192
|
+
return manifestOf(from)?.root ?? from;
|
|
193
|
+
}
|
|
146
194
|
// The nearest one above wherever this was run, which is the same walk the
|
|
147
195
|
// config itself is found by
|
|
148
196
|
function manifestOf(from) {
|
|
@@ -157,11 +205,16 @@ function manifestOf(from) {
|
|
|
157
205
|
directory = parent;
|
|
158
206
|
}
|
|
159
207
|
}
|
|
160
|
-
// package.json says where
|
|
161
|
-
//
|
|
208
|
+
// package.json says where redkite's files live, for a repository that would
|
|
209
|
+
// rather not keep them at its root
|
|
162
210
|
function directoryFrom(directory) {
|
|
163
|
-
|
|
164
|
-
|
|
211
|
+
return directoryOf(manifestAt(directory));
|
|
212
|
+
}
|
|
213
|
+
function directoryOf(manifest) {
|
|
214
|
+
if (!manifest)
|
|
215
|
+
return undefined;
|
|
216
|
+
const declared = manifest.redkite.directory;
|
|
217
|
+
return typeof declared === "string" ? resolve(manifest.root, declared) : undefined;
|
|
165
218
|
}
|
|
166
219
|
function defaultOf(module, path) {
|
|
167
220
|
const found = module;
|
package/dist/cli/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,8EAA8E;AAC9E,uEAAuE;AACvE,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,kBAAkB;AAElB,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC;AAEvD,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;AAEhF,6EAA6E;AAC7E,+EAA+E;AAC/E,sEAAsE;AACtE,2EAA2E;AAC3E,sDAAsD;AACtD,MAAM,eAAe,GAAG,8DAA8D,CAAC;AAEvF,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAElD,+EAA+E;AAC/E,gFAAgF;AAChF,wEAAwE;AACxE,6EAA6E;AAC7E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;IACrB,4BAA4B;IAC5B,mCAAmC;IACnC,sBAAsB;IACtB,8BAA8B;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAiB;IAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAe,CAAC;IAE/D,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.d.ts","sourceRoot":"","sources":["../../src/cli/dotenv.ts"],"names":[],"mappings":"AAoBA,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAchE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parseEnv } from "../environment.js";
|
|
4
|
+
// The credentials a deploy needs are the one thing that cannot live in the
|
|
5
|
+
// config, so they live beside it. Read here rather than by a plugin, because
|
|
6
|
+
// which file answers depends on the environment being deployed and a plugin
|
|
7
|
+
// is handed neither the directory nor the name.
|
|
8
|
+
// Most specific first. A deploy file is for what only a deploy needs, and it
|
|
9
|
+
// wins over the one the application itself reads
|
|
10
|
+
const NAMES = (environment) => [
|
|
11
|
+
`.env.${environment}.deploy`,
|
|
12
|
+
`.env.${environment}`,
|
|
13
|
+
".env",
|
|
14
|
+
];
|
|
15
|
+
// Only what is missing. Anything already in the environment was set by the
|
|
16
|
+
// person running this or by the job, and neither should be talked over
|
|
17
|
+
export function loadDotenv(directory, environment) {
|
|
18
|
+
const read = [];
|
|
19
|
+
for (const name of NAMES(environment)) {
|
|
20
|
+
const path = join(directory, name);
|
|
21
|
+
if (!existsSync(path))
|
|
22
|
+
continue;
|
|
23
|
+
read.push(name);
|
|
24
|
+
for (const [key, value] of Object.entries(parseEnv(readFileSync(path, "utf8")))) {
|
|
25
|
+
process.env[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return read;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=dotenv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.js","sourceRoot":"","sources":["../../src/cli/dotenv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,gDAAgD;AAEhD,6EAA6E;AAC7E,iDAAiD;AACjD,MAAM,KAAK,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC;IACrC,QAAQ,WAAW,SAAS;IAC5B,QAAQ,WAAW,EAAE;IACrB,MAAM;CACP,CAAC;AAEF,2EAA2E;AAC3E,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,WAAmB;IAC/D,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAEhC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AA+F1D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAgBxC;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,2BASxC;AA4QD,wBAAgB,OAAO,CAAC,EAAE,EAAE;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,cAwBA;AAkCD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAehF"}
|
package/dist/cli/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { deploy, verify } from "../deploy.js";
|
|
|
3
3
|
import { Docker } from "../docker.js";
|
|
4
4
|
import { localHost } from "../localHost.js";
|
|
5
5
|
import { silent } from "../log.js";
|
|
6
|
-
import {
|
|
6
|
+
import { renderProxy } from "../services/proxy.js";
|
|
7
7
|
import { addressOf, RUNS, SLOTS } from "../pipeline.js";
|
|
8
8
|
import { listRefs } from "../secrets/refs.js";
|
|
9
9
|
import { pluginSteps, storeFor } from "../plugin.js";
|
|
@@ -12,7 +12,8 @@ import { driftOf, plannedServices } from "../services/planned.js";
|
|
|
12
12
|
import { sshHost } from "../sshHost.js";
|
|
13
13
|
import { topologyFor } from "../topology.js";
|
|
14
14
|
import { needsAgent, requireAgent } from "./agent.js";
|
|
15
|
-
import { loadConfig } from "./config.js";
|
|
15
|
+
import { loadConfig, projectRoot } from "./config.js";
|
|
16
|
+
import { loadDotenv } from "./dotenv.js";
|
|
16
17
|
import { createLog, describeFailure } from "./log.js";
|
|
17
18
|
// One command that reads the config and does everything under it: the agent,
|
|
18
19
|
// the vault, the checkout, the build, the swap and the cleanup.
|
|
@@ -116,8 +117,11 @@ async function dispatch(argv) {
|
|
|
116
117
|
return process.stdout.write(`${await version()}\n`);
|
|
117
118
|
}
|
|
118
119
|
const configPath = flag(argv, "--config");
|
|
120
|
+
// Before anything reads a credential out of the environment, and only where
|
|
121
|
+
// the environment does not already say. What the job set wins over a file
|
|
122
|
+
const read = loadDotenv(projectRoot(configPath), environment);
|
|
119
123
|
if (command === "plan")
|
|
120
|
-
return await plan(environment, configPath);
|
|
124
|
+
return await plan(environment, configPath, read);
|
|
121
125
|
if (command === "rollback" || command === "down") {
|
|
122
126
|
return await recover(command, environment, configPath);
|
|
123
127
|
}
|
|
@@ -163,11 +167,13 @@ async function recover(command, environment, configPath) {
|
|
|
163
167
|
function asLog(say) {
|
|
164
168
|
return Object.assign(say, { warn: say, fail: say, done: say, step: () => silent.step("") });
|
|
165
169
|
}
|
|
166
|
-
async function plan(environment, configPath) {
|
|
170
|
+
async function plan(environment, configPath, read = []) {
|
|
167
171
|
const config = await loadConfig(configPath);
|
|
168
172
|
const topology = topologyFor(config, environment);
|
|
169
173
|
const say = (message = "") => process.stdout.write(`${message}\n`);
|
|
170
174
|
say(`# ${config.project} · ${environment}\n`);
|
|
175
|
+
if (read.length > 0)
|
|
176
|
+
say(`read ${read.join(", ")}`);
|
|
171
177
|
say(`network ${topology.network} ${topology.cidr}`);
|
|
172
178
|
say(`branch ${topology.branch}`);
|
|
173
179
|
// A verify environment publishes nothing, because nothing in one serves
|
|
@@ -204,7 +210,7 @@ async function plan(environment, configPath) {
|
|
|
204
210
|
if (!serves)
|
|
205
211
|
return;
|
|
206
212
|
say(`\n# rendered nginx ${"-".repeat(44)}\n`);
|
|
207
|
-
say(
|
|
213
|
+
say(renderProxy(topology, config.proxy));
|
|
208
214
|
}
|
|
209
215
|
// What is running against what this file says should be. Services outlive a
|
|
210
216
|
// deploy, so this is the only part of a plan that cannot be answered from the
|