@intentius/chant-lexicon-pulumi 0.124.54 → 0.124.55

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.
Files changed (146) hide show
  1. package/README.md +42 -3
  2. package/dist/adopt.d.ts +68 -0
  3. package/dist/adopt.d.ts.map +1 -0
  4. package/dist/adopt.js +162 -0
  5. package/dist/capability-plugin.d.ts +3 -0
  6. package/dist/capability-plugin.d.ts.map +1 -1
  7. package/dist/capability-plugin.js +8 -1
  8. package/dist/change-set.d.ts +27 -4
  9. package/dist/change-set.d.ts.map +1 -1
  10. package/dist/change-set.js +15 -5
  11. package/dist/ci-setup.d.ts +53 -0
  12. package/dist/ci-setup.d.ts.map +1 -0
  13. package/dist/ci-setup.js +146 -0
  14. package/dist/composites/pulumi-adopt-op.d.ts +106 -0
  15. package/dist/composites/pulumi-adopt-op.d.ts.map +1 -0
  16. package/dist/composites/pulumi-adopt-op.js +132 -0
  17. package/dist/engine-events.d.ts +222 -0
  18. package/dist/engine-events.d.ts.map +1 -0
  19. package/dist/engine-events.js +280 -0
  20. package/dist/exit-codes.d.ts +53 -0
  21. package/dist/exit-codes.d.ts.map +1 -0
  22. package/dist/exit-codes.js +67 -0
  23. package/dist/index.d.ts +12 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +15 -2
  26. package/dist/init-templates.d.ts.map +1 -1
  27. package/dist/init-templates.js +5 -3
  28. package/dist/integrity.json +3 -3
  29. package/dist/lint/post-synth/pul015.d.ts +2 -1
  30. package/dist/lint/post-synth/pul015.d.ts.map +1 -1
  31. package/dist/lock-rows.d.ts +32 -0
  32. package/dist/lock-rows.d.ts.map +1 -0
  33. package/dist/lock-rows.js +36 -0
  34. package/dist/manifest.json +1 -1
  35. package/dist/member-engine.d.ts +27 -2
  36. package/dist/member-engine.d.ts.map +1 -1
  37. package/dist/member-engine.js +58 -7
  38. package/dist/member-outputs.d.ts.map +1 -1
  39. package/dist/member-outputs.js +4 -4
  40. package/dist/op/activities/index.d.ts +9 -1
  41. package/dist/op/activities/index.d.ts.map +1 -1
  42. package/dist/op/activities/index.js +8 -1
  43. package/dist/op/activities/pulumi-adopt.d.ts +104 -0
  44. package/dist/op/activities/pulumi-adopt.d.ts.map +1 -0
  45. package/dist/op/activities/pulumi-adopt.js +216 -0
  46. package/dist/op/activities/pulumi.d.ts.map +1 -1
  47. package/dist/op/activities/pulumi.js +2 -1
  48. package/dist/op/activity-contracts.d.ts +73 -0
  49. package/dist/op/activity-contracts.d.ts.map +1 -1
  50. package/dist/op/activity-contracts.js +49 -0
  51. package/dist/op/builders.d.ts +9 -0
  52. package/dist/op/builders.d.ts.map +1 -1
  53. package/dist/op/builders.js +20 -0
  54. package/dist/plan-shape.d.ts +47 -0
  55. package/dist/plan-shape.d.ts.map +1 -0
  56. package/dist/plan-shape.js +94 -0
  57. package/dist/plugin.d.ts.map +1 -1
  58. package/dist/plugin.js +25 -4
  59. package/dist/plunge-timings.d.ts +43 -0
  60. package/dist/plunge-timings.d.ts.map +1 -0
  61. package/dist/plunge-timings.js +106 -0
  62. package/dist/pulumi-up.d.ts +376 -0
  63. package/dist/pulumi-up.d.ts.map +1 -0
  64. package/dist/pulumi-up.js +823 -0
  65. package/dist/release-copy.d.ts +47 -0
  66. package/dist/release-copy.d.ts.map +1 -0
  67. package/dist/release-copy.js +131 -0
  68. package/dist/review-stack.d.ts +92 -0
  69. package/dist/review-stack.d.ts.map +1 -0
  70. package/dist/review-stack.js +222 -0
  71. package/dist/rules/pul015.ts +2 -1
  72. package/dist/run.d.ts +250 -7
  73. package/dist/run.d.ts.map +1 -1
  74. package/dist/run.js +432 -26
  75. package/dist/stack-export-snapshot.d.ts +125 -0
  76. package/dist/stack-export-snapshot.d.ts.map +1 -0
  77. package/dist/stack-export-snapshot.js +233 -0
  78. package/dist/stack-ops.d.ts +175 -0
  79. package/dist/stack-ops.d.ts.map +1 -0
  80. package/dist/stack-ops.js +400 -0
  81. package/dist/stack-references.d.ts +46 -0
  82. package/dist/stack-references.d.ts.map +1 -0
  83. package/dist/stack-references.js +88 -0
  84. package/dist/trace-facts.d.ts +34 -0
  85. package/dist/trace-facts.d.ts.map +1 -0
  86. package/dist/trace-facts.js +81 -0
  87. package/dist/workspace-member.d.ts +13 -2
  88. package/dist/workspace-member.d.ts.map +1 -1
  89. package/dist/workspace-member.js +14 -9
  90. package/package.json +2 -2
  91. package/src/adopt.ts +202 -0
  92. package/src/capability-plugin.ts +15 -6
  93. package/src/change-set.ts +29 -5
  94. package/src/ci-setup.test.ts +123 -0
  95. package/src/ci-setup.ts +176 -0
  96. package/src/composites/pulumi-adopt-op.test.ts +223 -0
  97. package/src/composites/pulumi-adopt-op.ts +191 -0
  98. package/src/composites/pulumi-watch-op.test.ts +2 -2
  99. package/src/engine-events.test.ts +134 -0
  100. package/src/engine-events.ts +390 -0
  101. package/src/engine-graph.test.ts +1 -1
  102. package/src/exit-codes.test.ts +21 -0
  103. package/src/exit-codes.ts +71 -0
  104. package/src/index.ts +75 -1
  105. package/src/init-templates.ts +5 -3
  106. package/src/lint/post-synth/pul015.ts +2 -1
  107. package/src/lock-rows.test.ts +60 -0
  108. package/src/lock-rows.ts +56 -0
  109. package/src/member-engine.test.ts +112 -0
  110. package/src/member-engine.ts +73 -6
  111. package/src/member-outputs.test.ts +2 -2
  112. package/src/member-outputs.ts +9 -8
  113. package/src/op/activities/index.ts +19 -1
  114. package/src/op/activities/pulumi-adopt.ts +334 -0
  115. package/src/op/activities/pulumi.ts +2 -1
  116. package/src/op/activity-contracts.ts +75 -0
  117. package/src/op/builders.ts +37 -0
  118. package/src/plan-shape.test.ts +91 -0
  119. package/src/plan-shape.ts +105 -0
  120. package/src/plugin.test.ts +1 -1
  121. package/src/plugin.ts +28 -4
  122. package/src/plunge-timings.test.ts +241 -0
  123. package/src/plunge-timings.ts +115 -0
  124. package/src/plunge-up-failed.test.ts +54 -0
  125. package/src/pr-note.test.ts +87 -0
  126. package/src/pulumi-up.test.ts +470 -0
  127. package/src/pulumi-up.ts +1032 -0
  128. package/src/release-copy.test.ts +74 -0
  129. package/src/release-copy.ts +142 -0
  130. package/src/review-stack.test.ts +254 -0
  131. package/src/review-stack.ts +266 -0
  132. package/src/run.test.ts +176 -3
  133. package/src/run.ts +501 -30
  134. package/src/stack-export-snapshot.test.ts +190 -0
  135. package/src/stack-export-snapshot.ts +312 -0
  136. package/src/stack-ops.test.ts +286 -0
  137. package/src/stack-ops.ts +552 -0
  138. package/src/stack-references.test.ts +96 -0
  139. package/src/stack-references.ts +110 -0
  140. package/src/testdata/pulumi-stream/README.md +16 -0
  141. package/src/testdata/pulumi-stream/preview-stream.ndjson +42 -0
  142. package/src/testdata/pulumi-stream/up-failed-plunge.ndjson +5 -0
  143. package/src/trace-facts.test.ts +38 -0
  144. package/src/trace-facts.ts +83 -0
  145. package/src/workspace-member.test.ts +2 -1
  146. package/src/workspace-member.ts +30 -12
@@ -1,8 +1,33 @@
1
1
  /** What runs a Pulumi member's stack. */
2
2
  export type PulumiMemberEngine = "pulumi" | "plunge";
3
- /** Which engine runs the member, and the rule that said so (see `./run.ts`'s module comment). */
4
- export declare function pulumiMemberEngine(dir: string, configured?: PulumiMemberEngine): {
3
+ /** Where the engine decision came from, first rule that answered. */
4
+ export type PulumiMemberEngineSource = "member-config" | "plywood.yml" | "PULUMI_BACKEND_URL" | "Pulumi.yaml" | "default";
5
+ /** Inputs beyond the member directory. All optional. */
6
+ export interface PulumiMemberEngineOptions {
7
+ /** The job environment; defaults to `process.env`. Only `PULUMI_BACKEND_URL` is read. */
8
+ env?: Record<string, string | undefined>;
9
+ /** Where the search for `plywood.yml` stops (inclusive). Default: the first directory holding `.git`, else the filesystem root. */
10
+ plywoodRoot?: string;
11
+ }
12
+ /**
13
+ * The `engine` and `backend` keys of the nearest `plywood.yml`, looking in
14
+ * `dir` and each parent up to the repository root. plywood passes no
15
+ * detection of its own: the file is read here (chant#4559).
16
+ */
17
+ export declare function readPlywoodEngine(dir: string, stopAt?: string): {
18
+ file: string;
19
+ engine?: PulumiMemberEngine;
20
+ backend?: string;
21
+ } | undefined;
22
+ /**
23
+ * Which engine runs the member, the rule that said so, and where it came from
24
+ * (see `./run.ts`'s module comment). First rule that answers:
25
+ * the member's config, `engine` (then a `plunge+` `backend`) in `plywood.yml`,
26
+ * `PULUMI_BACKEND_URL`, `backend.url` in `Pulumi.yaml`, else pulumi.
27
+ */
28
+ export declare function pulumiMemberEngine(dir: string, configured?: PulumiMemberEngine, opts?: PulumiMemberEngineOptions): {
5
29
  engine: PulumiMemberEngine;
6
30
  because: string;
31
+ source: PulumiMemberEngineSource;
7
32
  };
8
33
  //# sourceMappingURL=member-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"member-engine.d.ts","sourceRoot":"","sources":["../src/member-engine.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,kBAAkB,GAAG;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAchI"}
1
+ {"version":3,"file":"member-engine.d.ts","sourceRoot":"","sources":["../src/member-engine.ts"],"names":[],"mappings":"AAWA,yCAAyC;AACzC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,qEAAqE;AACrE,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,aAAa,GAAG,oBAAoB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE1H,wDAAwD;AACxD,MAAM,WAAW,yBAAyB;IACxC,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,mIAAmI;IACnI,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuB3I;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,kBAAkB,EAC/B,IAAI,GAAE,yBAA8B,GACnC;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAA;CAAE,CA4BnF"}
@@ -6,24 +6,75 @@
6
6
  * only a member on plunge has a checked-in `engine-graph.json` read (#4529).
7
7
  */
8
8
  import { existsSync, readFileSync } from "node:fs";
9
- import { join } from "node:path";
9
+ import { dirname, join, resolve } from "node:path";
10
10
  import { parseYAML } from "@intentius/chant/yaml";
11
- /** Which engine runs the member, and the rule that said so (see `./run.ts`'s module comment). */
12
- export function pulumiMemberEngine(dir, configured) {
11
+ const PLUNGE_URL = /^plunge[+:]/;
12
+ const PLYWOOD_FILES = ["plywood.yml", "plywood.yaml"];
13
+ /**
14
+ * The `engine` and `backend` keys of the nearest `plywood.yml`, looking in
15
+ * `dir` and each parent up to the repository root. plywood passes no
16
+ * detection of its own: the file is read here (chant#4559).
17
+ */
18
+ export function readPlywoodEngine(dir, stopAt) {
19
+ let cur = resolve(dir);
20
+ const stop = stopAt ? resolve(stopAt) : undefined;
21
+ for (let depth = 0; depth < 32; depth++) {
22
+ for (const name of PLYWOOD_FILES) {
23
+ const file = join(cur, name);
24
+ if (!existsSync(file))
25
+ continue;
26
+ try {
27
+ const doc = parseYAML(readFileSync(file, "utf-8"));
28
+ const engine = doc?.engine === "pulumi" || doc?.engine === "plunge" ? doc.engine : undefined;
29
+ const backend = typeof doc?.backend === "string" ? doc.backend : undefined;
30
+ return { file, engine, backend };
31
+ }
32
+ catch {
33
+ // An unreadable plywood.yml fails plywood's own config check; here it names no engine.
34
+ return { file };
35
+ }
36
+ }
37
+ if (cur === stop || (!stop && existsSync(join(cur, ".git"))))
38
+ return undefined;
39
+ const parent = dirname(cur);
40
+ if (parent === cur)
41
+ return undefined;
42
+ cur = parent;
43
+ }
44
+ return undefined;
45
+ }
46
+ /**
47
+ * Which engine runs the member, the rule that said so, and where it came from
48
+ * (see `./run.ts`'s module comment). First rule that answers:
49
+ * the member's config, `engine` (then a `plunge+` `backend`) in `plywood.yml`,
50
+ * `PULUMI_BACKEND_URL`, `backend.url` in `Pulumi.yaml`, else pulumi.
51
+ */
52
+ export function pulumiMemberEngine(dir, configured, opts = {}) {
13
53
  if (configured)
14
- return { engine: configured, because: `the member's config says engine: ${configured}` };
54
+ return { engine: configured, because: `the member's config says engine: ${configured}`, source: "member-config" };
55
+ const plywood = readPlywoodEngine(dir, opts.plywoodRoot);
56
+ if (plywood?.engine) {
57
+ return { engine: plywood.engine, because: `${plywood.file} says engine: ${plywood.engine}`, source: "plywood.yml" };
58
+ }
59
+ if (plywood?.backend && PLUNGE_URL.test(plywood.backend)) {
60
+ return { engine: "plunge", because: `${plywood.file} names the plunge backend ${plywood.backend}`, source: "plywood.yml" };
61
+ }
62
+ const envUrl = (opts.env ?? process.env).PULUMI_BACKEND_URL;
63
+ if (envUrl && PLUNGE_URL.test(envUrl)) {
64
+ return { engine: "plunge", because: `PULUMI_BACKEND_URL names the plunge backend ${envUrl}`, source: "PULUMI_BACKEND_URL" };
65
+ }
15
66
  const file = join(dir, "Pulumi.yaml");
16
67
  if (existsSync(file)) {
17
68
  try {
18
69
  const doc = parseYAML(readFileSync(file, "utf-8"));
19
70
  const backend = doc.backend;
20
71
  const url = typeof backend?.url === "string" ? backend.url : undefined;
21
- if (url && /^plunge[+:]/.test(url))
22
- return { engine: "plunge", because: `Pulumi.yaml names the plunge backend ${url}` };
72
+ if (url && PLUNGE_URL.test(url))
73
+ return { engine: "plunge", because: `Pulumi.yaml names the plunge backend ${url}`, source: "Pulumi.yaml" };
23
74
  }
24
75
  catch {
25
76
  // An unreadable Pulumi.yaml fails the member file check; here it just names no backend.
26
77
  }
27
78
  }
28
- return { engine: "pulumi", because: "nothing names plunge" };
79
+ return { engine: "pulumi", because: "nothing names plunge", source: "default" };
29
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"member-outputs.d.ts","sourceRoot":"","sources":["../src/member-outputs.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AAClI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAuE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAIxI,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjD,sGAAsG;AACtG,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE,MAAM,WAAW,yBAAyB;IACxC,qHAAqH;IACrH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,oEAAoE;IACpE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAcD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAGjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,oBAAoB,CAcpJ;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErF;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,kBAAkB,CAoB9F;AAED,8DAA8D;AAC9D,eAAO,MAAM,uBAAuB,EAAE,kBAAyC,CAAC"}
1
+ {"version":3,"file":"member-outputs.d.ts","sourceRoot":"","sources":["../src/member-outputs.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AAClI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAqE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAItI,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjD,sGAAsG;AACtG,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AAEzE,MAAM,WAAW,yBAAyB;IACxC,qHAAqH;IACrH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,oEAAoE;IACpE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAcD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAGjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,oBAAoB,CAcpJ;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErF;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,kBAAkB,CAoB9F;AAED,8DAA8D;AAC9D,eAAO,MAAM,uBAAuB,EAAE,kBAAyC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { pulumiPlannedStackOutputs, pulumiExportedStackOutputs } from "./stack-outputs.js";
2
- import { previewPulumiMemberRead, pulumiMemberStackOutputs, readMemberExport } from "./run.js";
2
+ import { memberExportOf, previewPulumiMemberRead, pulumiMemberStackOutputs } from "./run.js";
3
3
  import { isSecret } from "./values.js";
4
4
  import { PULUMI_EXPORT_FILE } from "./workspace-member.js";
5
5
  /** The environment variable that makes the source read applied outputs from the checked-in export. */
@@ -64,9 +64,9 @@ export function pulumiOutputSource(options = {}) {
64
64
  kinds: ["pulumi"],
65
65
  async applied(_ctx, ref) {
66
66
  if (appliedFrom() === "export") {
67
- const exported = readMemberExport(ref.dir);
67
+ const exported = await memberExportOf(ref.dir);
68
68
  if (exported === undefined) {
69
- throw new Error(`member-outputs: Pulumi member "${ref.member}" has no readable ${PULUMI_EXPORT_FILE} in ${ref.dir}, and its outputs are read from the export (${PULUMI_APPLIED_OUTPUTS_ENV}=export)`);
69
+ throw new Error(`member-outputs: Pulumi member "${ref.member}" has no export in the index store and no readable ${PULUMI_EXPORT_FILE} in ${ref.dir}, and its outputs are read from the export (${PULUMI_APPLIED_OUTPUTS_ENV}=export)`);
70
70
  }
71
71
  return pulumiExportedOutputValues(exported);
72
72
  }
@@ -74,7 +74,7 @@ export function pulumiOutputSource(options = {}) {
74
74
  },
75
75
  async planned(_ctx, ref) {
76
76
  const read = await previewPulumiMemberRead({ member: ref.member, dir: ref.dir, ...runners });
77
- return pulumiMemberPlannedOutputs(ref.member, { ...read, exported: readMemberExport(ref.dir) });
77
+ return pulumiMemberPlannedOutputs(ref.member, { ...read, exported: await memberExportOf(ref.dir) });
78
78
  },
79
79
  };
80
80
  }
@@ -12,8 +12,16 @@
12
12
  * per resource (`plunge drift --resource <urn> --stream` on plunge), as
13
13
  * drift counts.
14
14
  *
15
- * Neither changes the stack. See `./pulumi.ts`.
15
+ * - pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt:
16
+ * `PulumiAdoptOp`'s steps (#4562), the shared bucket check, the stock
17
+ * checkpoint's export, `plunge stack adopt --json` and, after the gate,
18
+ * `plunge stack adopt --json --yes`. See `./pulumi-adopt.ts`.
19
+ *
20
+ * Only `pulumiAdopt` changes anything: it writes plunge's records. See
21
+ * `./pulumi.ts`.
16
22
  */
17
23
  export { pulumiPreview, pulumiDrift } from "./pulumi.js";
24
+ export { pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt } from "./pulumi-adopt.js";
25
+ export type { PulumiAdoptStackArgs, PulumiAdoptCheckArgs, PulumiAdoptCheckResult, PulumiAdoptExportArgs, PulumiAdoptExportResult, PulumiAdoptPreviewArgs, PulumiAdoptPreviewResult, PulumiAdoptArgs, PulumiAdoptResult, } from "./pulumi-adopt.js";
18
26
  export type { PulumiMemberArgs, PulumiPreviewArgs, PulumiPreviewResult, PulumiDriftArgs, PulumiDriftResult } from "./pulumi.js";
19
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtG,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
@@ -12,6 +12,13 @@
12
12
  * per resource (`plunge drift --resource <urn> --stream` on plunge), as
13
13
  * drift counts.
14
14
  *
15
- * Neither changes the stack. See `./pulumi.ts`.
15
+ * - pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt:
16
+ * `PulumiAdoptOp`'s steps (#4562), the shared bucket check, the stock
17
+ * checkpoint's export, `plunge stack adopt --json` and, after the gate,
18
+ * `plunge stack adopt --json --yes`. See `./pulumi-adopt.ts`.
19
+ *
20
+ * Only `pulumiAdopt` changes anything: it writes plunge's records. See
21
+ * `./pulumi.ts`.
16
22
  */
17
23
  export { pulumiPreview, pulumiDrift } from "./pulumi.js";
24
+ export { pulumiAdoptCheck, pulumiAdoptExport, pulumiAdoptPreview, pulumiAdopt } from "./pulumi-adopt.js";
@@ -0,0 +1,104 @@
1
+ import type { BucketReport, BucketTarget, CheckBucketOptions } from "@intentius/chant/bucket-check";
2
+ import { type PlungeAdoptStatus } from "../../adopt.js";
3
+ import { type PulumiRunner } from "../../run.js";
4
+ /** The fields every adopt activity takes. */
5
+ export interface PulumiAdoptStackArgs {
6
+ /** The member's name. */
7
+ member: string;
8
+ /** The stack's directory, where `Pulumi.yaml` is. Relative paths resolve against `cwd`. */
9
+ dir: string;
10
+ cwd?: string;
11
+ /** The stack to adopt. */
12
+ stack: string;
13
+ }
14
+ export interface PulumiAdoptCheckArgs extends PulumiAdoptStackArgs {
15
+ /** The plunge backend URL (`plunge+s3://...`). Default: `plywood.yml`'s, `PULUMI_BACKEND_URL`, `Pulumi.yaml`'s. */
16
+ backend?: string;
17
+ /** The bucket to check, when the URL does not say enough (azblob), as `@intentius/chant/bucket-check` takes it. */
18
+ bucket?: Record<string, unknown>;
19
+ /** Key prefixes a lifecycle rule must cover. Default: the URL's path. */
20
+ namespaces?: string[];
21
+ /** Settings waived on top of the URL's `allow_insecure` and `PLUNGE_ALLOW_INSECURE`. An unwaivable one stays refused. */
22
+ allowInsecure?: string[];
23
+ }
24
+ export interface PulumiAdoptCheckResult {
25
+ member: string;
26
+ stack: string;
27
+ /** False when there was no bucket to check. */
28
+ checked: boolean;
29
+ /** Why the check did not run. */
30
+ skipped?: string;
31
+ store?: string;
32
+ bucket?: string;
33
+ correct: boolean;
34
+ /** Settings that failed and were waived. */
35
+ waived: string[];
36
+ }
37
+ export interface PulumiAdoptExportArgs extends PulumiAdoptStackArgs {
38
+ /** The plunge backend URL; its stock form is where the export is read. */
39
+ backend?: string;
40
+ /** Where the checkpoint comes from instead: another backend (Pulumi Cloud, `https://api.pulumi.com`), or an export already taken. */
41
+ from?: {
42
+ backend?: string;
43
+ file?: string;
44
+ };
45
+ }
46
+ export interface PulumiAdoptExportResult {
47
+ member: string;
48
+ stack: string;
49
+ /** The export, a scratch file (mode 600) or `from.file`. */
50
+ file: string;
51
+ sha256: string;
52
+ resources: number;
53
+ pendingOperations: number;
54
+ /** The backend it was read from, or `file`. */
55
+ source: string;
56
+ /** True when plunge adopts this file (`--file`), on the route from another backend or a given file. */
57
+ adoptFromFile: boolean;
58
+ }
59
+ export interface PulumiAdoptPreviewArgs extends PulumiAdoptStackArgs {
60
+ /** `--file`: the export to adopt, from the Export step when `adoptFromFile`. */
61
+ file?: string;
62
+ }
63
+ export interface PulumiAdoptPreviewResult {
64
+ member: string;
65
+ stack: string;
66
+ status: PlungeAdoptStatus;
67
+ /** What the gate binds. */
68
+ planDigest: string;
69
+ checkpointDigest: string | null;
70
+ resources: number;
71
+ /** Resources by fate: marker, record, pending, already-adopted. */
72
+ fates: Record<string, number>;
73
+ /** False when the stack is already adopted from this checkpoint. */
74
+ changed: boolean;
75
+ }
76
+ export interface PulumiAdoptArgs extends PulumiAdoptPreviewArgs {
77
+ /** The approved preview's digest, to report whether the adoption matched it. */
78
+ planDigest?: string;
79
+ }
80
+ export interface PulumiAdoptResult extends PulumiAdoptPreviewResult {
81
+ /** Whether what plunge adopted digests as the approved preview. Absent when no digest was handed in. */
82
+ matchesApproved?: boolean;
83
+ }
84
+ /** Runners and seams, injectable so the tests run no binary and read no bucket. */
85
+ export interface PulumiAdoptDeps {
86
+ run?: PulumiRunner;
87
+ plunge?: PulumiRunner;
88
+ env?: Record<string, string | undefined>;
89
+ tmp?: string;
90
+ checkBucket?: (target: BucketTarget, options: CheckBucketOptions) => Promise<BucketReport>;
91
+ }
92
+ /** The shared bucket check on the stack's backend bucket; throws when a setting fails unwaived. */
93
+ export declare function adoptCheck(a: PulumiAdoptCheckArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptCheckResult>;
94
+ /** The stock checkpoint as a scratch file, or the given one. */
95
+ export declare function adoptExport(a: PulumiAdoptExportArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptExportResult>;
96
+ /** `plunge stack adopt --json`: the classification, written nowhere. A refusal fails the step. */
97
+ export declare function adoptPreview(a: PulumiAdoptPreviewArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptPreviewResult>;
98
+ /** `plunge stack adopt --json --yes`: writes the records. A refusal fails the step; plunge wrote nothing then. */
99
+ export declare function adoptStack(a: PulumiAdoptArgs, deps?: PulumiAdoptDeps): Promise<PulumiAdoptResult>;
100
+ export declare function pulumiAdoptCheck(args: Record<string, unknown>): Promise<PulumiAdoptCheckResult>;
101
+ export declare function pulumiAdoptExport(args: Record<string, unknown>): Promise<PulumiAdoptExportResult>;
102
+ export declare function pulumiAdoptPreview(args: Record<string, unknown>): Promise<PulumiAdoptPreviewResult>;
103
+ export declare function pulumiAdopt(args: Record<string, unknown>): Promise<PulumiAdoptResult>;
104
+ //# sourceMappingURL=pulumi-adopt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pulumi-adopt.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi-adopt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * `PulumiAdoptOp`'s activities (#4562): check the bucket, export the stock
3
+ * checkpoint, preview the adoption, adopt. The composite
4
+ * (`../../composites/pulumi-adopt-op.ts`) puts its gate between the preview
5
+ * and the adoption, bound to the preview's `planDigest`.
6
+ *
7
+ * - `pulumiAdoptCheck`: the shared bucket check (#4558, `@intentius/chant/bucket-check`)
8
+ * on the bucket the stack's backend URL names. A failing setting that is
9
+ * not waived (`allow_insecure` on the URL, `PLUNGE_ALLOW_INSECURE`, or the
10
+ * step's `allowInsecure`) refuses the stack by name with its fix, before
11
+ * anything is exported. A `file://` backend has no bucket and is skipped.
12
+ * - `pulumiAdoptExport`: stock `pulumi stack export --stack <s>`, through the
13
+ * read allowlist (#4546), against the stack's stock backend at the same
14
+ * root (the backend URL without `plunge+`) or the step's `from.backend`
15
+ * (Pulumi Cloud, for the `--file` route). The export is kept in a scratch
16
+ * file under the OS temp dir, mode 600, since it holds secret ciphertext:
17
+ * it is the back-out copy, and on the `--file` route the document plunge
18
+ * adopts. `from.file` names an export taken by hand instead, and nothing
19
+ * runs. The result gives the file, its SHA-256 and its counts.
20
+ * - `pulumiAdoptPreview`: `plunge stack adopt --json --stack <s> [--file f]`,
21
+ * which classifies and writes nothing. A refused adoption fails the step,
22
+ * naming each refusal. Its `planDigest` (`../../adopt.ts`'s
23
+ * `pulumiAdoptDigest`) is what the gate binds.
24
+ * - `pulumiAdopt`: `plunge stack adopt --json --yes --stack <s> [--file f]`
25
+ * through `runAdoptPlunge`, the one entry point allowed to write. It
26
+ * reports whether what plunge adopted digests as the approved preview did.
27
+ *
28
+ * None of them calls a cloud API but the bucket check's reads: adoption
29
+ * writes plunge's records only, and the next `plunge up` writes the
30
+ * markers.
31
+ */
32
+ import { createHash } from "node:crypto";
33
+ import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
34
+ import { tmpdir } from "node:os";
35
+ import { isAbsolute, join, resolve } from "node:path";
36
+ import { adoptBucketTarget, adoptFates, parsePlungeAdoptView, pulumiAdoptDigest, pulumiStackBackend, stockBackendUrl, } from "../../adopt.js";
37
+ import { pulumiExportResources } from "../../change-set.js";
38
+ import { defaultPlungeRunner, defaultPulumiRunner, plungeAdoptArgs, pulumiRunFailure, runAdoptPlunge, runAllowedPlunge, runAllowedPulumi, } from "../../run.js";
39
+ import { isObject } from "../../values.js";
40
+ function stackDir(a) {
41
+ return isAbsolute(a.dir) ? a.dir : resolve(a.cwd ?? process.cwd(), a.dir);
42
+ }
43
+ function requireStack(a, what) {
44
+ if (typeof a?.dir !== "string" || a.dir === "")
45
+ throw new Error(`${what}: the step needs "dir", the directory holding Pulumi.yaml`);
46
+ if (typeof a.stack !== "string" || a.stack === "" || a.stack.startsWith("-"))
47
+ throw new Error(`${what}: the step needs "stack", the stack to adopt`);
48
+ }
49
+ function refusalText(refusals) {
50
+ return refusals.map((r) => `${r.code}${r.urn ? ` (${r.urn})` : ""}: ${r.reason}`).join("; ");
51
+ }
52
+ /** The shared bucket check on the stack's backend bucket; throws when a setting fails unwaived. */
53
+ export async function adoptCheck(a, deps = {}) {
54
+ requireStack(a, "pulumiAdoptCheck");
55
+ const env = deps.env ?? process.env;
56
+ const dir = stackDir(a);
57
+ const base = { member: a.member, stack: a.stack };
58
+ let target;
59
+ let namespaces;
60
+ let waived;
61
+ if (a.bucket) {
62
+ target = a.bucket;
63
+ namespaces = a.namespaces ?? [];
64
+ waived = [...(env.PLUNGE_ALLOW_INSECURE ?? "").split(",").map((s) => s.trim()).filter(Boolean)];
65
+ }
66
+ else {
67
+ const backend = pulumiStackBackend(dir, { ...(a.backend ? { configured: a.backend } : {}), env });
68
+ if (!backend) {
69
+ throw new Error(`pulumiAdoptCheck: "${a.member}/${a.stack}" names no backend (the step's backend, plywood.yml, PULUMI_BACKEND_URL or Pulumi.yaml), so its bucket cannot be checked before adoption`);
70
+ }
71
+ const found = adoptBucketTarget(backend.url, env);
72
+ if ("skip" in found)
73
+ return { ...base, checked: false, skipped: found.skip, correct: true, waived: [] };
74
+ if ("refuse" in found)
75
+ throw new Error(`pulumiAdoptCheck: refusing to adopt "${a.member}/${a.stack}": ${found.refuse}`);
76
+ target = found.target;
77
+ namespaces = a.namespaces ?? found.namespaces;
78
+ waived = found.waived;
79
+ }
80
+ waived = [...new Set([...waived, ...(a.allowInsecure ?? [])])];
81
+ const check = deps.checkBucket ??
82
+ (async (t, o) => {
83
+ const mod = await import("@intentius/chant/bucket-check");
84
+ return mod.checkBucket(t, o);
85
+ });
86
+ const report = await check(target, { namespaces });
87
+ const failing = report.settings.filter((f) => f.verdict !== "ok");
88
+ const refused = failing.filter((f) => f.unwaivable || !waived.includes(f.setting));
89
+ if (refused.length > 0) {
90
+ const lines = refused.map((f) => `${f.setting} (${f.verdict}): ${f.found}${f.fix ? `; fix: ${f.fix}` : ""}${f.unwaivable ? "; no waiver reaches it" : ""}`);
91
+ throw new Error(`pulumiAdoptCheck: refusing to adopt "${a.member}/${a.stack}": the ${report.store} bucket ${report.bucket} fails the shared check: ${lines.join(" | ")}`);
92
+ }
93
+ return { ...base, checked: true, store: report.store, bucket: report.bucket, correct: report.correct, waived: failing.map((f) => f.setting) };
94
+ }
95
+ /** The stock checkpoint as a scratch file, or the given one. */
96
+ export async function adoptExport(a, deps = {}) {
97
+ requireStack(a, "pulumiAdoptExport");
98
+ const env = deps.env ?? process.env;
99
+ const dir = stackDir(a);
100
+ const base = { member: a.member, stack: a.stack };
101
+ const summarize = (text, file, source, adoptFromFile) => {
102
+ let doc;
103
+ try {
104
+ doc = JSON.parse(text);
105
+ }
106
+ catch {
107
+ throw new Error(`pulumiAdoptExport: the export of "${a.member}/${a.stack}" from ${source} is not JSON`);
108
+ }
109
+ const deployment = isObject(doc) && isObject(doc.deployment) ? doc.deployment : undefined;
110
+ const pending = deployment && Array.isArray(deployment.pending_operations) ? deployment.pending_operations.length : 0;
111
+ return {
112
+ ...base,
113
+ file,
114
+ sha256: createHash("sha256").update(text).digest("hex"),
115
+ resources: pulumiExportResources(doc).length,
116
+ pendingOperations: pending,
117
+ source,
118
+ adoptFromFile,
119
+ };
120
+ };
121
+ if (a.from?.file) {
122
+ const file = isAbsolute(a.from.file) ? a.from.file : resolve(dir, a.from.file);
123
+ if (!existsSync(file))
124
+ throw new Error(`pulumiAdoptExport: the export ${file} for "${a.member}/${a.stack}" does not exist`);
125
+ return summarize(readFileSync(file, "utf-8"), file, "file", true);
126
+ }
127
+ let source;
128
+ if (a.from?.backend) {
129
+ source = a.from.backend;
130
+ }
131
+ else {
132
+ const backend = pulumiStackBackend(dir, { ...(a.backend ? { configured: a.backend } : {}), env });
133
+ source = backend ? stockBackendUrl(backend.url) : undefined;
134
+ }
135
+ const args = ["stack", "export", "--stack", a.stack];
136
+ let stdout;
137
+ try {
138
+ ({ stdout } = await runAllowedPulumi(deps.run ?? defaultPulumiRunner, args, dir, source ? { PULUMI_BACKEND_URL: source } : undefined));
139
+ }
140
+ catch (err) {
141
+ const f = pulumiRunFailure(err);
142
+ const why = f.missingBinary ? "the pulumi binary was not found on PATH" : (f.stderr?.trim() || f.message).split("\n").slice(-3).join("\n");
143
+ throw new Error(`pulumiAdoptExport: pulumi ${args.join(" ")} for "${a.member}/${a.stack}"${source ? ` against ${source}` : ""} failed: ${why}`);
144
+ }
145
+ const scratch = mkdtempSync(join(deps.tmp ?? tmpdir(), "chant-pulumi-adopt-"));
146
+ const file = join(scratch, `${a.stack.replace(/[^A-Za-z0-9._-]+/g, "_")}.export.json`);
147
+ writeFileSync(file, stdout, { mode: 0o600 });
148
+ return summarize(stdout, file, source ?? "the selected backend", a.from?.backend !== undefined);
149
+ }
150
+ /** The adopt document from a run, its failure's stdout included; throws when there is none. */
151
+ async function adoptView(run, what, command) {
152
+ try {
153
+ const { stdout } = await run();
154
+ const view = parsePlungeAdoptView(stdout);
155
+ if (!view)
156
+ throw new Error(`${what}: ${command} printed no adopt document`);
157
+ return view;
158
+ }
159
+ catch (err) {
160
+ const f = pulumiRunFailure(err);
161
+ const view = parsePlungeAdoptView(f.stdout);
162
+ if (view)
163
+ return view;
164
+ if (err instanceof Error && err.message.startsWith(`${what}:`))
165
+ throw err;
166
+ const why = f.missingBinary ? "the plunge binary was not found on PATH" : (f.stderr?.trim() || f.message).split("\n").slice(-3).join("\n");
167
+ throw new Error(`${what}: ${command} failed: ${why}`);
168
+ }
169
+ }
170
+ function summary(a, view) {
171
+ return {
172
+ member: a.member,
173
+ stack: a.stack,
174
+ status: view.status,
175
+ planDigest: pulumiAdoptDigest(view),
176
+ checkpointDigest: view.checkpoint.digest ?? null,
177
+ resources: view.resources.length,
178
+ fates: adoptFates(view),
179
+ changed: view.status !== "already-adopted",
180
+ };
181
+ }
182
+ /** `plunge stack adopt --json`: the classification, written nowhere. A refusal fails the step. */
183
+ export async function adoptPreview(a, deps = {}) {
184
+ requireStack(a, "pulumiAdoptPreview");
185
+ const dir = stackDir(a);
186
+ const args = plungeAdoptArgs({ stack: a.stack, ...(a.file ? { file: a.file } : {}) });
187
+ const view = await adoptView(() => runAllowedPlunge(deps.plunge ?? defaultPlungeRunner, args, dir), "pulumiAdoptPreview", `plunge ${args.join(" ")}`);
188
+ if (view.status === "refused") {
189
+ throw new Error(`pulumiAdoptPreview: plunge refuses to adopt "${a.member}/${a.stack}": ${refusalText(view.refusals)}. Nothing was written.`);
190
+ }
191
+ return summary(a, view);
192
+ }
193
+ /** `plunge stack adopt --json --yes`: writes the records. A refusal fails the step; plunge wrote nothing then. */
194
+ export async function adoptStack(a, deps = {}) {
195
+ requireStack(a, "pulumiAdopt");
196
+ const dir = stackDir(a);
197
+ const args = plungeAdoptArgs({ stack: a.stack, yes: true, ...(a.file ? { file: a.file } : {}) });
198
+ const view = await adoptView(() => runAdoptPlunge(deps.plunge ?? defaultPlungeRunner, args, dir), "pulumiAdopt", `plunge ${args.join(" ")}`);
199
+ if (view.status === "refused") {
200
+ throw new Error(`pulumiAdopt: plunge refused to adopt "${a.member}/${a.stack}": ${refusalText(view.refusals)}. Nothing was written.`);
201
+ }
202
+ const out = summary(a, view);
203
+ return { ...out, ...(a.planDigest ? { matchesApproved: out.planDigest === a.planDigest } : {}) };
204
+ }
205
+ export async function pulumiAdoptCheck(args) {
206
+ return adoptCheck(args);
207
+ }
208
+ export async function pulumiAdoptExport(args) {
209
+ return adoptExport(args);
210
+ }
211
+ export async function pulumiAdoptPreview(args) {
212
+ return adoptPreview(args);
213
+ }
214
+ export async function pulumiAdopt(args) {
215
+ return adoptStack(args);
216
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"pulumi.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAgD,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAElG,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,oHAAoH;IACpH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyB/F;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmB3F"}
1
+ {"version":3,"file":"pulumi.d.ts","sourceRoot":"","sources":["../../../src/op/activities/pulumi.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAgD,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAElG,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,oHAAoH;IACpH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyB/F;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmB3F"}
@@ -7,7 +7,8 @@
7
7
  * already allow: `pulumi preview --json` (or `plunge preview --json`) and
8
8
  * `pulumi refresh --preview-only --json --target <urn>` (or `plunge drift
9
9
  * --resource <urn> --stream`). Neither changes the stack. There is no apply
10
- * activity, because chant never runs `pulumi up`.
10
+ * activity: a stack applies as a component step through the `pulumi-up`
11
+ * capability (`../../pulumi-up.ts`, #4541), the only caller of `up`.
11
12
  *
12
13
  * `dir` is the member's directory, where `Pulumi.yaml` is, resolved against
13
14
  * `cwd` (default: the process's working directory, the project root on a
@@ -31,4 +31,77 @@ export declare const pulumiDriftContract: import("@intentius/chant/op").Activity
31
31
  notObserved: number;
32
32
  records: number;
33
33
  }>;
34
+ export declare const pulumiAdoptCheckContract: import("@intentius/chant/op").ActivityContract<{
35
+ member: string;
36
+ dir: string;
37
+ cwd?: string | undefined;
38
+ stack: string;
39
+ backend?: string | undefined;
40
+ bucket?: Record<string, unknown> | undefined;
41
+ namespaces?: string[] | undefined;
42
+ allowInsecure?: string[] | undefined;
43
+ }, {
44
+ member: string;
45
+ stack: string;
46
+ checked: boolean;
47
+ skipped?: string | undefined;
48
+ store?: string | undefined;
49
+ bucket?: string | undefined;
50
+ correct: boolean;
51
+ waived: string[];
52
+ }>;
53
+ export declare const pulumiAdoptExportContract: import("@intentius/chant/op").ActivityContract<{
54
+ member: string;
55
+ dir: string;
56
+ cwd?: string | undefined;
57
+ stack: string;
58
+ backend?: string | undefined;
59
+ from?: {
60
+ backend?: string | undefined;
61
+ file?: string | undefined;
62
+ } | undefined;
63
+ }, {
64
+ member: string;
65
+ stack: string;
66
+ file: string;
67
+ sha256: string;
68
+ resources: number;
69
+ pendingOperations: number;
70
+ source: string;
71
+ adoptFromFile: boolean;
72
+ }>;
73
+ export declare const pulumiAdoptPreviewContract: import("@intentius/chant/op").ActivityContract<{
74
+ member: string;
75
+ dir: string;
76
+ cwd?: string | undefined;
77
+ stack: string;
78
+ file?: string | undefined;
79
+ }, {
80
+ member: string;
81
+ stack: string;
82
+ status: "adopted" | "already-adopted" | "refused" | "would-adopt";
83
+ planDigest: string;
84
+ checkpointDigest: string | null;
85
+ resources: number;
86
+ fates: Record<string, number>;
87
+ changed: boolean;
88
+ }>;
89
+ export declare const pulumiAdoptContract: import("@intentius/chant/op").ActivityContract<{
90
+ member: string;
91
+ dir: string;
92
+ cwd?: string | undefined;
93
+ stack: string;
94
+ file?: string | undefined;
95
+ planDigest?: string | undefined;
96
+ }, {
97
+ member: string;
98
+ stack: string;
99
+ status: "adopted" | "already-adopted" | "refused" | "would-adopt";
100
+ planDigest: string;
101
+ checkpointDigest: string | null;
102
+ resources: number;
103
+ fates: Record<string, number>;
104
+ changed: boolean;
105
+ matchesApproved?: boolean | undefined;
106
+ }>;
34
107
  //# sourceMappingURL=activity-contracts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../src/op/activity-contracts.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAiBjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;EAW/B,CAAC"}
1
+ {"version":3,"file":"activity-contracts.d.ts","sourceRoot":"","sources":["../../src/op/activity-contracts.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAiBjC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;EAW/B,CAAC;AAqBF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;EAoBpC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;EAkBrC,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;EAKtC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;EAK/B,CAAC"}