@intentius/terragucci 0.4.3 → 0.4.4

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,3 +1,4 @@
1
+ import { type GenerateSettings } from "./generate-config";
1
2
  export declare const BINARIES: readonly ["terraform", "tofu", "choudoufu"];
2
3
  export declare const FORGES: readonly ["github", "gitlab", "forgejo"];
3
4
  export declare const GATES: readonly ["always", "on-destroy", "never"];
@@ -57,6 +58,30 @@ export type ApplyWhen = (typeof APPLY_WHEN)[number];
57
58
  export type Locks = (typeof LOCKS)[number];
58
59
  export type ApplyMerge = (typeof APPLY_MERGE)[number];
59
60
  export type ApplyRequire = (typeof APPLY_REQUIRES)[number];
61
+ /** The stages a step runs before or after (`steps:`). `drift` is the drift job's refresh-only plan. */
62
+ export declare const STEP_STAGES: readonly ["init", "plan", "apply", "drift"];
63
+ export type StepStage = (typeof STEP_STAGES)[number];
64
+ /** What a step's non-zero exit does: fail the root (the default), or hold its wave for an approval. */
65
+ export declare const STEP_FAILURES: readonly ["fail", "approve"];
66
+ export type StepFailure = (typeof STEP_FAILURES)[number];
67
+ export declare const STEP_KEYS: readonly ["name", "run", "before", "after", "roots", "on_failure"];
68
+ /**
69
+ * One entry of `steps:`. `run` is a shell command, run in the root's
70
+ * directory. Exactly one of `before` and `after` names the stage. `roots`
71
+ * are globs of the roots it runs for (every root when unset).
72
+ * `on_failure: approve` turns a non-zero exit into a hold: the root's wave
73
+ * waits for an approval of its set digest, whatever `gate` says. Only a step
74
+ * that runs before the gate is decided can hold it: one before or after
75
+ * init or plan.
76
+ */
77
+ export interface StepSettings {
78
+ run: string;
79
+ name?: string;
80
+ before?: StepStage;
81
+ after?: StepStage;
82
+ roots?: string[];
83
+ on_failure?: StepFailure;
84
+ }
60
85
  /**
61
86
  * `apply:`: when a change applies. `when: merge` (the default) applies the
62
87
  * default branch after a merge. `when: pull-request` applies an open pull
@@ -243,14 +268,37 @@ export interface AgentCommentSettings {
243
268
  timeout?: number;
244
269
  }
245
270
  export declare const AGENT_COMMENT_KEYS: readonly ["command", "key_secret", "max_turns", "timeout"];
271
+ /**
272
+ * `review`: a model reviews each pull request's intent against its plan
273
+ * (review-agent.ts), off unless `agent` is true. It posts a note and never
274
+ * approves; a `tf-apply` wave's policy reads its risk as `input.review`.
275
+ */
276
+ export interface ReviewSettings {
277
+ /** Turns the review on. */
278
+ agent?: boolean;
279
+ /** The command line, run with the prompt on stdin; it prints the review. Default: Claude Code in print mode with no tools (REVIEW_COMMAND in review-agent.ts). */
280
+ command?: string;
281
+ /** The secret holding the model's API key, mapped into the review command's step alone. Default `ANTHROPIC_API_KEY`. */
282
+ key_secret?: string;
283
+ /** The instructions file, read from the default branch. Default `.terragucci/review.md`. */
284
+ instructions?: string;
285
+ /** Minutes before the review job is stopped. Default 10. */
286
+ timeout?: number;
287
+ }
288
+ export declare const REVIEW_KEYS: readonly ["agent", "command", "key_secret", "instructions", "timeout"];
246
289
  /** The settings one project (or one repo) can carry. Every key is optional. */
247
290
  export interface ProjectSettings {
248
291
  /** Globs of root directories. Detected when absent. */
249
292
  roots?: string[];
250
293
  /** The binary the pipeline runs. Detected when absent. */
251
294
  binary?: Binary;
252
- /** The binary's version. Read from the roots' `required_version` when it pins one. */
253
- version?: string;
295
+ /**
296
+ * The binary's version. Read from the roots' `required_version` when it pins one. As a map of root
297
+ * glob to release, the version each root it matches runs (tofu and terraform, plain roots only).
298
+ */
299
+ version?: string | Record<string, string>;
300
+ /** Each plain root's backend, provider and version files, which `terragucci generate` writes; see generate.ts. */
301
+ generate?: GenerateSettings;
254
302
  /** The forge, for a host terragucci cannot name. */
255
303
  forge?: ForgeName;
256
304
  /** Where the project lives, for a forge not on https or the default port. */
@@ -263,8 +311,10 @@ export interface ProjectSettings {
263
311
  apply?: ApplySettings;
264
312
  /** When a pull request takes its root locks; see LOCKS. */
265
313
  locks?: Locks;
314
+ /** `canary`: globs for the wave that applies first. `jobs`: the most jobs one wave's roots spread across (plain roots, GitHub and Forgejo). */
266
315
  waves?: {
267
316
  canary?: string[];
317
+ jobs?: number;
268
318
  };
269
319
  /** A cron schedule for tf-drift, or false. */
270
320
  drift?: string | false;
@@ -274,17 +324,34 @@ export interface ProjectSettings {
274
324
  * plan, apply and drift jobs, on their own checkout.
275
325
  */
276
326
  synth?: string;
327
+ /**
328
+ * Commands run before and after a root's init, plan, apply and drift, in
329
+ * the stage's own job, on its checkout, with its environment less the forge
330
+ * tokens. Read from terragucci.yml at base, never from the change under
331
+ * review (./steps.ts).
332
+ */
333
+ steps?: StepSettings[];
334
+ /**
335
+ * The image every job runs in, in place of terragucci's: one built FROM
336
+ * the terragucci image for the binary, so the job still has terragucci and
337
+ * the binary, plus what the steps need.
338
+ */
339
+ image?: string;
277
340
  /**
278
341
  * Notifications: the names of the secrets holding a Slack or Teams
279
342
  * incoming webhook, and a generic webhook's address with the key that
280
343
  * signs its body. An apply job whose wave waits, is refused or fails posts
281
- * to each (notify.ts).
344
+ * to each (notify.ts), and the drift job posts drift to Slack and Teams.
345
+ * `relay` names the customer's relay (relay.ts): a waiting wave's Slack
346
+ * message gets Approve and Decline buttons, its Teams card the reply
347
+ * `@<relay> approve wave-<k> <digest>`.
282
348
  */
283
349
  notify?: {
284
350
  slack?: string;
285
351
  teams?: string;
286
352
  webhook?: string;
287
353
  webhook_key?: string;
354
+ relay?: string;
288
355
  };
289
356
  /**
290
357
  * Cost estimates per root in the plan note: Infracost on the customer's
@@ -353,6 +420,12 @@ export interface ProjectSettings {
353
420
  terragrunt?: TerragruntSettings;
354
421
  /** Opt-in policy checks over each plan; see PolicySettings. */
355
422
  policy?: PolicySettings;
423
+ /**
424
+ * `atlantis plan` and `atlantis apply` comments read as `/terragucci plan`
425
+ * and `/terragucci apply`. Off by default. The alias changes the words
426
+ * only: the same checks decide (comment.ts).
427
+ */
428
+ atlantis_comments?: boolean;
356
429
  /** The response to each pipeline event; see RESPONSES. */
357
430
  respond?: Partial<Record<RespondEvent, string>>;
358
431
  /**
@@ -364,6 +437,8 @@ export interface ProjectSettings {
364
437
  token_env: string;
365
438
  comment?: boolean | AgentCommentSettings;
366
439
  };
440
+ /** The AI review of a pull request's intent against its plan; see ReviewSettings. Off when absent. */
441
+ review?: ReviewSettings;
367
442
  /** The typed-decision service; see DecideSettings. Off when absent. A project's `decide` replaces the defaults' whole. */
368
443
  decide?: DecideSettings;
369
444
  /** The AWS region whose CloudTrail drift attribution reads. Default: the region the aws CLI already uses. */
@@ -382,6 +457,7 @@ export declare function responseTo(settings: ProjectSettings, event: RespondEven
382
457
  export type CostSettings = true | {
383
458
  key_secret?: string;
384
459
  command?: string;
460
+ approve_above?: number;
385
461
  };
386
462
  /** The secret Infracost's key is read from when `cost.key_secret` is unset; the job gets it as this variable too. */
387
463
  export declare const COST_KEY_SECRET = "INFRACOST_API_KEY";
@@ -405,7 +481,7 @@ export declare const BUILT_IN: ResolvedSettings;
405
481
  * own clone URL and `rollouts` belongs to a single repo, so `defaults`
406
482
  * refuses both.
407
483
  */
408
- export declare const PROJECT_FILE_KEYS: readonly ["policy", "reports", "approval", "gate", "roots", "waves", "parallelism", "synth", "drift", "cost", "tips", "runtime", "telemetry", "respond", "decide", "audit_region", "modules", "terragrunt", "token_env"];
484
+ export declare const PROJECT_FILE_KEYS: readonly ["policy", "reports", "approval", "gate", "roots", "waves", "parallelism", "synth", "steps", "drift", "cost", "tips", "runtime", "telemetry", "respond", "review", "decide", "audit_region", "modules", "terragrunt", "token_env", "generate"];
409
485
  export declare class ConfigError extends Error {
410
486
  /** Every problem found, when the error is a validation failure. */
411
487
  readonly problems?: string[];
@@ -438,7 +514,22 @@ export interface ModulesSettings {
438
514
  trusted?: TrustedModuleSource[];
439
515
  }
440
516
  /** Why a control repo's projects take no `rollouts` job: each project's pipeline sees only its own roots. */
517
+ /** Why `waves.jobs` is refused on GitLab: a split wave's shares hold one apply lock between them on GitHub and Forgejo, and GitLab's apply jobs take a resource group one job at a time. */
518
+ export declare const WAVE_JOBS_NOT_GITLAB = "a wave splits across jobs on GitHub and Forgejo; GitLab runs one apply job at a time in its resource group, so leave waves.jobs unset there";
519
+ export declare const WAVE_JOBS_NOT_PR_APPLY = "apply.when: pull-request applies every wave in the one job a comment starts, so a wave has no jobs to spread across; leave waves.jobs unset";
520
+ export declare const WAVE_JOBS_NOT_TERRAGRUNT = "a Terragrunt wave applies its units with one run --all in one job; waves.jobs splits a wave of plain roots, so leave it unset";
441
521
  export declare const ROLLOUTS_SINGLE_REPO = "a control repo's rollout plans its waves across every project, and a project's pipeline sees only its own roots; leave rollouts unset and run terragucci respond rollout --mode apply on a schedule in the control repo";
522
+ /**
523
+ * What `synth` rules out, each because it would edit the roots the synth
524
+ * command writes. Those files are output, not in git: a change to them is
525
+ * lost at the next synth, and their source is the app's code (a CDK Terrain
526
+ * app's TypeScript), which terragucci does not edit.
527
+ */
528
+ export declare const SYNTH_DRIFT_PR_SHORT = "synth writes the roots, so a live value belongs in the app that writes them, which terragucci does not edit";
529
+ export declare const SYNTH_DRIFT_PR = "the drift pull request writes each live value into a root's own files, and with synth the command writes those files and git does not hold them, so the value belongs in the app that writes them, which terragucci does not edit; set respond.drift to attribute, which names who changed each value in the drift issue, or to off";
530
+ export declare const SYNTH_ROLLOUTS = "a rollout moves a pin in each root's files or its lock file, and with synth the command writes those files and git does not hold them, so the pin is in the app that writes them; move it there";
531
+ /** The problems `synth` finds in one project's settings: a drift schedule whose response is the pull request, and a rollouts schedule. */
532
+ export declare function synthProblems(s: ProjectSettings, where: string): string[];
442
533
  /** Why `comments` is GitLab's alone: the other forges start a job for each comment. */
443
534
  export declare const COMMENTS_GITLAB_ONLY = "comments is for GitLab, which starts no pipeline for a merge request note; GitHub and Forgejo start the comment jobs from the comment itself, so leave comments unset";
444
535
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/terragucci",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
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",