1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5/**
6 * Git links need a connection whose GitHub App install is COMPLETE; a fresh
7 * connection stays PENDING_USER_OAUTH and link create fails with BadRequest
8 * ("connection must have installation_state COMPLETE"). Set
9 * `GCP_TEST_DEVELOPERCONNECT_GITHUB_TOKEN_SECRET` (OAuth token secret
10 * version) and `GCP_TEST_DEVELOPERCONNECT_GITHUB_INSTALLATION_ID` to run.
11 * The values are forwarded to the host's environment so the deployed
12 * runtime binds the same set.
13 */
14const githubTokenSecret =
15 process.env.GCP_TEST_DEVELOPERCONNECT_GITHUB_TOKEN_SECRET ?? "";
16const githubInstallationId =
17 process.env.GCP_TEST_DEVELOPERCONNECT_GITHUB_INSTALLATION_ID ?? "";
18export const linkEnabled = !!githubTokenSecret && !!githubInstallationId;
19
20const cloneUri =
21 process.env.GCP_DEVELOPERCONNECT_CLONE_URI ??
22 "https://github.com/octocat/Hello-World.git";
23
24/** GitHub connection; declared only when {@link linkEnabled}. */
25export const Github = GCP.DeveloperConnect.Connection("Github", {
26 githubConfig: {
27 githubApp: "DEVELOPER_CONNECT",
28 authorizerCredential: { oauthTokenSecretVersion: githubTokenSecret },
29 appInstallationId: githubInstallationId,
30 },
31});
32
33/** Repository link the bindings bind; declared only when {@link linkEnabled}. */
34export const Source = Effect.gen(function* () {
35 const github = yield* Github;
36 return yield* GCP.DeveloperConnect.ConnectionsGitRepositoryLink("Source", {
37 connection: github.name,
38 cloneUri,
39 });
40});
41
42const linkProbes = Effect.gen(function* () {
43 const fetchReadToken = yield* GCP.DeveloperConnect.FetchReadToken(Source);
44 const fetchReadWriteToken =
45 yield* GCP.DeveloperConnect.FetchReadWriteToken(Source);
46 const fetchGitRefs = yield* GCP.DeveloperConnect.FetchGitRefs(Source);
47 return {
48 fetchReadToken: fetchReadToken().pipe(
49 Effect.map((read) => ({ hasToken: !!read.token })),
50 ),
51 fetchReadWriteToken: fetchReadWriteToken().pipe(
52 Effect.map((write) => ({ hasToken: !!write.token })),
53 ),
54 fetchGitRefs: fetchGitRefs({ refType: "BRANCH" }),
55 };
56});
57
58/**
59 * Effect-native Cloud Run service exercising every Developer Connect binding
60 * as its own runtime service account. Deployed from
61 * {@link ../Bindings.test.ts}.
62 */
63export default class DeveloperConnectBindingsHost extends GCP.Function<DeveloperConnectBindingsHost>()(
64 "DeveloperConnectBindingsHost",
65 {
66 main: import.meta.url,
67 invokerIamDisabled: true,
68 env: {
69 GCP_TEST_DEVELOPERCONNECT_GITHUB_TOKEN_SECRET: githubTokenSecret,
70 GCP_TEST_DEVELOPERCONNECT_GITHUB_INSTALLATION_ID: githubInstallationId,
71 GCP_DEVELOPERCONNECT_CLONE_URI: cloneUri,
72 },
73 },
74 Effect.gen(function* () {
75 const link = linkEnabled ? yield* linkProbes : {};
76 return { fetch: serveProbes({ ...link }) };
77 }).pipe(
78 Effect.provide(GCP.DeveloperConnect.FetchReadTokenHttp),
79 Effect.provide(GCP.DeveloperConnect.FetchReadWriteTokenHttp),
80 Effect.provide(GCP.DeveloperConnect.FetchGitRefsHttp),
81 ),
82) {}