Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Changed artifact registry cleanup policy error to warn for CI/CD workloads #8513
- Enhance firebase init apphosting to support local source deploys. (#8479)
- Add GCP API client functions to support App Hosting deploy from source feature. (#8545)
18 changes: 17 additions & 1 deletion src/gcp/apphosting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
}

interface BuildSource {
codebase: CodebaseSource;
codebase?: CodebaseSource;
archive?: ArchiveSource;
}

interface CodebaseSource {
Expand All @@ -116,6 +117,21 @@
commitTime: string;
}

interface ArchiveSource {
// oneof reference
userStorageUri?: string;
externalSignedUri?: string;
// end oneof reference
rootDirectory?: string;
author?: SourceUserMetadata;
}

interface SourceUserMetadata {
displayName: string;
email: string;
imageUri: string;
}

interface Status {
code: number;
message: string;
Expand Down Expand Up @@ -250,7 +266,7 @@
done: boolean;
// oneof result
error?: Status;
response?: any;

Check warning on line 269 in src/gcp/apphosting.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
// end oneof result
}

Expand Down Expand Up @@ -532,14 +548,14 @@
/**
* Ensure that the App Hosting API is enabled on the project.
*/
export async function ensureApiEnabled(options: any): Promise<void> {

Check warning on line 551 in src/gcp/apphosting.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
const projectId = needProjectId(options);

Check warning on line 552 in src/gcp/apphosting.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `{ projectId?: string | undefined; project?: string | undefined; rc?: RC | undefined; }`
return await ensure(projectId, apphostingOrigin(), "app hosting", 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 558 in src/gcp/apphosting.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Expected @param names to be "projectId, location, backendId, counter". Got "counter"
*/
export async function getNextRolloutId(
projectId: string,
Expand Down
13 changes: 13 additions & 0 deletions src/gcp/devConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
metadata?: OperationMetadata;
done: boolean;
error?: { code: number; message: string; details: unknown };
response?: any;

Check warning on line 30 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
}

export interface OAuthCredential {
Expand Down Expand Up @@ -304,6 +304,19 @@
return res.body.installations;
}

/**
* Splits a Git Repository Link resource name into its parts.
*/
export function parseGitRepositoryLinkName(gitRepositoryLinkName: string): {
projectName: string;
location: string;
connectionName: string;
id: string;
} {
const [, projectName, , location, , connectionName, , id] = gitRepositoryLinkName.split("/");
return { projectName, location, connectionName, id };
}

/**
* Creates a GitRepositoryLink. Upon linking a Git Repository, Developer
* Connect will configure the Git Repository to send webhook events to
Expand Down Expand Up @@ -358,9 +371,9 @@
/**
* sorts the given list of connections by create_time from earliest to latest
*/
export function sortConnectionsByCreateTime(connections: Connection[]) {

Check warning on line 374 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
return connections.sort((a, b) => {
return Date.parse(a.createTime!) - Date.parse(b.createTime!);

Check warning on line 376 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion

Check warning on line 376 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
});
}

Expand Down Expand Up @@ -395,8 +408,8 @@
connection: string | null;
gitRepoLink: string | null;
} {
const connectionMatch = /connections\/([^\/]+)/.exec(path);

Check warning on line 411 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unnecessary escape character: \/
const repositoryMatch = /gitRepositoryLinks\/([^\/]+)/.exec(path);

Check warning on line 412 in src/gcp/devConnect.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unnecessary escape character: \/

const connection = connectionMatch ? connectionMatch[1] : null;
const gitRepoLink = repositoryMatch ? repositoryMatch[1] : null;
Expand Down
72 changes: 71 additions & 1 deletion src/gcp/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,28 @@ interface GetDefaultBucketResponse {
};
}

interface CreateBucketRequest {
name: string;
location: string;
lifecycle: {
rule: LifecycleRule[];
};
}

interface LifecycleRule {
action: {
type: string;
};
condition: {
age: number;
};
}

interface UploadObjectResponse {
selfLink: string;
mediaLink: string;
}

/** Response type for obtaining the storage service agent */
interface StorageServiceAccountResponse {
email_address: string;
Expand Down Expand Up @@ -230,7 +252,11 @@ export async function uploadObject(
source: { file: string; stream: Readable },
/** Bucket to upload to. */
bucketName: string,
): Promise<{ bucket: string; object: string; generation: string | null }> {
): Promise<{
bucket: string;
object: string;
generation: string | null;
}> {
if (path.extname(source.file) !== ".zip") {
throw new FirebaseError(`Expected a file name ending in .zip, got ${source.file}`);
}
Expand All @@ -252,6 +278,20 @@ export async function uploadObject(
};
}

/**
* Get a storage object from GCP.
* @param {string} bucketName name of the storage bucket that contains the object
* @param {string} objectName name of the object
*/
export async function getObject(
bucketName: string,
objectName: string,
): Promise<UploadObjectResponse> {
const client = new Client({ urlPrefix: storageOrigin() });
const res = await client.get<UploadObjectResponse>(`/storage/v1/b/${bucketName}/o/${objectName}`);
return res.body;
}

/**
* Deletes an object via Firebase Storage.
* @param {string} location A Firebase Storage location, of the form "/v0/b/<bucket>/o/<object>"
Expand Down Expand Up @@ -280,6 +320,36 @@ export async function getBucket(bucketName: string): Promise<BucketResponse> {
}
}

/**
* Creates a storage bucket on GCP.
* Ref: https://cloud.google.com/storage/docs/json_api/v1/buckets/insert
* @param {string} bucketName name of the storage bucket
* @return a bucket resource object
*/
export async function createBucket(
projectId: string,
req: CreateBucketRequest,
): Promise<BucketResponse> {
try {
const localAPIClient = new Client({ urlPrefix: storageOrigin() });
const result = await localAPIClient.post<CreateBucketRequest, BucketResponse>(
`/storage/v1/b`,
req,
{
queryParams: {
project: projectId,
},
},
);
return result.body;
} catch (err: any) {
logger.debug(err);
throw new FirebaseError("Failed to create the storage bucket", {
original: err,
});
}
}

/**
* Gets the list of storage buckets associated with a specific project from GCP.
* Ref: https://cloud.google.com/storage/docs/json_api/v1/buckets/list
Expand Down
Loading