-
Notifications
You must be signed in to change notification settings - Fork 901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FAH uses ids using the same naming policy as rolloutPolicy #6743
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
788ef07
FAH uses ids using the same naming policy as rolloutPolicy
inlined 988a836
lint fixes
inlined 1dcecd8
s/getNextBuildId/getNextRolloutId
inlined 42b9278
Pad build incrementer per offline chat
inlined a2ac032
Fix pagination and padding
inlined 28c1bb3
Remove unused function. Fix style issues
inlined 3bfd6f8
Merge branch 'master' into inlined.initial-rollout
inlined 2ab3db1
PR feedback
inlined acabd18
I can't get 'satisfies' to help me avoid stupidity
inlined File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,12 @@ | |
import { apphostingOrigin } from "../api"; | ||
import { ensure } from "../ensureApiEnabled"; | ||
import * as deploymentTool from "../deploymentTool"; | ||
import { FirebaseError } from "../error"; | ||
|
||
export const API_HOST = new URL(apphostingOrigin).host; | ||
export const API_VERSION = "v1alpha"; | ||
|
||
const client = new Client({ | ||
export const client = new Client({ | ||
urlPrefix: apphostingOrigin, | ||
auth: true, | ||
apiVersion: API_VERSION, | ||
|
@@ -63,6 +64,12 @@ | |
deleteTime: string; | ||
} | ||
|
||
export interface ListBuildsResponse { | ||
builds: Build[]; | ||
nextPageToken?: string; | ||
unreachable?: string[]; | ||
} | ||
|
||
export type BuildOutputOnlyFields = | ||
| "state" | ||
| "error" | ||
|
@@ -158,6 +165,12 @@ | |
| "etag" | ||
| "reconciling"; | ||
|
||
export interface ListRolloutsResponse { | ||
rollouts: Rollout[]; | ||
unreachable: string[]; | ||
nextPageToken?: string; | ||
} | ||
|
||
export interface Traffic { | ||
name: string; | ||
// oneof traffic_management | ||
|
@@ -248,7 +261,7 @@ | |
done: boolean; | ||
// oneof result | ||
error?: Status; | ||
response?: any; | ||
// end oneof result | ||
} | ||
|
||
|
@@ -334,6 +347,33 @@ | |
return res.body; | ||
} | ||
|
||
/** | ||
* List Builds by backend | ||
*/ | ||
export async function listBuilds( | ||
projectId: string, | ||
location: string, | ||
backendId: string, | ||
): Promise<ListBuildsResponse> { | ||
const name = `projects/${projectId}/locations/${location}/backends/${backendId}/builds`; | ||
let pageToken: string | undefined; | ||
const res: ListBuildsResponse = { | ||
builds: [], | ||
unreachable: [], | ||
}; | ||
|
||
do { | ||
const queryParams: Record<string, string> = pageToken ? { pageToken } : {}; | ||
const int = await client.get<ListBuildsResponse>(name, { queryParams }); | ||
res.builds.push(...(int.body.builds || [])); | ||
res.unreachable?.push(...(int.body.unreachable || [])); | ||
pageToken = int.body.nextPageToken; | ||
} while (pageToken); | ||
|
||
res.unreachable = [...new Set(res.unreachable)]; | ||
return res; | ||
} | ||
|
||
/** | ||
* Creates a new Build in a given project and location. | ||
*/ | ||
|
@@ -389,11 +429,24 @@ | |
projectId: string, | ||
location: string, | ||
backendId: string, | ||
): Promise<Rollout[]> { | ||
const res = await client.get<{ rollouts: Rollout[] }>( | ||
`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`, | ||
); | ||
return res.body.rollouts; | ||
): Promise<ListRolloutsResponse> { | ||
const name = `projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`; | ||
let pageToken: string | undefined = undefined; | ||
const res: ListRolloutsResponse = { | ||
rollouts: [], | ||
unreachable: [], | ||
}; | ||
|
||
do { | ||
const queryParams: Record<string, string> = pageToken ? { pageToken } : {}; | ||
const int = await client.get<ListRolloutsResponse>(name, { queryParams }); | ||
res.rollouts.splice(res.rollouts.length, 0, ...(int.body.rollouts || [])); | ||
res.unreachable.splice(res.unreachable.length, 0, ...(int.body.unreachable || [])); | ||
pageToken = int.body.nextPageToken; | ||
} while (pageToken); | ||
|
||
res.unreachable = [...new Set(res.unreachable)]; | ||
return res; | ||
} | ||
|
||
/** | ||
|
@@ -410,7 +463,7 @@ | |
// correct. | ||
const trafficCopy = { ...traffic }; | ||
if ("rolloutPolicy" in traffic) { | ||
trafficCopy.rolloutPolicy = {} as any; | ||
Check warning on line 466 in src/gcp/apphosting.ts GitHub Actions / lint (20)
|
||
} | ||
const fieldMasks = proto.fieldMasks(trafficCopy); | ||
const queryParams = { | ||
|
@@ -441,10 +494,13 @@ | |
* Lists information about the supported locations. | ||
*/ | ||
export async function listLocations(projectId: string): Promise<Location[]> { | ||
let pageToken; | ||
let pageToken: string | undefined = undefined; | ||
let locations: Location[] = []; | ||
do { | ||
const response = await client.get<ListLocationsResponse>(`projects/${projectId}/locations`); | ||
const queryParams: Record<string, string> = pageToken ? { pageToken } : {}; | ||
const response = await client.get<ListLocationsResponse>(`projects/${projectId}/locations`, { | ||
queryParams, | ||
}); | ||
if (response.body.locations && response.body.locations.length > 0) { | ||
locations = locations.concat(response.body.locations); | ||
} | ||
|
@@ -456,7 +512,56 @@ | |
/** | ||
* Ensure that Frameworks API is enabled on the project. | ||
*/ | ||
export async function ensureApiEnabled(options: any): Promise<void> { | ||
const projectId = needProjectId(options); | ||
return await ensure(projectId, API_HOST, "frameworks", true); | ||
} | ||
|
||
/** | ||
* Generates the next build ID to fit with the naming scheme of the backend API. | ||
* @param counter Overrides the counter to use, avoiding an API call. | ||
Check warning on line 522 in src/gcp/apphosting.ts GitHub Actions / lint (20)
|
||
*/ | ||
export async function getNextRolloutId( | ||
projectId: string, | ||
location: string, | ||
backendId: string, | ||
counter?: number, | ||
): Promise<string> { | ||
const date = new Date(); | ||
const year = date.getUTCFullYear(); | ||
// Note: month is 0 based in JS | ||
const month = String(date.getUTCMonth() + 1).padStart(2, "0"); | ||
const day = String(date.getUTCDay()).padStart(2, "0"); | ||
|
||
if (counter) { | ||
return `build-${year}-${month}-${day}-${String(counter).padStart(3, "0")}`; | ||
} | ||
|
||
// Note: must use exports here so that listRollouts can be stubbed in tests. | ||
const builds = await (exports as { listRollouts: typeof listRollouts }).listRollouts( | ||
projectId, | ||
location, | ||
backendId, | ||
); | ||
if (builds.unreachable?.includes(location)) { | ||
throw new FirebaseError( | ||
`Firebase App Hosting is currently unreachable in location ${location}`, | ||
); | ||
} | ||
|
||
let highest = 0; | ||
const test = new RegExp( | ||
`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts/build-${year}-${month}-${day}-(\\d+)`, | ||
); | ||
for (const rollout of builds.rollouts) { | ||
const match = rollout.name.match(test); | ||
if (!match) { | ||
continue; | ||
} | ||
const n = Number(match[1]); | ||
if (n > highest) { | ||
highest = n; | ||
} | ||
} | ||
return `build-${year}-${month}-${day}-${String(highest + 1).padStart(3, "0")}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, but
exports.listRollouts
gives you type errors or something? That's unfortunate :(