1import { GcpEnvironment } from "@/GCP/Environment";
2import * as GCP from "@/GCP";
3import * as Test from "@/Test/Alchemy";
4import * as deploymentmanager from "@distilled.cloud/gcp/deploymentmanager_v2";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import { MinimumLogLevel } from "effect/References";
8import * as Schedule from "effect/Schedule";
9
10const { test } = Test.make({ providers: GCP.providers() });
11
12const logLevel = Effect.provideService(
13 MinimumLogLevel,
14 process.env.DEBUG ? "Debug" : "Info",
15);
16
17const waitUntilGone = (deployment: string) =>
18 GcpEnvironment.current.pipe(
19 Effect.flatMap(({ project }) =>
20 deploymentmanager.getDeployments({ project, deployment }),
21 ),
22 Effect.as("found" as const),
23 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
24 Effect.repeat({
25 schedule: Schedule.spaced("2 seconds"),
26 until: (status) => status === "gone",
27 times: 10,
28 }),
29 );
30
31const target = {
32 config: {
33 content: `imports:
34- path: topic.jinja
35resources:
36- name: topic
37 type: topic.jinja
38`,
39 },
40 imports: [
41 {
42 name: "topic.jinja",
43 content: `resources:
44- name: topic
45 type: pubsub.v1.topic
46 properties:
47 topic: {{ env["deployment"] }}
48`,
49 },
50 ],
51};
52
53test.provider(
54 "getDeployments on a missing deployment fails with a typed tag",
55 (stack) =>
56 Effect.gen(function* () {
57 const { project } = yield* GcpEnvironment.current;
58
59 yield* stack.destroy();
60
61 const error = yield* Effect.flip(
62 deploymentmanager.getDeployments({
63 project,
64 deployment: "alchemy-missing-deployment",
65 }),
66 );
67 expect(error._tag).toEqual("NotFound");
68
69 yield* stack.destroy();
70 }).pipe(logLevel),
71 {
72 tags: ["provider:gcp", "provider:gcp:deploymentmanager", "live"],
73 timeout: 90_000,
74 },
75);
76
77test.provider(
78 "create, update, and delete a deployment",
79 (stack) =>
80 Effect.gen(function* () {
81 const { project } = yield* GcpEnvironment.current;
82
83 yield* stack.destroy();
84
85 const created = yield* stack.deploy(
86 Effect.gen(function* () {
87 return yield* GCP.DeploymentManager.Deployment("App", {
88 description: "alchemy dm test",
89 labels: { env: "test" },
90 target,
91 });
92 }),
93 );
94
95 expect(created.name).toEqual(expect.any(String));
96 expect(created.deploymentId).toEqual(created.name);
97 expect(created.project).toEqual(project);
98 expect(created.description).toEqual("alchemy dm test");
99 expect(created.labels).toMatchObject({ env: "test" });
100 expect(created.preview).toEqual(false);
101
102 const fetched = yield* deploymentmanager.getDeployments({
103 project,
104 deployment: created.name,
105 });
106 expect(fetched.name).toEqual(created.name);
107 const fetchedLabels = Object.fromEntries(
108 (fetched.labels ?? [])
109 .filter(
110 (entry): entry is { key: string; value: string } =>
111 typeof entry.key === "string" && typeof entry.value === "string",
112 )
113 .map((entry) => [entry.key, entry.value]),
114 );
115 expect(fetchedLabels.env).toEqual("test");
116 expect(fetchedLabels["alchemy-id"]).toEqual(expect.any(String));
117
118 const updated = yield* stack.deploy(
119 Effect.gen(function* () {
120 return yield* GCP.DeploymentManager.Deployment("App", {
121 deploymentId: created.deploymentId,
122 description: "alchemy dm test updated",
123 labels: { env: "prod", role: "events" },
124 target,
125 });
126 }),
127 );
128
129 expect(updated.name).toEqual(created.name);
130 expect(updated.deploymentId).toEqual(created.deploymentId);
131 expect(updated.description).toEqual("alchemy dm test updated");
132 expect(updated.labels).toMatchObject({ env: "prod", role: "events" });
133
134 const fetchedUpdate = yield* deploymentmanager.getDeployments({
135 project,
136 deployment: created.name,
137 });
138 expect(fetchedUpdate.description).toEqual("alchemy dm test updated");
139
140 yield* stack.destroy();
141
142 const gone = yield* waitUntilGone(created.name);
143 expect(gone).toEqual("gone");
144 }).pipe(logLevel),
145 {
146 tags: ["provider:gcp", "provider:gcp:deploymentmanager", "live"],
147 timeout: 90_000,
148 },
149);