flecto 4.0.0 → 4.1.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/CHANGELOG.md CHANGED
@@ -7,6 +7,76 @@ The format is based on [Keep a Changelog], and this project adheres to
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.1.0] - 2026-09-29
11
+
12
+ ### Added
13
+
14
+ - **A root [`action.yml`](action.yml), so the Action can be listed on the GitHub
15
+ Marketplace.** GitHub only lists an action whose metadata file sits at a public
16
+ repository's root; Flecto's Actions live in `.github/actions/`, which is why
17
+ they were never listable. The listed action is `flecto-pr-risk` — the pull
18
+ request risk comment — with branding and the wedge description.
19
+
20
+ `.github/actions/flecto-pr-risk/action.yml` **stays exactly where it is**, so
21
+ nothing referencing that path changes. The two files' `runs:` blocks are
22
+ byte-identical and a test enforces it, so a fix to one is a CI failure until it
23
+ lands in both.
24
+
25
+ Docs continue to reference
26
+ `myselfsiddharth/Flecto/.github/actions/flecto-pr-risk@v4.0.0` until a release
27
+ carrying the root file exists. The shorter `myselfsiddharth/Flecto@vX.Y.Z` form
28
+ becomes correct at that point; see [RELEASE.md](RELEASE.md) step 5.
29
+
30
+ - **`flecto-pr-risk` takes a Terraform plan directly.** A new `terraform-plan`
31
+ input points at `terraform show -json` output and switches the Action to
32
+ `flecto plan`, so reviewing a plan on every pull request is two steps:
33
+
34
+ ```yaml
35
+ - run: terraform plan -out=tf.plan && terraform show -json tf.plan > plan.json
36
+ - uses: myselfsiddharth/Flecto/.github/actions/flecto-pr-risk@v4.0.0
37
+ with:
38
+ terraform-plan: plan.json
39
+ fail-on: error
40
+ ```
41
+
42
+ Because a plan JSON carries its own before and after, **no baseline is resolved
43
+ and no git history is needed** in this mode — the `fetch-depth: 0` that config
44
+ mode wants does not apply, and the Action runs on events with no pull request
45
+ base commit. A missing plan file fails the step rather than letting Flecto
46
+ report nothing. `targets` is ignored; add a second step without
47
+ `terraform-plan` to also check config files.
48
+
49
+ Config mode is unchanged, including its fail-closed behaviour when no baseline
50
+ can be resolved. A complete workflow is in
51
+ [`examples/github-action/flecto-terraform-plan.yml`](examples/github-action/flecto-terraform-plan.yml).
52
+
53
+ - [docs/stability.md](docs/stability.md): what the public contract covers (the
54
+ `schema_version: "2.0"` envelope, exit codes, `.flectorc`, the CLI surface),
55
+ what it deliberately does not, and the deprecation sequence — one minor release
56
+ carrying a warning before any removal, with security fixes the stated
57
+ exception.
58
+
59
+ ### Fixed
60
+
61
+ - **The bundled GitHub Actions installed the pre-4.0 CLI.** `flecto-ci`
62
+ hardcoded `npx --yes flecto@3` and `flecto-pr-risk` defaulted
63
+ `flecto-version: "3"`, so both shipped Actions ran the 3.x line after 4.0.0
64
+ released. Two consequences: `flecto-ci`'s advertised `snapshot-file:` input
65
+ passed a flag that does not exist before 4.0, and its default
66
+ `snapshot-ref: HEAD~1` against a 3.x CLI is the baseline-shadowing bypass 4.0
67
+ closed — a pull request commits a file named `HEAD~1`, it is read instead of
68
+ the revision, the diff comes back empty and no `--fail-on` value catches it.
69
+
70
+ Both now default to `4`. `flecto-ci` gains a `flecto-version` input so the CLI
71
+ can be pinned without forking, matching `flecto-pr-risk`. A test asserts the
72
+ floor across both Actions, including hardcoded installs that would bypass the
73
+ input.
74
+
75
+ **If you copied an earlier README example you are affected**: the examples
76
+ referenced the Actions `@main`, which resolved to a 3.x install. Re-pin to
77
+ `@v4.0.0` — every example in the README and [docs/ci.md](docs/ci.md) now does,
78
+ with SHA pinning documented for security-sensitive users.
79
+
10
80
  ## [4.0.0] - 2026-09-23
11
81
 
12
82
  **A security release.** Every breaking change below exists because a pull
@@ -1222,7 +1292,8 @@ fixed — those runs were never actually gated — but the failure is new.
1222
1292
  - Misconfigured policy packs/plugins cause `watch` to exit non-zero instead of
1223
1293
  continuing with no policies.
1224
1294
 
1225
- [Unreleased]: https://github.com/myselfsiddharth/Flecto/compare/v3.1.0...HEAD
1295
+ [Unreleased]: https://github.com/myselfsiddharth/Flecto/compare/v4.1.0...HEAD
1296
+ [4.1.0]: https://github.com/myselfsiddharth/Flecto/compare/v4.0.0...v4.1.0
1226
1297
  [4.0.0]: https://github.com/myselfsiddharth/Flecto/compare/v3.1.0...v4.0.0
1227
1298
  [3.1.0]: https://github.com/myselfsiddharth/Flecto/compare/v3.0.2...v3.1.0
1228
1299
  [3.0.2]: https://github.com/myselfsiddharth/Flecto/compare/v3.0.1...v3.0.2
package/README.md CHANGED
@@ -63,7 +63,7 @@ flecto doctor
63
63
  ```
64
64
 
65
65
  Prefer not to install globally? Every example below works with
66
- `npx --yes flecto@3` instead of `flecto`.
66
+ `npx --yes flecto@4` instead of `flecto`.
67
67
 
68
68
  ---
69
69
 
@@ -173,7 +173,7 @@ steps:
173
173
  - uses: actions/checkout@v7
174
174
  with:
175
175
  fetch-depth: 2
176
- - uses: myselfsiddharth/Flecto/.github/actions/flecto-ci@main
176
+ - uses: myselfsiddharth/Flecto/.github/actions/flecto-ci@v4.0.0
177
177
  with:
178
178
  targets: config/**/*.{yaml,yml,json,toml,ini}
179
179
  snapshot-ref: HEAD~1
@@ -197,7 +197,7 @@ steps:
197
197
  - uses: actions/checkout@v7
198
198
  with:
199
199
  fetch-depth: 0
200
- - uses: myselfsiddharth/Flecto/.github/actions/flecto-pr-risk@main
200
+ - uses: myselfsiddharth/Flecto/.github/actions/flecto-pr-risk@v4.0.0
201
201
  ```
202
202
 
203
203
  GitLab and Bitbucket work the same way — Flecto detects the host from CI
@@ -537,6 +537,7 @@ Explicit CLI flags win over profiles, which win over `defaults`.
537
537
  | **[Plugins](docs/plugins.md)** · **[Cookbook](docs/plugin-cookbook.md)** | Rules that need real code |
538
538
  | **[Live drift](docs/drift.md)** | `flecto-drift`: comparing a declared config against what is actually running |
539
539
  | **[Troubleshooting](docs/troubleshooting.md)** | When something doesn't behave |
540
+ | **[Stability](docs/stability.md)** | What you can build against, what you cannot, and the deprecation sequence |
540
541
  | **[Migrating to 4.0](docs/migrating-to-4.md)** | The five breaking changes, and how to tell whether they affect you |
541
542
  | **[Changelog](CHANGELOG.md)** | Release history and migration notes |
542
543
 
@@ -556,6 +557,40 @@ leaves the process unless you configure a webhook or command.
556
557
 
557
558
  ---
558
559
 
560
+ ## Stability
561
+
562
+ Flecto runs inside your merge path, so here is what you can build against.
563
+ These follow [semver](https://semver.org/) and are covered by the deprecation
564
+ sequence below:
565
+
566
+ - **The JSON envelope** (`schema_version: "2.0"`) — existing fields keep their
567
+ name, type, and meaning; new fields are additive. Schemas in [`schemas/`](schemas).
568
+ - **Exit codes** — `0` clean, `1` a fail trigger matched or the run could not
569
+ complete. That is the whole set, and Flecto fails closed.
570
+ - **`.flectorc`** — documented keys keep their name, meaning, and default.
571
+ - **Command and flag names**, and what a flag accepts.
572
+
573
+ **No breaking change to those ships without a minor release that warns first**,
574
+ names the replacement, and says which version removes the old form. The one
575
+ exception is a security fix: if a surface can make `flecto ci` report a clean run
576
+ on a change that is not clean, it gets closed in the next release with an
577
+ advisory. 4.0 was exactly that — five breaking changes, every one a bypass.
578
+
579
+ Deliberately **not** stable: terminal and `pr-comment` output (presentation —
580
+ parse `--format json` instead), message wording, anything under `src/`, and
581
+ snapshot file internals. Built-in packs gain rules in minor releases; rule IDs
582
+ never change meaning.
583
+
584
+ Flecto reached 4.0 in four months, which is fast. That churn was front-loaded
585
+ into a period with no real users, and 4.0 was forced by a
586
+ [security review](docs/security-review.md) finding real bypasses. The intent now
587
+ is minor releases only — anything needing a 5.0 waits in
588
+ [`docs/v5-proposals.md`](docs/v5-proposals.md).
589
+
590
+ → **[Full stability policy](docs/stability.md)**
591
+
592
+ ---
593
+
559
594
  ## Project
560
595
 
561
596
  - **Questions and ideas** — [Discussions](https://github.com/myselfsiddharth/Flecto/discussions)
package/package.json CHANGED
@@ -4,17 +4,24 @@
4
4
  "access": "public",
5
5
  "provenance": true
6
6
  },
7
- "version": "4.0.0",
8
- "description": "Flecto \u2014 semantic config watcher that reports meaningful changes in plain English",
7
+ "version": "4.1.0",
8
+ "description": "Reads your Terraform plan and Kubernetes changes and posts a plain-English risk summary on every pull request, blocking the dangerous ones",
9
9
  "license": "MIT",
10
10
  "keywords": [
11
- "flecto",
12
- "cli",
13
- "watcher",
14
- "config",
11
+ "terraform",
12
+ "terraform-plan",
13
+ "kubernetes",
14
+ "helm",
15
+ "pull-request",
16
+ "code-review",
17
+ "policy-as-code",
18
+ "github-actions",
15
19
  "semantic-diff",
20
+ "config",
16
21
  "devops",
17
- "ci"
22
+ "ci",
23
+ "cli",
24
+ "flecto"
18
25
  ],
19
26
  "homepage": "https://github.com/myselfsiddharth/Flecto#readme",
20
27
  "bugs": {
@@ -56,7 +63,7 @@
56
63
  "chalk": "^5.3.0",
57
64
  "chokidar": "^5.0.0",
58
65
  "commander": "^12.1.0",
59
- "dotenv": "^17.4.2",
66
+ "dotenv": "^18.0.1",
60
67
  "fast-glob": "^3.3.3",
61
68
  "js-yaml": "^4.3.0",
62
69
  "re2js": "^2.8.6"
package/src/positions.js CHANGED
@@ -655,9 +655,15 @@ function readJsonValue(state) {
655
655
  // dotenv
656
656
 
657
657
  /**
658
- * dotenv's own line pattern (dotenv/lib/main.js), with match indices. Reading
659
- * keys with the parser's exact pattern is what makes the positions agree with
660
- * it; verification catches a future dotenv that changes it.
658
+ * dotenv's own line pattern, with match indices. Reading keys with the parser's
659
+ * exact pattern is what makes the positions agree with it; verification catches
660
+ * a future dotenv that changes it.
661
+ *
662
+ * Upstream source moved in dotenv 18: it was `dotenv/lib/main.js`, and is now
663
+ * bundled and minified into `dotenv/dist/index.cjs`. The pattern itself is
664
+ * unchanged between 17.4.2 and 18.0.1 -- byte-identical apart from the `d` flag
665
+ * added here for match indices. To re-check it after a bump, grep the bundle for
666
+ * `export\s+`, which is distinctive enough to find the regex in minified code.
661
667
  */
662
668
  const DOTENV_LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/dgm;
663
669