@udondan/avanti 0.19.1 → 0.21.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 +239 -27
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +51 -12
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/lock.d.ts.map +1 -1
- package/dist/commands/lock.js +19 -5
- package/dist/commands/lock.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +135 -15
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/reset.d.ts.map +1 -1
- package/dist/commands/reset.js +1 -1
- package/dist/commands/reset.js.map +1 -1
- package/dist/commands/revert.d.ts.map +1 -1
- package/dist/commands/revert.js +1 -1
- package/dist/commands/revert.js.map +1 -1
- package/dist/condition.d.ts +4 -0
- package/dist/condition.d.ts.map +1 -0
- package/dist/condition.js +86 -0
- package/dist/condition.js.map +1 -0
- package/dist/config-writeback.d.ts.map +1 -1
- package/dist/config-writeback.js +26 -3
- package/dist/config-writeback.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +278 -34
- package/dist/config.js.map +1 -1
- package/dist/history.d.ts +9 -0
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +59 -1
- package/dist/history.js.map +1 -1
- package/dist/processors/insert.d.ts +3 -0
- package/dist/processors/insert.d.ts.map +1 -0
- package/dist/processors/insert.js +285 -0
- package/dist/processors/insert.js.map +1 -0
- package/dist/processors/json.d.ts +1 -1
- package/dist/processors/json.d.ts.map +1 -1
- package/dist/processors/json.js +124 -3
- package/dist/processors/json.js.map +1 -1
- package/dist/sources/index.d.ts +6 -2
- package/dist/sources/index.d.ts.map +1 -1
- package/dist/sources/index.js +89 -16
- package/dist/sources/index.js.map +1 -1
- package/dist/sources/s3.d.ts +1 -1
- package/dist/sources/s3.d.ts.map +1 -1
- package/dist/sources/s3.js +49 -48
- package/dist/sources/s3.js.map +1 -1
- package/dist/sources/secrets-manager.d.ts +5 -0
- package/dist/sources/secrets-manager.d.ts.map +1 -0
- package/dist/sources/secrets-manager.js +48 -0
- package/dist/sources/secrets-manager.js.map +1 -0
- package/dist/sources/ssm.d.ts +5 -0
- package/dist/sources/ssm.d.ts.map +1 -0
- package/dist/sources/ssm.js +79 -0
- package/dist/sources/ssm.js.map +1 -0
- package/dist/types.d.ts +68 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/variables-remote.d.ts +4 -0
- package/dist/variables-remote.d.ts.map +1 -0
- package/dist/variables-remote.js +52 -0
- package/dist/variables-remote.js.map +1 -0
- package/dist/variables.d.ts +2 -2
- package/dist/variables.d.ts.map +1 -1
- package/dist/variables.js.map +1 -1
- package/dist/writer.d.ts.map +1 -1
- package/dist/writer.js +1 -1
- package/dist/writer.js.map +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -15,11 +15,13 @@ atomic rollbacks, and diff-before-apply safety.
|
|
|
15
15
|
- [Usage](#usage)
|
|
16
16
|
- [`avanti diff`](#avanti-diff)
|
|
17
17
|
- [`avanti pull`](#avanti-pull)
|
|
18
|
+
- [`avanti lock`](#avanti-lock)
|
|
18
19
|
- [History](#history)
|
|
19
20
|
- [`avanti log`](#avanti-log)
|
|
20
21
|
- [`avanti diff <pullId>`](#avanti-diff-pullid)
|
|
21
22
|
- [`avanti revert [pullId]`](#avanti-revert-pullid)
|
|
22
23
|
- [`avanti reset`](#avanti-reset)
|
|
24
|
+
- [`--verbose` / `-v`](#--verbose---v)
|
|
23
25
|
- [Working Directory](#working-directory)
|
|
24
26
|
- [Path Constraints](#path-constraints)
|
|
25
27
|
- [Configuration](#configuration)
|
|
@@ -28,6 +30,9 @@ atomic rollbacks, and diff-before-apply safety.
|
|
|
28
30
|
- [Directory Sources](#directory-sources)
|
|
29
31
|
- [JSON Merging](#json-merging)
|
|
30
32
|
- [YAML Merging](#yaml-merging)
|
|
33
|
+
- [TOML Merging](#toml-merging)
|
|
34
|
+
- [Insert Mode](#insert-mode)
|
|
35
|
+
- [Conditions](#conditions)
|
|
31
36
|
- [Variables](#variables)
|
|
32
37
|
- [$self — Self-managing Config](#self--self-managing-config)
|
|
33
38
|
- [Authentication](#authentication)
|
|
@@ -38,7 +43,7 @@ atomic rollbacks, and diff-before-apply safety.
|
|
|
38
43
|
- [CI/CD: Shared Workflow Fragments](#cicd-shared-workflow-fragments)
|
|
39
44
|
- [CI/CD: Scheduled Sync PR](#cicd-scheduled-sync-pr)
|
|
40
45
|
- [Environment-Specific Config from a Single Spec](#environment-specific-config-from-a-single-spec)
|
|
41
|
-
- [Secrets from Vault or
|
|
46
|
+
- [Secrets from Vault or AWS](#secrets-from-vault-or-aws)
|
|
42
47
|
- [Multi-Project Deployment](#multi-project-deployment)
|
|
43
48
|
- [Docker Compose from Upstream Sources](#docker-compose-from-upstream-sources)
|
|
44
49
|
- [Developer Onboarding Bootstrap](#developer-onboarding-bootstrap)
|
|
@@ -90,16 +95,20 @@ avanti revert # roll back instantly if something breaks
|
|
|
90
95
|
|
|
91
96
|
## Features
|
|
92
97
|
|
|
93
|
-
- Fetch files from **HTTP/HTTPS**, **local paths**, **GitLab** (via `glab`), **GitHub** (via `gh`), **Bitbucket**, **any git remote**, **S3**, **HashiCorp Vault**, **shell commands**, or **inline raw content**
|
|
98
|
+
- Fetch files from **HTTP/HTTPS**, **local paths**, **GitLab** (via `glab`), **GitHub** (via `gh`), **Bitbucket**, **any git remote**, **S3**, **AWS Secrets Manager**, **SSM Parameter Store**, **HashiCorp Vault**, **shell commands**, or **inline raw content**
|
|
94
99
|
- **Multi-source entries** — combine multiple sources into a single file by providing `src` as a list
|
|
95
|
-
- **JSON merging** — deep-merge multiple JSON/JSONC sources with configurable conflict, array, and object strategies
|
|
100
|
+
- **JSON merging** — deep-merge multiple JSON/JSONC sources with configurable conflict, array, and object strategies; format output with configurable indentation, trailing commas, key sorting, minification, and comment stripping
|
|
96
101
|
- **YAML merging** — deep-merge multiple YAML/YML sources with the same strategies, with full comment preservation
|
|
97
|
-
- **
|
|
102
|
+
- **TOML merging** — deep-merge multiple TOML sources with configurable conflict, array, and table strategies
|
|
103
|
+
- **Variables** — define reusable values in a `variables:` block and reference them anywhere with `$name`; variables can be plain strings, `$env:NAME` environment variable references, or fetched from any remote/local source (the same source types as `files:`)
|
|
98
104
|
- **Post-processing** — apply text replacements (string or regex) and/or pipe content through a shell script
|
|
99
105
|
- **Directory sync** — recursively sync directories from GitLab/GitHub/Bitbucket/git/S3/local sources
|
|
106
|
+
- **SHA pinning** — pin any remote source to a content fingerprint with `sha:`; use `avanti lock` to compute and write SHAs automatically; `avanti pull --accept-changes` reviews a mismatch and updates the pin
|
|
107
|
+
- **`$self`** — avanti can manage its own config file; declare `$self` in `files:` and the fetched content becomes the active config for the rest of the run, including YAML/JSON merge from multiple sources
|
|
100
108
|
- **Diff preview** — see exactly what will change before applying, or compare against any past pull
|
|
101
109
|
- **Atomic writes** — all files are staged to a temp dir first; targets are only written if everything succeeds
|
|
102
110
|
- **History** — every pull is recorded; inspect what changed, revert the whole project to a past state, or fully undo all avanti changes
|
|
111
|
+
- **Conditions** — use `if` and `ifAny` on file entries or individual sources to conditionally skip based on OS, filesystem path existence, shell command exit code, or whether the target file already exists; supports AND/OR logic and negation with `not: true`
|
|
103
112
|
- **Optional sources** — mark `path:` and `url:` sources `optional: true` to silently skip them when the file is missing or the URL returns 404; lets a central config reference per-user local overrides without erroring on machines that haven't created them
|
|
104
113
|
- **Stale file cleanup** — files dropped from a directory source are automatically deleted or restored to their pre-avanti content
|
|
105
114
|
|
|
@@ -374,14 +383,17 @@ files:
|
|
|
374
383
|
|
|
375
384
|
End the target path with `/` to write a directory source as a mirror; omit the trailing slash to merge all files from the directory into a single output file (YAML/JSON auto-detected by extension, or forced with `yaml:`/`json:`).
|
|
376
385
|
|
|
377
|
-
| Field
|
|
378
|
-
|
|
|
379
|
-
| `src`
|
|
380
|
-
| `
|
|
381
|
-
| `
|
|
382
|
-
| `
|
|
383
|
-
| `
|
|
384
|
-
| `
|
|
386
|
+
| Field | Required | Description |
|
|
387
|
+
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
388
|
+
| `src` | Yes | Source (see below). May be a single source or a **list** of sources to concatenate. |
|
|
389
|
+
| `if` | No | Condition object (or list of objects). All must pass for the entry to be processed. See [Conditions](#conditions). |
|
|
390
|
+
| `ifAny` | No | List of condition objects. At least one must pass. See [Conditions](#conditions). |
|
|
391
|
+
| `mode` | No | File permission mode, e.g. `"0755"` |
|
|
392
|
+
| `replace` | No | List of `{from, to}` replacement rules. `from` may be a plain string or `/pattern/flags` regex. |
|
|
393
|
+
| `post` | No | Shell script. Content is piped via stdin; stdout is used as the result. Runs after `replace`. |
|
|
394
|
+
| `json` | No | JSON merge/format options (see below). When omitted, merging is auto-enabled if all sources have a `.json` or `.jsonc` extension. Use `true`/`false` to force on or off regardless of extension. |
|
|
395
|
+
| `yaml` | No | YAML merge/format options (see below). When omitted, merging is auto-enabled if all sources have a `.yaml` or `.yml` extension. Use `true`/`false` to force on or off regardless of extension. Comments are preserved in merged output. |
|
|
396
|
+
| `strategy` | No | Write strategy: `replace` _(default)_ — overwrite the target file entirely; `insert` — merge content into the existing file without clobbering unrelated content. See [Insert Mode](#insert-mode). |
|
|
385
397
|
|
|
386
398
|
### Source Types
|
|
387
399
|
|
|
@@ -393,7 +405,8 @@ src: ~/templates/file.txt
|
|
|
393
405
|
src: /absolute/path/file.txt
|
|
394
406
|
```
|
|
395
407
|
|
|
396
|
-
**Map** — for path, url, exec, gitlab, github, bitbucket, git,
|
|
408
|
+
**Map** — for path, url, exec, gitlab, github, bitbucket, git, aws_s3,
|
|
409
|
+
aws_secrets_manager, aws_systems_manager_parameter, vault, http, raw:
|
|
397
410
|
|
|
398
411
|
```yaml
|
|
399
412
|
src:
|
|
@@ -461,9 +474,22 @@ src:
|
|
|
461
474
|
url: git+ssh://git@ssh.git.private.de/org/repo.git//path/to/file.txt@main
|
|
462
475
|
|
|
463
476
|
src:
|
|
464
|
-
|
|
477
|
+
aws_s3: s3://my-bucket/path/to/file.txt # end with / for a prefix sync
|
|
465
478
|
sha: abc123... # optional SHA-256 fingerprint
|
|
466
479
|
|
|
480
|
+
src:
|
|
481
|
+
aws_secrets_manager:
|
|
482
|
+
name: myapp/prod/db # secret name or ARN
|
|
483
|
+
key: password # optional: extract one field from a JSON secret
|
|
484
|
+
region: us-east-1 # optional: AWS region (default: SDK chain)
|
|
485
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
486
|
+
|
|
487
|
+
src:
|
|
488
|
+
aws_systems_manager_parameter:
|
|
489
|
+
name: /myapp/prod/db-host # parameter name; end with / for path prefix fetch
|
|
490
|
+
region: us-east-1 # optional: AWS region (default: SDK chain)
|
|
491
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
492
|
+
|
|
467
493
|
src:
|
|
468
494
|
vault:
|
|
469
495
|
path: secret/myapp/config # Vault KV path (mount/subpath)
|
|
@@ -521,7 +547,7 @@ files:
|
|
|
521
547
|
# S3 prefix → local directory (trailing / triggers sync)
|
|
522
548
|
configs/:
|
|
523
549
|
src:
|
|
524
|
-
|
|
550
|
+
aws_s3: s3://my-bucket/configs/
|
|
525
551
|
|
|
526
552
|
# Local directory → local directory
|
|
527
553
|
.githooks/:
|
|
@@ -608,6 +634,11 @@ files:
|
|
|
608
634
|
conflicts: last_wins # abort | first_wins | last_wins (default)
|
|
609
635
|
arrays: replace # replace (default) | concat
|
|
610
636
|
objects: merge # merge (default) | replace
|
|
637
|
+
indent: 2 # number of spaces, or "tab"
|
|
638
|
+
trailing_commas: false # add trailing comma after last item (valid JSONC)
|
|
639
|
+
sort_keys: false # sort object keys alphabetically
|
|
640
|
+
minify: false # collapse to single line, strips comments
|
|
641
|
+
strip_comments: false # remove JSONC comments from output
|
|
611
642
|
```
|
|
612
643
|
|
|
613
644
|
- `conflicts` — what to do when the same key holds a scalar (or an array/object when their strategy is `replace`):
|
|
@@ -620,6 +651,11 @@ files:
|
|
|
620
651
|
- `objects` — how to combine objects (maps) at the same key:
|
|
621
652
|
- `merge` _(default)_ — deep merge, applying the same rules recursively to nested keys
|
|
622
653
|
- `replace` — the later source's object replaces the earlier one entirely
|
|
654
|
+
- `indent` _(default: `2`)_ — indentation: a non-negative integer for spaces, or `"tab"` for tab characters
|
|
655
|
+
- `trailing_commas` _(default: `false`)_ — append a trailing comma after the last element in every array and object; valid JSONC syntax that produces cleaner diffs
|
|
656
|
+
- `sort_keys` _(default: `false`)_ — sort all object keys alphabetically (recursive); useful for stable diffs regardless of insertion order; rebuilds objects from scratch so JSONC comments are not preserved in the output
|
|
657
|
+
- `minify` _(default: `false`)_ — collapse output to a single line with no whitespace; also strips JSONC comments since they are not valid in strict JSON; overrides `indent` and `trailing_commas`
|
|
658
|
+
- `strip_comments` _(default: `false`)_ — remove all JSONC comments from the output, producing valid strict JSON; also overrides `trailing_commas` (strict JSON does not support trailing commas)
|
|
623
659
|
|
|
624
660
|
**Pretty-printing a single file** — `json` works on single-source entries too. Auto-detection applies here as well, so a single `.json` source is pretty-printed automatically:
|
|
625
661
|
|
|
@@ -761,6 +797,129 @@ files:
|
|
|
761
797
|
src: ./config.toml
|
|
762
798
|
```
|
|
763
799
|
|
|
800
|
+
### Insert Mode
|
|
801
|
+
|
|
802
|
+
By default (`strategy: replace`) avanti overwrites the target file with the fully processed source content. Set `strategy: insert` to **merge** content into an existing file instead of replacing it.
|
|
803
|
+
|
|
804
|
+
```yaml
|
|
805
|
+
files:
|
|
806
|
+
.vscode/settings.json:
|
|
807
|
+
src: ./shared/vscode-settings.json
|
|
808
|
+
json: true
|
|
809
|
+
strategy: insert
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
**How it works:**
|
|
813
|
+
|
|
814
|
+
- **First run** — the fetched content is merged into the existing file (or written as-is if the file does not exist yet).
|
|
815
|
+
- **Subsequent runs (no-op)** — avanti detects that the raw source and the post-processed output (`replace`/`post`) are both unchanged and skips the file entirely.
|
|
816
|
+
- **Subsequent runs (source changed)** — avanti removes the keys/text it previously contributed, then merges the updated content in.
|
|
817
|
+
- **User edits are preserved** — keys or text the user added or modified are left untouched. If a user overrides an avanti-managed key, avanti will not remove it even if the source no longer includes it.
|
|
818
|
+
|
|
819
|
+
**Structured files (JSON / YAML / TOML):**
|
|
820
|
+
|
|
821
|
+
Avanti tracks which keys it contributed in the previous pull. On the next pull it removes only those keys (if they still match) and then merges the new contribution. This means:
|
|
822
|
+
|
|
823
|
+
- Keys removed from the remote source are removed from the local file.
|
|
824
|
+
- Keys the user added or modified independently are preserved.
|
|
825
|
+
- Nested objects and arrays are handled recursively. For arrays, combine with `arrays: concat` so avanti appends items; avanti removes only the items it previously appended, leaving user-owned items intact.
|
|
826
|
+
|
|
827
|
+
```yaml
|
|
828
|
+
files:
|
|
829
|
+
tsconfig.json:
|
|
830
|
+
src: https://example.com/shared-tsconfig.json
|
|
831
|
+
json:
|
|
832
|
+
objects: merge
|
|
833
|
+
arrays: concat
|
|
834
|
+
strategy: insert
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
**Plain text:**
|
|
838
|
+
|
|
839
|
+
On the first insert, the text is appended to the existing file. On subsequent runs, the old block is replaced in-place when the source changes; if it is no longer found (e.g. the user removed it), the new block is appended.
|
|
840
|
+
|
|
841
|
+
### Conditions
|
|
842
|
+
|
|
843
|
+
Use `if` and `ifAny` on a file entry or on an individual source to control when it is processed.
|
|
844
|
+
|
|
845
|
+
**`if`** — a condition object (or list of objects) where **all** checks must pass (AND).
|
|
846
|
+
|
|
847
|
+
**`ifAny`** — a list of condition objects where **at least one** must pass (OR).
|
|
848
|
+
|
|
849
|
+
When both are present, both must pass. Each condition object may also include `not: true` to invert its result.
|
|
850
|
+
|
|
851
|
+
#### Condition fields
|
|
852
|
+
|
|
853
|
+
| Field | Type | Description |
|
|
854
|
+
| --------------- | -------------- | --------------------------------------------------------------------------- |
|
|
855
|
+
| `os` | string or list | Platform must match. Values: `linux`, `mac`, `windows`. List = any matches. |
|
|
856
|
+
| `exists` | string | Path (file or directory) must exist. Variables are resolved. |
|
|
857
|
+
| `exec` | string | Shell command must exit with code `0`. |
|
|
858
|
+
| `target_exists` | `true` | Skip entry if the target path does not already exist (update-only guard). |
|
|
859
|
+
| `not` | boolean | `true` — invert the result of all checks in this condition object. |
|
|
860
|
+
|
|
861
|
+
#### Examples
|
|
862
|
+
|
|
863
|
+
```yaml
|
|
864
|
+
files:
|
|
865
|
+
# Only on Linux
|
|
866
|
+
/etc/app.conf:
|
|
867
|
+
if:
|
|
868
|
+
os: linux
|
|
869
|
+
src: ...
|
|
870
|
+
|
|
871
|
+
# Skip on Windows
|
|
872
|
+
~/.config/app.conf:
|
|
873
|
+
if:
|
|
874
|
+
os: windows
|
|
875
|
+
not: true
|
|
876
|
+
src: ...
|
|
877
|
+
|
|
878
|
+
# Only if Docker is installed
|
|
879
|
+
~/.docker/config.json:
|
|
880
|
+
if:
|
|
881
|
+
exec: which docker
|
|
882
|
+
src: ...
|
|
883
|
+
|
|
884
|
+
# Only update — never create
|
|
885
|
+
~/.ssh/config:
|
|
886
|
+
if:
|
|
887
|
+
target_exists: true
|
|
888
|
+
src: ...
|
|
889
|
+
|
|
890
|
+
# OR: write if on mac OR if app is installed
|
|
891
|
+
app.conf:
|
|
892
|
+
ifAny:
|
|
893
|
+
- os: mac
|
|
894
|
+
- exec: which app
|
|
895
|
+
src: ...
|
|
896
|
+
|
|
897
|
+
# Combined AND + OR
|
|
898
|
+
combined.conf:
|
|
899
|
+
if:
|
|
900
|
+
os: windows
|
|
901
|
+
not: true
|
|
902
|
+
ifAny:
|
|
903
|
+
- exists: /opt/app
|
|
904
|
+
- exec: which app
|
|
905
|
+
src: ...
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
Conditions also apply at the **source level** within a multi-source entry (plain string sources excluded — use `path:` or `url:` wrapper form):
|
|
909
|
+
|
|
910
|
+
```yaml
|
|
911
|
+
files:
|
|
912
|
+
platform.conf:
|
|
913
|
+
src:
|
|
914
|
+
- raw: "# linux config\n"
|
|
915
|
+
if:
|
|
916
|
+
os: linux
|
|
917
|
+
- raw: "# mac config\n"
|
|
918
|
+
if:
|
|
919
|
+
os: mac
|
|
920
|
+
- path: /common/base.conf
|
|
921
|
+
```
|
|
922
|
+
|
|
764
923
|
### Variables
|
|
765
924
|
|
|
766
925
|
Define reusable values at the top level under `variables:`:
|
|
@@ -826,6 +985,52 @@ replace:
|
|
|
826
985
|
|
|
827
986
|
Referencing an undefined variable or a missing environment variable is an error.
|
|
828
987
|
|
|
988
|
+
#### Source-based variables
|
|
989
|
+
|
|
990
|
+
A variable can be populated from any remote or local source — the same source types supported by `files:`. Instead of a plain string value, provide a `src:` key:
|
|
991
|
+
|
|
992
|
+
```yaml
|
|
993
|
+
variables:
|
|
994
|
+
auth_token:
|
|
995
|
+
src:
|
|
996
|
+
aws_secrets_manager:
|
|
997
|
+
name: my-artifactory-token
|
|
998
|
+
registry_host: my-registry.example.com
|
|
999
|
+
|
|
1000
|
+
files:
|
|
1001
|
+
.npmrc:
|
|
1002
|
+
src:
|
|
1003
|
+
raw: |
|
|
1004
|
+
registry=https://$registry_host
|
|
1005
|
+
//$registry_host/:_authToken=$auth_token
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
The fetched content is trimmed of leading and trailing whitespace before being used as the variable value (secrets from AWS Secrets Manager, SSM Parameter Store, Vault, etc. often include a trailing newline).
|
|
1009
|
+
|
|
1010
|
+
All source types are supported: `http`, `path`, `url`, `exec`, `github`, `gitlab`, `bitbucket`, `git`, `aws_s3`, `aws_secrets_manager`, `aws_systems_manager_parameter`, `vault`, and `raw`. Multi-source arrays and `json`/`yaml`/`toml` merging work exactly as they do in `files:`:
|
|
1011
|
+
|
|
1012
|
+
```yaml
|
|
1013
|
+
variables:
|
|
1014
|
+
config:
|
|
1015
|
+
src:
|
|
1016
|
+
- raw: '{"base":"value"}'
|
|
1017
|
+
- raw: '{"extra":"added"}'
|
|
1018
|
+
json:
|
|
1019
|
+
conflicts: last_wins
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
**Evaluation order** — variables are resolved one by one in the order they are defined. A variable may reference any variable defined above it. Referencing a variable that has not yet been defined (a forward reference) is an error. This rule also prevents circular dependencies.
|
|
1023
|
+
|
|
1024
|
+
```yaml
|
|
1025
|
+
variables:
|
|
1026
|
+
host: registry.example.com
|
|
1027
|
+
token:
|
|
1028
|
+
src:
|
|
1029
|
+
aws_secrets_manager:
|
|
1030
|
+
name: my-token # fetched first; $host is already resolved
|
|
1031
|
+
registry_line: //$host/:_authToken=$token # both $host and $token are available
|
|
1032
|
+
```
|
|
1033
|
+
|
|
829
1034
|
`$latest` is a reserved keyword that resolves to the latest published version and cannot be used as a variable name. For GitLab it resolves to the latest tag sorted by semantic version. For GitHub it resolves to the tag of the latest release; if the repository has no releases, it falls back to the most recently created tag. For Bitbucket it resolves to the latest tag sorted by name; if no tags exist, it falls back to the repository's default branch.
|
|
830
1035
|
|
|
831
1036
|
When `ref` is omitted, all source types (GitHub, GitLab, Bitbucket, git) resolve to the repository's default branch.
|
|
@@ -878,14 +1083,16 @@ files:
|
|
|
878
1083
|
|
|
879
1084
|
Public repositories on github.com and gitlab.com work without any configuration. For private repositories or instances, supply credentials via environment variables:
|
|
880
1085
|
|
|
881
|
-
| Platform
|
|
882
|
-
|
|
|
883
|
-
| GitHub
|
|
884
|
-
| GitLab
|
|
885
|
-
| Bitbucket
|
|
886
|
-
| Bitbucket
|
|
887
|
-
| S3
|
|
888
|
-
|
|
|
1086
|
+
| Platform | Environment variable(s) | Notes |
|
|
1087
|
+
| --------------- | ---------------------------------------------------------------- | ------------------------------------------ |
|
|
1088
|
+
| GitHub | `GITHUB_TOKEN` | `Authorization: Bearer <token>` |
|
|
1089
|
+
| GitLab | `GITLAB_TOKEN` or `GITLAB_PRIVATE_TOKEN` | `PRIVATE-TOKEN: <token>` |
|
|
1090
|
+
| Bitbucket | `BITBUCKET_TOKEN` | `Authorization: Bearer <token>` |
|
|
1091
|
+
| Bitbucket | `BITBUCKET_USERNAME` + `BITBUCKET_APP_PASSWORD` | Basic auth (alternative to token) |
|
|
1092
|
+
| S3 | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
1093
|
+
| Secrets Manager | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
1094
|
+
| SSM | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
1095
|
+
| Vault | `VAULT_TOKEN` + `VAULT_ADDR` (and optionally `VAULT_NAMESPACE`) | Used when the `vault` CLI is not installed |
|
|
889
1096
|
|
|
890
1097
|
If a GitHub or GitLab request fails with a 401, 403, or 404 response, or with a network-level connectivity error, and `gh` / `glab` is installed and authenticated, the tool falls back to the CLI automatically. This means existing CLI setups continue to work for private repos without any extra configuration.
|
|
891
1098
|
|
|
@@ -900,7 +1107,8 @@ HTTP server errors (5xx) do not trigger CLI fallback regardless of the `via` ord
|
|
|
900
1107
|
|
|
901
1108
|
**Vault** uses the `vault` CLI when it is installed (picks up `VAULT_TOKEN`, `~/.vault-token`, and any other auth methods configured in the CLI). If the CLI is not available, it falls back to the HTTP API using `VAULT_ADDR` and `VAULT_TOKEN`.
|
|
902
1109
|
|
|
903
|
-
**S3
|
|
1110
|
+
**S3, Secrets Manager, and SSM** use the AWS SDK default credential chain (env
|
|
1111
|
+
vars, `~/.aws/credentials`, instance profiles, etc.).
|
|
904
1112
|
|
|
905
1113
|
### Private Instances
|
|
906
1114
|
|
|
@@ -1123,9 +1331,13 @@ files:
|
|
|
1123
1331
|
|
|
1124
1332
|
CI sets `DEPLOY_VERSION` and `ENVIRONMENT`; the config pins every file to exactly the version being deployed.
|
|
1125
1333
|
|
|
1126
|
-
### Secrets from Vault or
|
|
1334
|
+
### Secrets from Vault or AWS
|
|
1127
1335
|
|
|
1128
|
-
Pull secrets at runtime and write them to local files with tight permissions.
|
|
1336
|
+
Pull secrets at runtime and write them to local files with tight permissions.
|
|
1337
|
+
The native `vault:` source authenticates via the Vault CLI or `VAULT_TOKEN` env
|
|
1338
|
+
var. The `aws_s3:`, `aws_secrets_manager:`, and `aws_systems_manager_parameter:`
|
|
1339
|
+
sources authenticate via the AWS SDK credential chain (env vars, `~/.aws/credentials`,
|
|
1340
|
+
IAM roles). No shell scripting needed.
|
|
1129
1341
|
|
|
1130
1342
|
```yaml
|
|
1131
1343
|
files:
|
|
@@ -1147,7 +1359,7 @@ files:
|
|
|
1147
1359
|
# Config file stored in S3
|
|
1148
1360
|
config/app.json:
|
|
1149
1361
|
src:
|
|
1150
|
-
|
|
1362
|
+
aws_s3: s3://my-bucket/configs/app.json
|
|
1151
1363
|
mode: '0600'
|
|
1152
1364
|
```
|
|
1153
1365
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmKpC,wBAAgB,WAAW,IAAI,OAAO,CAoJrC"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -35,26 +35,52 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.diffCommand = diffCommand;
|
|
37
37
|
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const config_1 = require("../config");
|
|
40
41
|
const sources_1 = require("../sources");
|
|
41
42
|
const replace_1 = require("../processors/replace");
|
|
42
43
|
const post_1 = require("../processors/post");
|
|
44
|
+
const insert_1 = require("../processors/insert");
|
|
43
45
|
const binary_1 = require("../binary");
|
|
44
46
|
const diff_1 = require("../diff");
|
|
45
47
|
const history_1 = require("../history");
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
const variables_remote_1 = require("../variables-remote");
|
|
49
|
+
const condition_1 = require("../condition");
|
|
50
|
+
async function runDiffLoop(config, workingDir, cache, configPath, history) {
|
|
51
|
+
let vars;
|
|
52
|
+
try {
|
|
53
|
+
vars = await (0, variables_remote_1.resolveVariableSpec)(config.variables ?? {}, workingDir, cache);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
57
|
+
return { allDiffs: [], hasError: true };
|
|
58
|
+
}
|
|
48
59
|
const allDiffs = [];
|
|
49
60
|
let hasError = false;
|
|
50
61
|
let selfContent;
|
|
51
|
-
|
|
62
|
+
let hasSelf = config_1.SELF_KEY in config.files;
|
|
63
|
+
if (hasSelf) {
|
|
64
|
+
const selfEntry = config.files[config_1.SELF_KEY];
|
|
65
|
+
try {
|
|
66
|
+
hasSelf = (0, condition_1.evaluateConditions)(selfEntry['if'], selfEntry.ifAny, () => configPath !== undefined
|
|
67
|
+
? configPath
|
|
68
|
+
: (0, diff_1.resolveTargetPath)(selfEntry, '', workingDir, vars), workingDir, vars);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
console.error(`Error processing ${config_1.SELF_KEY}: ${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
return { allDiffs: [], hasError: true };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
52
75
|
for (const [key, entry] of Object.entries(config.files)) {
|
|
53
76
|
const isSelf = key === config_1.SELF_KEY;
|
|
54
|
-
if (hasSelf
|
|
77
|
+
if (hasSelf !== isSelf)
|
|
55
78
|
continue;
|
|
56
79
|
try {
|
|
57
|
-
|
|
80
|
+
if (!isSelf &&
|
|
81
|
+
!(0, condition_1.evaluateConditions)(entry['if'], entry.ifAny, () => (0, diff_1.resolveTargetPath)(entry, '', workingDir, vars), workingDir, vars))
|
|
82
|
+
continue;
|
|
83
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars, cache, isSelf && configPath !== undefined ? () => configPath : undefined);
|
|
58
84
|
for (const rec of result.sourceRecords) {
|
|
59
85
|
if (!rec.matched) {
|
|
60
86
|
console.error(`⚠ SHA mismatch for ${rec.sourceLabel}\n` +
|
|
@@ -68,11 +94,23 @@ async function runDiffLoop(config, workingDir, cache) {
|
|
|
68
94
|
for (const [relPath, rawContent] of result.files) {
|
|
69
95
|
let content = rawContent;
|
|
70
96
|
if (!(0, binary_1.isBinary)(content)) {
|
|
71
|
-
|
|
97
|
+
const rawText = content.toString('utf8');
|
|
98
|
+
let text = rawText;
|
|
72
99
|
if (entry.replace?.length)
|
|
73
100
|
text = (0, replace_1.applyReplace)(text, entry.replace, vars);
|
|
74
101
|
if (entry.post)
|
|
75
102
|
text = (0, post_1.applyPost)(text, entry.post, vars);
|
|
103
|
+
if (entry.strategy === 'insert' && !isSelf) {
|
|
104
|
+
const targetPath = (0, diff_1.resolveTargetPath)(entry, relPath, workingDir, vars);
|
|
105
|
+
const lastInserted = history?.getInsertedFragment(targetPath) ?? null;
|
|
106
|
+
if (lastInserted !== null &&
|
|
107
|
+
rawText === lastInserted.raw &&
|
|
108
|
+
text === lastInserted.processed &&
|
|
109
|
+
fs.existsSync(targetPath)) {
|
|
110
|
+
continue; // source and processed output unchanged — would be a no-op write, skip diff
|
|
111
|
+
}
|
|
112
|
+
text = (0, insert_1.applyInsertMode)(entry, text, lastInserted?.processed ?? null, targetPath);
|
|
113
|
+
}
|
|
76
114
|
content = Buffer.from(text, 'utf8');
|
|
77
115
|
}
|
|
78
116
|
if (isSelf) {
|
|
@@ -84,7 +122,7 @@ async function runDiffLoop(config, workingDir, cache) {
|
|
|
84
122
|
}
|
|
85
123
|
}
|
|
86
124
|
catch (err) {
|
|
87
|
-
console.error(`Error processing ${JSON.stringify(entry.src)}: ${err.message}`);
|
|
125
|
+
console.error(`Error processing ${JSON.stringify(entry.src)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
88
126
|
hasError = true;
|
|
89
127
|
}
|
|
90
128
|
}
|
|
@@ -110,11 +148,12 @@ function diffCommand() {
|
|
|
110
148
|
config = await (0, config_1.loadConfig)(configPath, via);
|
|
111
149
|
}
|
|
112
150
|
catch (err) {
|
|
113
|
-
console.error(err.message);
|
|
151
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
114
152
|
process.exit(2);
|
|
115
153
|
}
|
|
116
154
|
const fetchCache = new Map();
|
|
117
|
-
const
|
|
155
|
+
const history = new history_1.HistoryManager((0, config_1.normalizeConfigKey)(configPath), workingDir);
|
|
156
|
+
const firstPass = await runDiffLoop(config, workingDir, fetchCache, configPath, history);
|
|
118
157
|
let { allDiffs, hasError } = firstPass;
|
|
119
158
|
if (hasError)
|
|
120
159
|
process.exit(2);
|
|
@@ -128,7 +167,7 @@ function diffCommand() {
|
|
|
128
167
|
currentConfig = (0, config_1.parseConfigContent)(currentSelfContent);
|
|
129
168
|
}
|
|
130
169
|
catch (err) {
|
|
131
|
-
console.error(`$self config is invalid: ${err.message}`);
|
|
170
|
+
console.error(`$self config is invalid: ${err instanceof Error ? err.message : String(err)}`);
|
|
132
171
|
process.exit(2);
|
|
133
172
|
}
|
|
134
173
|
if (!(config_1.SELF_KEY in currentConfig.files) ||
|
|
@@ -137,7 +176,7 @@ function diffCommand() {
|
|
|
137
176
|
break;
|
|
138
177
|
}
|
|
139
178
|
console.log('$self config resolved; re-evaluating with merged config...');
|
|
140
|
-
const next = await runDiffLoop(currentConfig, workingDir, fetchCache);
|
|
179
|
+
const next = await runDiffLoop(currentConfig, workingDir, fetchCache, configPath, history);
|
|
141
180
|
if (next.hasError) {
|
|
142
181
|
hasError = true;
|
|
143
182
|
break;
|
|
@@ -158,7 +197,7 @@ function diffCommand() {
|
|
|
158
197
|
filesWithoutSelf[k] = v;
|
|
159
198
|
}
|
|
160
199
|
if (Object.keys(filesWithoutSelf).length > 0) {
|
|
161
|
-
const second = await runDiffLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache);
|
|
200
|
+
const second = await runDiffLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache, configPath, history);
|
|
162
201
|
allDiffs = second.allDiffs;
|
|
163
202
|
hasError = second.hasError;
|
|
164
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,WAAW,IAAI,OAAO,CA2GrC"}
|
package/dist/commands/lock.js
CHANGED
|
@@ -37,8 +37,11 @@ exports.lockCommand = lockCommand;
|
|
|
37
37
|
const commander_1 = require("commander");
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const config_1 = require("../config");
|
|
40
|
+
const condition_1 = require("../condition");
|
|
40
41
|
const sources_1 = require("../sources");
|
|
42
|
+
const diff_1 = require("../diff");
|
|
41
43
|
const config_writeback_1 = require("../config-writeback");
|
|
44
|
+
const variables_remote_1 = require("../variables-remote");
|
|
42
45
|
function lockCommand() {
|
|
43
46
|
return new commander_1.Command('lock')
|
|
44
47
|
.description('Compute and pin SHA values for all remote sources in the config')
|
|
@@ -59,16 +62,27 @@ function lockCommand() {
|
|
|
59
62
|
config = await (0, config_1.loadConfig)(configPath);
|
|
60
63
|
}
|
|
61
64
|
catch (err) {
|
|
62
|
-
console.error(err.message);
|
|
65
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
66
|
+
process.exit(2);
|
|
67
|
+
}
|
|
68
|
+
let vars;
|
|
69
|
+
try {
|
|
70
|
+
vars = await (0, variables_remote_1.resolveVariableSpec)(config.variables ?? {}, workingDir);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
63
74
|
process.exit(2);
|
|
64
75
|
}
|
|
65
|
-
const vars = config.variables ?? {};
|
|
66
76
|
const toPin = new Map(); // label → sha
|
|
67
77
|
let hasError = false;
|
|
68
78
|
let remoteSourceCount = 0;
|
|
69
|
-
for (const entry of Object.
|
|
79
|
+
for (const [key, entry] of Object.entries(config.files)) {
|
|
70
80
|
try {
|
|
71
|
-
|
|
81
|
+
if (!(0, condition_1.evaluateConditions)(entry['if'], entry.ifAny, () => key === config_1.SELF_KEY
|
|
82
|
+
? configPath
|
|
83
|
+
: (0, diff_1.resolveTargetPath)(entry, '', workingDir, vars), workingDir, vars))
|
|
84
|
+
continue;
|
|
85
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars, undefined, key === config_1.SELF_KEY ? () => configPath : undefined);
|
|
72
86
|
remoteSourceCount += result.sourceRecords.length;
|
|
73
87
|
for (const rec of result.sourceRecords) {
|
|
74
88
|
if (!opts.force && rec.expectedSha !== undefined)
|
|
@@ -77,7 +91,7 @@ function lockCommand() {
|
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
catch (err) {
|
|
80
|
-
console.error(`Error processing ${JSON.stringify(entry.src)}: ${err.message}`);
|
|
94
|
+
console.error(`Error processing ${JSON.stringify(entry.src)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
81
95
|
hasError = true;
|
|
82
96
|
}
|
|
83
97
|
}
|