@intentius/terragucci 0.4.43 → 0.4.44

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.
@@ -252,9 +252,37 @@
252
252
  "description": "The command that writes the roots before any job reads them."
253
253
  },
254
254
  "image": {
255
- "type": "string",
256
- "pattern": "^[^\\s]+$",
257
- "description": "The image every job runs in, built FROM terragucci's."
255
+ "anyOf": [
256
+ {
257
+ "type": "string",
258
+ "pattern": "^[^\\s]+$"
259
+ },
260
+ {
261
+ "type": "object",
262
+ "properties": {
263
+ "name": {
264
+ "type": "string",
265
+ "pattern": "^[^\\s]+$"
266
+ },
267
+ "mirror": {
268
+ "anyOf": [
269
+ {
270
+ "const": true
271
+ },
272
+ {
273
+ "type": "string",
274
+ "pattern": "^/"
275
+ }
276
+ ]
277
+ }
278
+ },
279
+ "additionalProperties": false,
280
+ "required": [
281
+ "name"
282
+ ]
283
+ }
284
+ ],
285
+ "description": "The image every job runs in, built FROM terragucci's; as a map, its name and the provider mirror it carries."
258
286
  },
259
287
  "notify": {
260
288
  "type": "object",
@@ -360,6 +388,48 @@
360
388
  ],
361
389
  "description": "A cron schedule for the job that opens each rollout's next wave, or false."
362
390
  },
391
+ "control": {
392
+ "type": "object",
393
+ "properties": {
394
+ "repo": {
395
+ "type": "string",
396
+ "pattern": "^[^/\\s]+(/[^/\\s]+){2,}$"
397
+ },
398
+ "op": {
399
+ "type": "string",
400
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
401
+ },
402
+ "forge": {
403
+ "enum": [
404
+ "github",
405
+ "gitlab",
406
+ "forgejo"
407
+ ]
408
+ },
409
+ "member": {
410
+ "type": "string",
411
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
412
+ },
413
+ "token_env": {
414
+ "type": "string",
415
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
416
+ },
417
+ "read_token_env": {
418
+ "type": "string",
419
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
420
+ },
421
+ "ref": {
422
+ "type": "string",
423
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
424
+ }
425
+ },
426
+ "additionalProperties": false,
427
+ "required": [
428
+ "repo",
429
+ "op"
430
+ ],
431
+ "description": "The control repo to tell after the default branch's apply succeeds; it runs this repo's dependents."
432
+ },
363
433
  "gitlab": {
364
434
  "type": "object",
365
435
  "properties": {
@@ -1052,6 +1122,15 @@
1052
1122
  "allow_unattended"
1053
1123
  ]
1054
1124
  }
1125
+ },
1126
+ "agents": {
1127
+ "type": "array",
1128
+ "minItems": 1,
1129
+ "items": {
1130
+ "type": "string",
1131
+ "pattern": "^\\S+$"
1132
+ },
1133
+ "description": "Forge app or bot identities that are agents; a change proposed through one has input.actor.kind agent."
1055
1134
  }
1056
1135
  },
1057
1136
  "additionalProperties": false,
@@ -1189,6 +1268,10 @@
1189
1268
  "type": "integer",
1190
1269
  "minimum": 1
1191
1270
  },
1271
+ "max_cost_usd": {
1272
+ "type": "number",
1273
+ "exclusiveMinimum": 0
1274
+ },
1192
1275
  "timeout": {
1193
1276
  "type": "integer",
1194
1277
  "minimum": 1
@@ -1218,6 +1301,10 @@
1218
1301
  "type": "integer",
1219
1302
  "minimum": 1
1220
1303
  },
1304
+ "max_cost_usd": {
1305
+ "type": "number",
1306
+ "exclusiveMinimum": 0
1307
+ },
1221
1308
  "timeout": {
1222
1309
  "type": "integer",
1223
1310
  "minimum": 1
@@ -1998,9 +2085,37 @@
1998
2085
  "description": "The command that writes the roots before any job reads them."
1999
2086
  },
2000
2087
  "image": {
2001
- "type": "string",
2002
- "pattern": "^[^\\s]+$",
2003
- "description": "The image every job runs in, built FROM terragucci's."
2088
+ "anyOf": [
2089
+ {
2090
+ "type": "string",
2091
+ "pattern": "^[^\\s]+$"
2092
+ },
2093
+ {
2094
+ "type": "object",
2095
+ "properties": {
2096
+ "name": {
2097
+ "type": "string",
2098
+ "pattern": "^[^\\s]+$"
2099
+ },
2100
+ "mirror": {
2101
+ "anyOf": [
2102
+ {
2103
+ "const": true
2104
+ },
2105
+ {
2106
+ "type": "string",
2107
+ "pattern": "^/"
2108
+ }
2109
+ ]
2110
+ }
2111
+ },
2112
+ "additionalProperties": false,
2113
+ "required": [
2114
+ "name"
2115
+ ]
2116
+ }
2117
+ ],
2118
+ "description": "The image every job runs in, built FROM terragucci's; as a map, its name and the provider mirror it carries."
2004
2119
  },
2005
2120
  "notify": {
2006
2121
  "type": "object",
@@ -2098,6 +2213,48 @@
2098
2213
  "const": false,
2099
2214
  "description": "A single repo's key; a control repo runs terragucci respond rollout itself."
2100
2215
  },
2216
+ "control": {
2217
+ "type": "object",
2218
+ "properties": {
2219
+ "repo": {
2220
+ "type": "string",
2221
+ "pattern": "^[^/\\s]+(/[^/\\s]+){2,}$"
2222
+ },
2223
+ "op": {
2224
+ "type": "string",
2225
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
2226
+ },
2227
+ "forge": {
2228
+ "enum": [
2229
+ "github",
2230
+ "gitlab",
2231
+ "forgejo"
2232
+ ]
2233
+ },
2234
+ "member": {
2235
+ "type": "string",
2236
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
2237
+ },
2238
+ "token_env": {
2239
+ "type": "string",
2240
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
2241
+ },
2242
+ "read_token_env": {
2243
+ "type": "string",
2244
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
2245
+ },
2246
+ "ref": {
2247
+ "type": "string",
2248
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._\\/-]{0,127}$"
2249
+ }
2250
+ },
2251
+ "additionalProperties": false,
2252
+ "required": [
2253
+ "repo",
2254
+ "op"
2255
+ ],
2256
+ "description": "The control repo to tell after the default branch's apply succeeds; it runs this repo's dependents."
2257
+ },
2101
2258
  "gitlab": {
2102
2259
  "type": "object",
2103
2260
  "properties": {
@@ -2790,6 +2947,15 @@
2790
2947
  "allow_unattended"
2791
2948
  ]
2792
2949
  }
2950
+ },
2951
+ "agents": {
2952
+ "type": "array",
2953
+ "minItems": 1,
2954
+ "items": {
2955
+ "type": "string",
2956
+ "pattern": "^\\S+$"
2957
+ },
2958
+ "description": "Forge app or bot identities that are agents; a change proposed through one has input.actor.kind agent."
2793
2959
  }
2794
2960
  },
2795
2961
  "additionalProperties": false,
@@ -2927,6 +3093,10 @@
2927
3093
  "type": "integer",
2928
3094
  "minimum": 1
2929
3095
  },
3096
+ "max_cost_usd": {
3097
+ "type": "number",
3098
+ "exclusiveMinimum": 0
3099
+ },
2930
3100
  "timeout": {
2931
3101
  "type": "integer",
2932
3102
  "minimum": 1
@@ -2956,6 +3126,10 @@
2956
3126
  "type": "integer",
2957
3127
  "minimum": 1
2958
3128
  },
3129
+ "max_cost_usd": {
3130
+ "type": "number",
3131
+ "exclusiveMinimum": 0
3132
+ },
2959
3133
  "timeout": {
2960
3134
  "type": "integer",
2961
3135
  "minimum": 1
package/dist/types.d.ts CHANGED
@@ -196,6 +196,13 @@ export interface PolicySettings {
196
196
  * counts.
197
197
  */
198
198
  override?: (string | OverrideEntry)[];
199
+ /**
200
+ * The forge app or bot identities that are agents, such as `my-agent[bot]`.
201
+ * A change proposed through one is an agent's: `input.actor.kind` is
202
+ * `agent` (./actor.ts). Read at base, like `override`. Unset, every change
203
+ * is a person's.
204
+ */
205
+ agents?: string[];
199
206
  /**
200
207
  * The rule outcomes the policy has: `deny` always, and `hold` and
201
208
  * `allow_unattended` when listed, read from `hold`, `hold_*`,
@@ -363,10 +370,65 @@ export interface AgentCommentSettings {
363
370
  key_secret?: string;
364
371
  /** The most turns the agent takes, as `$TG_AGENT_MAX_TURNS`. Default 30. */
365
372
  max_turns?: number;
373
+ /** The most the agent may spend, in US dollars, as `$TG_AGENT_MAX_COST_USD`. The agent job is stopped and nothing is pushed when the cost it reports is above it. No default: without it there is no money limit. */
374
+ max_cost_usd?: number;
366
375
  /** Minutes before the agent's job is stopped. Default 30. */
367
376
  timeout?: number;
368
377
  }
369
- export declare const AGENT_COMMENT_KEYS: readonly ["command", "key_secret", "max_turns", "timeout"];
378
+ /**
379
+ * `image` as a map: the image every job runs in, and whether it is a prepared
380
+ * image carrying a provider mirror (`terragucci image recipe` writes one).
381
+ * With `mirror` set, tf-check checks the mirror covers every lock file.
382
+ */
383
+ export interface ImageSettings {
384
+ /** The image reference, built FROM the terragucci image for the binary. */
385
+ name: string;
386
+ /** The provider mirror's directory in the image; `true` is the one the recipe writes (MIRROR_DIR). */
387
+ mirror?: string | true;
388
+ }
389
+ export declare const IMAGE_KEYS: readonly ["name", "mirror"];
390
+ /**
391
+ * `control`: after a member repo's apply on the default branch succeeds, its pipeline sends a dispatch to the
392
+ * control repo (a repository_dispatch on GitHub, a pipeline trigger on GitLab, a workflow dispatch on Forgejo),
393
+ * and the control repo runs the member's dependents with `chant workspace run --dependents-of`. The token the
394
+ * member holds is for that one call.
395
+ */
396
+ export interface ControlSettings {
397
+ /** The control repo, as a project key: `<host>/<owner>/<name>`. Its host says which forge's dispatch is sent. */
398
+ repo: string;
399
+ /** The control repo's forge, when its host does not say (forgeFromHost). */
400
+ forge?: ForgeName;
401
+ /** The Op the control repo runs on the member's dependents (`chant workspace run --op`). */
402
+ op: string;
403
+ /** The member's name in the control repo's workspace. Default: the repo's name. */
404
+ member?: string;
405
+ /** The secret holding the token that may dispatch to the control repo. Default `TERRAGUCCI_CONTROL_TOKEN`. */
406
+ token_env?: string;
407
+ /** The secret holding a read-only token for the control repo, which the generated tf-plan job checks it out with. Default `TERRAGUCCI_CONTROL_READ_TOKEN`; the job's own token is used when the secret is not set. Never the dispatch token. */
408
+ read_token_env?: string;
409
+ /** The branch of the control repo a GitLab pipeline or a Forgejo workflow runs on. Default `main`; GitHub's dispatch always runs the default branch. */
410
+ ref?: string;
411
+ }
412
+ export declare const CONTROL_KEYS: readonly ["repo", "op", "forge", "member", "token_env", "read_token_env", "ref"];
413
+ /** The token a member holds for the dispatch when `control.token_env` is unset. */
414
+ export declare const CONTROL_TOKEN_ENV = "TERRAGUCCI_CONTROL_TOKEN";
415
+ /** The secret the plan job reads the control repo with when `control.read_token_env` is unset: read-only, and not the dispatch token. */
416
+ export declare const CONTROL_READ_TOKEN_ENV = "TERRAGUCCI_CONTROL_READ_TOKEN";
417
+ /** A member name or Op name as the control repo's workspace spells them; the dispatch carries both into a shell line. */
418
+ export declare const CONTROL_NAME: RegExp;
419
+ /** A branch name the dispatch may carry into a URL and a shell line. */
420
+ export declare const CONTROL_REF: RegExp;
421
+ /** The problems with `control`. */
422
+ export declare function controlProblems(v: unknown, where: string): string[];
423
+ /** Where `terragucci image recipe` puts the provider mirror in the image. */
424
+ export declare const MIRROR_DIR = "/usr/share/terragucci/providers";
425
+ /** The image reference `image` names, in either form. */
426
+ export declare function imageName(image: string | ImageSettings | undefined): string | undefined;
427
+ /** The provider mirror's directory in the image `image` names, when it carries one. */
428
+ export declare function imageMirror(image: string | ImageSettings | undefined): string | undefined;
429
+ /** The problems with `image`: a reference, or a map of `name` and `mirror`. */
430
+ export declare function imageProblems(v: unknown, where: string): string[];
431
+ export declare const AGENT_COMMENT_KEYS: readonly ["command", "key_secret", "max_turns", "max_cost_usd", "timeout"];
370
432
  /**
371
433
  * `agent.drift`: when the drift job opens the drift issue, a job runs a coding
372
434
  * agent on the default branch with the drift report, and a second job opens a
@@ -374,7 +436,7 @@ export declare const AGENT_COMMENT_KEYS: readonly ["command", "key_secret", "max
374
436
  * agent's job holds no forge token and no cloud role. Its settings are
375
437
  * `agent.comment`'s (AgentCommentSettings); `true` takes every default.
376
438
  */
377
- export declare const AGENT_DRIFT_KEYS: readonly ["command", "key_secret", "max_turns", "timeout"];
439
+ export declare const AGENT_DRIFT_KEYS: readonly ["command", "key_secret", "max_turns", "max_cost_usd", "timeout"];
378
440
  /** Why `agent.drift` and `respond.drift: pull-request` do not go together. */
379
441
  export declare const AGENT_DRIFT_RESPOND = "agent.drift opens the drift pull request itself, so the codified one would be a second; set respond.drift to attribute or off";
380
442
  /**
@@ -446,9 +508,10 @@ export interface ProjectSettings {
446
508
  /**
447
509
  * The image every job runs in, in place of terragucci's: one built FROM
448
510
  * the terragucci image for the binary, so the job still has terragucci and
449
- * the binary, plus what the `ci.hooks` need.
511
+ * the binary, plus what the `ci.hooks` need. A map names it under `name`
512
+ * and says, with `mirror`, that it carries a provider mirror (ImageSettings).
450
513
  */
451
- image?: string;
514
+ image?: string | ImageSettings;
452
515
  /**
453
516
  * Notifications: the names of the secrets holding a Slack or Teams
454
517
  * incoming webhook, and a generic webhook's address with the key that
@@ -485,6 +548,11 @@ export interface ProjectSettings {
485
548
  * control repo. `respond.rollout: off` leaves the job out.
486
549
  */
487
550
  rollouts?: string | false;
551
+ /**
552
+ * The control repo to tell once the default branch's apply succeeded (ControlSettings). The pipeline gets a
553
+ * job that sends the control repo a dispatch, and the control repo runs this project's dependents.
554
+ */
555
+ control?: ControlSettings;
488
556
  /** GitLab only: how the project keeps its forge token; see TOKEN_PROTECTIONS. */
489
557
  gitlab?: {
490
558
  token?: GitLabToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/terragucci",
3
- "version": "0.4.43",
3
+ "version": "0.4.44",
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",
@@ -19,10 +19,12 @@
19
19
  },
20
20
  "./report.schema.json": "./dist/report.schema.json",
21
21
  "./notify.schema.json": "./dist/notify.schema.json",
22
- "./terragucci.schema.json": "./dist/terragucci.schema.json"
22
+ "./terragucci.schema.json": "./dist/terragucci.schema.json",
23
+ "./workspace-kinds": "./workspace-kinds.json"
23
24
  },
24
25
  "files": [
25
26
  "dist",
27
+ "workspace-kinds.json",
26
28
  "README.md",
27
29
  "LICENSE"
28
30
  ],
@@ -34,7 +36,7 @@
34
36
  "build": "node ../../scripts/build-cli.mjs"
35
37
  },
36
38
  "dependencies": {
37
- "@intentius/chant": "0.124.46"
39
+ "@intentius/chant": "0.124.50"
38
40
  },
39
41
  "peerDependencies": {
40
42
  "@intentius/tsad-reference": "2.x",
@@ -50,10 +52,10 @@
50
52
  },
51
53
  "devDependencies": {
52
54
  "@cdktn/hcl2json": "0.24.0",
53
- "@intentius/chant-lexicon-forgejo": "0.124.46",
54
- "@intentius/chant-lexicon-github": "0.124.46",
55
- "@intentius/chant-lexicon-gitlab": "0.124.46",
56
- "@intentius/chant-lexicon-terraform": "0.124.46",
55
+ "@intentius/chant-lexicon-forgejo": "0.124.50",
56
+ "@intentius/chant-lexicon-github": "0.124.50",
57
+ "@intentius/chant-lexicon-gitlab": "0.124.50",
58
+ "@intentius/chant-lexicon-terraform": "0.124.50",
57
59
  "@intentius/tsad-reference": "2.1.0",
58
60
  "@modelcontextprotocol/sdk": "1.30.1"
59
61
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "schema": 1,
3
+ "kinds": [
4
+ {
5
+ "name": "terragucci-control",
6
+ "description": "a terragucci control repo: a terragucci.yml that lists projects and the defaults they share",
7
+ "precedence": 300,
8
+ "probe": { "anyFile": ["terragucci.yml", "terragucci.yaml", "terragucci.json"] },
9
+ "memberFile": { "path": "terragucci.yml", "schema": "dist/terragucci.schema.json" }
10
+ }
11
+ ]
12
+ }