Skip to content

Commit 916fc34

Browse files
authored
Create build and update traffic during backends:create (#6611)
After creating a build via the "backends:create" command, follow up by creating a new build and updating the traffic setting to the newly created build. This allows users to access their newly created site without having to manually trigger a rollout themselves.
1 parent d56766a commit 916fc34

File tree

2 files changed

+304
-35
lines changed

2 files changed

+304
-35
lines changed

src/gcp/apphosting.ts

Lines changed: 206 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as proto from "../gcp/proto";
12
import { Client } from "../apiv2";
23
import { needProjectId } from "../projectUtils";
34
import { apphostingOrigin } from "../api";
@@ -12,7 +13,7 @@ const client = new Client({
1213
apiVersion: API_VERSION,
1314
});
1415

15-
type State = "BUILDING" | "BUILD" | "DEPLOYING" | "READY" | "FAILED";
16+
type BuildState = "BUILDING" | "BUILD" | "DEPLOYING" | "READY" | "FAILED";
1617

1718
interface Codebase {
1819
repository?: string;
@@ -43,36 +44,183 @@ export type BackendOutputOnlyFields = "name" | "createTime" | "updateTime" | "ur
4344

4445
export interface Build {
4546
name: string;
46-
state: State;
47+
state: BuildState;
4748
error: Status;
4849
image: string;
50+
config?: BuildConfig;
4951
source: BuildSource;
50-
buildLogsUri: string;
51-
createTime: Date;
52-
updateTime: Date;
5352
sourceRef: string;
53+
buildLogsUri?: string;
54+
displayName?: string;
55+
labels?: Record<string, string>;
56+
annotations?: Record<string, string>;
57+
uuid: string;
58+
etag: string;
59+
reconciling: boolean;
60+
createTime: string;
61+
updateTime: string;
62+
deleteTime: string;
5463
}
5564

56-
export type BuildOutputOnlyFields = "createTime" | "updateTime" | "sourceRef";
65+
export type BuildOutputOnlyFields =
66+
| "state"
67+
| "error"
68+
| "image"
69+
| "sourceRef"
70+
| "buildLogUri"
71+
| "reconciling"
72+
| "uuid"
73+
| "etag"
74+
| "createTime"
75+
| "updateTime"
76+
| "deleteTime";
77+
78+
export interface BuildConfig {
79+
minInstances?: number;
80+
memory?: string;
81+
}
5782

5883
interface BuildSource {
59-
codeBaseSource?: CodebaseSource;
84+
codebase: CodebaseSource;
6085
}
6186

87+
interface CodebaseSource {
88+
// oneof reference
89+
branch?: string;
90+
commit?: string;
91+
tag?: string;
92+
// end oneof reference
93+
displayName: string;
94+
hash: string;
95+
commitMessage: string;
96+
uri: string;
97+
commitTime: string;
98+
}
99+
100+
export type CodebaseSourceOutputOnlyFields =
101+
| "displayName"
102+
| "hash"
103+
| "commitMessage"
104+
| "uri"
105+
| "commitTime";
106+
107+
export type BuildInput = Omit<Build, BuildOutputOnlyFields | "source"> & {
108+
source: Omit<BuildSource, "codebase"> & {
109+
codebase: Omit<CodebaseSource, CodebaseSourceOutputOnlyFields>;
110+
};
111+
};
112+
62113
interface Status {
63114
code: number;
64115
message: string;
65-
details: any[];
116+
details: unknown;
66117
}
67118

68-
interface CodebaseSource {
69-
// oneof reference
70-
branch: string;
71-
commit: string;
72-
tag: string;
73-
// end oneof reference
119+
type RolloutState =
120+
| "STATE_UNSPECIFIED"
121+
| "QUEUED"
122+
| "PENDING_BUILD"
123+
| "PROGRESSING"
124+
| "PAUSED"
125+
| "SUCCEEDED"
126+
| "FAILED"
127+
| "CANCELLED";
128+
129+
export interface Rollout {
130+
name: string;
131+
state: RolloutState;
132+
paused?: boolean;
133+
pauseTime: string;
134+
error?: Error;
135+
build: string;
136+
stages?: RolloutStage[];
137+
displayName?: string;
138+
createTime: string;
139+
updateTime: string;
140+
deleteTime?: string;
141+
purgeTime?: string;
142+
labels?: Record<string, string>;
143+
annotations?: Record<string, string>;
144+
uid: string;
145+
etag: string;
146+
reconciling: boolean;
147+
}
148+
149+
export type RolloutOutputOnlyFields =
150+
| "state"
151+
| "pauseTime"
152+
| "createTime"
153+
| "updateTime"
154+
| "deleteTime"
155+
| "purgeTime"
156+
| "uid"
157+
| "etag"
158+
| "reconciling";
159+
160+
export interface Traffic {
161+
name: string;
162+
// oneof traffic_management
163+
target?: TrafficSet;
164+
rolloutPolicy?: RolloutPolicy;
165+
// end oneof traffic_management
166+
current: TrafficSet;
167+
reconciling: boolean;
168+
createTime: string;
169+
updateTime: string;
170+
annotations?: Record<string, string>;
171+
etag: string;
172+
uid: string;
173+
}
174+
175+
export type TrafficOutputOnlyFields =
176+
| "current"
177+
| "reconciling"
178+
| "createTime"
179+
| "updateTime"
180+
| "etag"
181+
| "uid";
182+
183+
export interface TrafficSet {
184+
splits: TrafficSplit[];
185+
}
186+
187+
export interface TrafficSplit {
188+
build: string;
189+
percent: number;
190+
}
191+
192+
export interface RolloutPolicy {
193+
// oneof trigger
194+
codebaseBranch?: string;
195+
codebaseTagPattern?: string;
196+
// end oneof trigger
197+
stages?: RolloutStage[];
198+
disabled?: boolean;
199+
disabledTime: string;
200+
}
201+
202+
export type RolloutPolicyOutputOnlyFields = "disabledtime";
203+
204+
export type RolloutProgression =
205+
| "PROGRESSION_UNSPECIFIED"
206+
| "IMMEDIATE"
207+
| "LINEAR"
208+
| "EXPONENTIAL"
209+
| "PAUSE";
210+
211+
export interface RolloutStage {
212+
progression: RolloutProgression;
213+
duration?: {
214+
seconds: number;
215+
nanos: number;
216+
};
217+
targetPercent?: number;
218+
startTime: string;
219+
endTime: string;
74220
}
75221

222+
export type RolloutStageOutputOnlyFields = "startTime" | "endTime";
223+
76224
interface OperationMetadata {
77225
createTime: string;
78226
endTime: string;
@@ -162,15 +310,56 @@ export async function createBuild(
162310
projectId: string,
163311
location: string,
164312
backendId: string,
165-
buildInput: Omit<Build, BuildOutputOnlyFields>
313+
buildId: string,
314+
buildInput: Omit<BuildInput, "name">
166315
): Promise<Operation> {
167-
const buildId = buildInput.name;
168-
const res = await client.post<Omit<Build, BuildOutputOnlyFields>, Operation>(
316+
const res = await client.post<Omit<BuildInput, "name">, Operation>(
169317
`projects/${projectId}/locations/${location}/backends/${backendId}/builds`,
170318
buildInput,
171319
{ queryParams: { buildId } }
172320
);
321+
return res.body;
322+
}
173323

324+
/**
325+
* Create a new rollout for a backend
326+
*/
327+
export async function createRollout(
328+
projectId: string,
329+
location: string,
330+
backendId: string,
331+
rolloutId: string,
332+
rollout: Omit<Rollout, RolloutOutputOnlyFields | "name">
333+
): Promise<Operation> {
334+
const res = await client.post<Omit<Rollout, RolloutOutputOnlyFields | "name">, Operation>(
335+
`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`,
336+
rollout,
337+
{ queryParams: { rolloutId } }
338+
);
339+
return res.body;
340+
}
341+
342+
/**
343+
* Update traffic of a backend
344+
*/
345+
export async function updateTraffic(
346+
projectId: string,
347+
location: string,
348+
backendId: string,
349+
traffic: Omit<Traffic, TrafficOutputOnlyFields | "name">
350+
): Promise<Operation> {
351+
const fieldMasks = proto.fieldMasks(traffic);
352+
const queryParams = {
353+
updateMask: fieldMasks.join(","),
354+
};
355+
const name = `projects/${projectId}/locations/${location}/backends/${backendId}/traffic`;
356+
const res = await client.patch<Omit<Traffic, TrafficOutputOnlyFields>, Operation>(
357+
name,
358+
{ ...traffic, name },
359+
{
360+
queryParams,
361+
}
362+
);
174363
return res.body;
175364
}
176365

0 commit comments

Comments
 (0)