@intentius/terragucci 0.2.0 → 0.3.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/dist/types.d.ts CHANGED
@@ -1,10 +1,15 @@
1
- export declare const BINARIES: readonly ["terraform", "tofu", "choudoufu", "cdktn"];
1
+ export declare const BINARIES: readonly ["terraform", "tofu", "choudoufu"];
2
2
  export declare const FORGES: readonly ["github", "gitlab", "forgejo"];
3
3
  export declare const GATES: readonly ["always", "on-destroy", "never"];
4
- export declare const RUNTIMES: readonly ["forge", "fountain"];
4
+ /** Every stage runs on the forge's CI. */
5
+ export declare const RUNTIMES: readonly ["forge"];
5
6
  export declare const DEPENDENTS: readonly ["follow", "plan"];
6
7
  export declare const POLICY_ENGINES: readonly ["conftest", "opa"];
7
8
  export declare const POLICY_INPUTS: readonly ["plan", "hcp"];
9
+ /** When a change applies: after it merges (default), or from its open pull request before it merges. */
10
+ export declare const APPLY_WHEN: readonly ["merge", "pull-request"];
11
+ /** With `apply.when: pull-request`, who merges once every wave applied: a person (default), or terragucci. */
12
+ export declare const APPLY_MERGE: readonly ["manual", "auto"];
8
13
  export type Binary = (typeof BINARIES)[number];
9
14
  export type ForgeName = (typeof FORGES)[number];
10
15
  export type Gate = (typeof GATES)[number];
@@ -12,6 +17,23 @@ export type Runtime = (typeof RUNTIMES)[number];
12
17
  export type Dependents = (typeof DEPENDENTS)[number];
13
18
  export type PolicyEngine = (typeof POLICY_ENGINES)[number];
14
19
  export type PolicyInput = (typeof POLICY_INPUTS)[number];
20
+ export type ApplyWhen = (typeof APPLY_WHEN)[number];
21
+ export type ApplyMerge = (typeof APPLY_MERGE)[number];
22
+ /**
23
+ * `apply:`: when a change applies. `when: merge` (the default) applies the
24
+ * default branch after a merge. `when: pull-request` applies an open pull
25
+ * request's head on `/terragucci apply`, under the same waves and gates, and
26
+ * the push after the merge plans and reports drift without applying.
27
+ * `merge: auto` merges the pull request once every wave applied, in a job of
28
+ * its own, with the token in the secret `merge_token_env` names when it is
29
+ * set (required on Forgejo, whose job token cannot push to the default
30
+ * branch). Plain roots on GitHub and Forgejo only (NO_GITLAB_PR_APPLY).
31
+ */
32
+ export interface ApplySettings {
33
+ when?: ApplyWhen;
34
+ merge?: ApplyMerge;
35
+ merge_token_env?: string;
36
+ }
15
37
  /**
16
38
  * Policy as code, off unless set. `tf-plan` runs the engine over each planned
17
39
  * root's plan JSON and fails the root on a denial. No response, agent or
@@ -41,14 +63,16 @@ export interface OidcSettings {
41
63
  gcp?: {
42
64
  workload_identity_provider: string;
43
65
  plan_service_account: string;
44
- apply_service_account: string;
66
+ apply_service_account: string; /** Default `https://sts.googleapis.com/v1/token`; a regional endpoint such as `https://sts.europe-west3.rep.googleapis.com/v1/token`. */
67
+ token_url?: string;
45
68
  };
46
69
  /** An Entra app registration or managed identity per stage, with a federated credential for the forge. */
47
70
  azure?: {
48
71
  tenant_id: string;
49
72
  subscription_id: string;
50
73
  plan_client_id: string;
51
- apply_client_id: string;
74
+ apply_client_id: string; /** The token's audience. Default `api://AzureADTokenExchange`; `api://AzureADTokenExchangeUSGov` for Azure US Government, `api://AzureADTokenExchangeChina` for Azure China. */
75
+ audience?: string;
52
76
  };
53
77
  }
54
78
  /** A plan role and an apply role, for the units under one path. */
@@ -77,27 +101,24 @@ export interface TerragruntSettings {
77
101
  }
78
102
  /**
79
103
  * Pipeline events and the responses each takes. The first mode is the
80
- * default and needs no model; `agent` adds an agent's comment or proposal on
81
- * top of the deterministic response, and is never the default. `drift:
82
- * attribute` also names who changed each drifted attribute (a known-writes
104
+ * default and needs no model. `drift: attribute` also names who changed each drifted attribute (a known-writes
83
105
  * table, then the audit log, then a typed decision when `decide:` is set).
84
106
  */
85
107
  export declare const RESPONSES: {
86
- readonly plan: readonly ["summary", "agent"];
108
+ readonly plan: readonly ["summary"];
87
109
  readonly "wave-refused": readonly ["diff", "off"];
88
- readonly "apply-failed": readonly ["triage", "agent", "off"];
89
- readonly drift: readonly ["pull-request", "attribute", "agent", "off"];
110
+ readonly "apply-failed": readonly ["triage", "off"];
111
+ readonly drift: readonly ["pull-request", "attribute", "off"];
90
112
  readonly tips: readonly ["pull-request", "off"];
91
113
  readonly fmt: readonly ["commit", "off"];
92
- readonly publish: readonly ["notes", "agent", "off"];
114
+ readonly publish: readonly ["notes", "off"];
93
115
  readonly rollout: readonly ["next-wave", "off"];
94
- readonly question: readonly ["off", "agent"];
95
116
  readonly "version-bump": readonly ["off", "suggest"];
96
117
  /** terragucci#30: a typed decision flags a pull request whose description leaves out what its plan destroys or replaces. Needs `decide:`. */
97
118
  readonly description: readonly ["off", "check"];
98
119
  };
99
120
  export type RespondEvent = keyof typeof RESPONSES;
100
- export declare const AGENT_VIA: readonly ["forge", "fountain"];
121
+ export declare const AGENT_VIA: readonly ["forge"];
101
122
  /** The services `decide:` can name; each speaks the Jev request and response shape. */
102
123
  export declare const DECIDE_BACKENDS: readonly ["laya", "von", "decider", "jev"];
103
124
  export type DecideBackend = (typeof DECIDE_BACKENDS)[number];
@@ -144,8 +165,8 @@ export declare const DASHBOARD_DURATION_KEYS: readonly ["drift_age", "wave_wait"
144
165
  * `agent.comment`: the `/terragucci agent <ask>` pull request comment, off
145
166
  * unless set. The comment starts a job that runs a coding agent on the pull
146
167
  * request's head branch and pushes what it changes with `agent.token_env`'s
147
- * token. The job gets no cloud credentials: no `oidc` role and not
148
- * `agent.role`. `true` takes every default.
168
+ * token. The job gets no cloud credentials: no `oidc` role. `true` takes every
169
+ * default.
149
170
  */
150
171
  export interface AgentCommentSettings {
151
172
  /** The agent's command line, run in the checkout with the prompt on stdin. Default: Claude Code in print mode with file tools only (AGENT_COMMAND in agent-comment.ts). */
@@ -172,6 +193,8 @@ export interface ProjectSettings {
172
193
  url?: string;
173
194
  /** When a wave waits for an approval. */
174
195
  gate?: Gate;
196
+ /** When a change applies; see ApplySettings. */
197
+ apply?: ApplySettings;
175
198
  waves?: {
176
199
  canary?: string[];
177
200
  };
@@ -182,12 +205,15 @@ export interface ProjectSettings {
182
205
  * A bucket for plan reports. `url` is the address that serves the bucket's
183
206
  * objects to a browser (a static site, a CDN, the store's public endpoint);
184
207
  * with it, the note, the index and the dashboards link the bucket's copy.
208
+ * `role` is an AWS role the job assumes with its OIDC token to write the
209
+ * reports, apart from the job's own role.
185
210
  */
186
211
  reports?: {
187
212
  bucket: string;
188
213
  endpoint?: string;
189
214
  prefix?: string;
190
215
  url?: string;
216
+ role?: string;
191
217
  };
192
218
  /** The environment variable holding the forge token. */
193
219
  token_env?: string;
@@ -213,8 +239,6 @@ export interface ProjectSettings {
213
239
  * write one. The two must differ, on every cloud set.
214
240
  */
215
241
  oidc?: OidcSettings;
216
- /** Whether removing the project from a control repo removes its generated files. */
217
- owned?: boolean;
218
242
  /** How many roots of one dependency layer plan at once. Default: from the state backend. */
219
243
  parallelism?: number;
220
244
  /** Terragrunt settings, for a repo terragucci finds Terragrunt in. */
@@ -224,13 +248,12 @@ export interface ProjectSettings {
224
248
  /** The response to each pipeline event; see RESPONSES. */
225
249
  respond?: Partial<Record<RespondEvent, string>>;
226
250
  /**
227
- * Where an agent response runs, for any event set to `agent`. Its token can
228
- * comment and open pull requests; its role, when named, is read-only.
251
+ * The agent integration behind `agent.comment`. Its token can comment and
252
+ * push to a pull request's branch; its role, when named, is read-only.
229
253
  */
230
254
  agent?: {
231
255
  via: (typeof AGENT_VIA)[number];
232
256
  token_env: string;
233
- role?: string;
234
257
  comment?: boolean | AgentCommentSettings;
235
258
  };
236
259
  /** The typed-decision service; see DecideSettings. Off when absent. A project's `decide` replaces the defaults' whole. */
@@ -253,7 +276,6 @@ export interface ResolvedSettings extends ProjectSettings {
253
276
  drift: string | false;
254
277
  runtime: Runtime;
255
278
  tips: boolean;
256
- owned: boolean;
257
279
  env: Record<string, string>;
258
280
  }
259
281
  export declare const BUILT_IN: ResolvedSettings;
@@ -267,6 +289,14 @@ export declare function checkMode(mode: string): "dry-run" | "apply";
267
289
  export declare const CONFIG_NAMES: string[];
268
290
  /** The config file in `dir`, or undefined. Two of them is an error. */
269
291
  export declare function findConfig(dir: string): string | undefined;
292
+ /**
293
+ * Why GitLab has no apply before merge. GitLab builds a merge request's
294
+ * pipeline from the merge request's own `.gitlab-ci.yml`, so a job that
295
+ * applies it would run the checks before the apply (approval, locks, the
296
+ * pipeline file) inside a pipeline the merge request controls, and the apply
297
+ * role would have to trust every branch of the project.
298
+ */
299
+ export declare const NO_GITLAB_PR_APPLY = "pull-request is not supported on GitLab, where a merge request's pipeline is defined by the merge request itself, so nothing it runs can be trusted with the apply role; leave apply.when unset, and the change applies after it merges";
270
300
  /** Check a parsed config and return it typed, or throw with every problem listed. */
271
301
  export declare function validateConfig(raw: unknown, where: string): TerragucciConfig;
272
302
  export type ConfigMode = "fold" | "run" | "check";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/terragucci",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "The whole Terraform lifecycle, handled: one config file, generated pipelines for GitHub, GitLab and Forgejo.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -45,11 +45,11 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@cdktn/hcl2json": "0.24.0",
48
- "@intentius/chant": "0.106.4",
49
- "@intentius/chant-lexicon-forgejo": "0.106.4",
50
- "@intentius/chant-lexicon-github": "0.106.4",
51
- "@intentius/chant-lexicon-gitlab": "0.106.4",
52
- "@intentius/chant-lexicon-terraform": "0.106.4",
48
+ "@intentius/chant": "0.107.1",
49
+ "@intentius/chant-lexicon-forgejo": "0.107.1",
50
+ "@intentius/chant-lexicon-github": "0.107.1",
51
+ "@intentius/chant-lexicon-gitlab": "0.107.1",
52
+ "@intentius/chant-lexicon-terraform": "0.107.1",
53
53
  "@intentius/tsad-reference": "2.1.0"
54
54
  }
55
55
  }