Skip to content

Commit

Permalink
Git to cloud build (#6044)
Browse files Browse the repository at this point in the history
* Initial commit integrate init with api

* Revert "Initial commit integrate init with api"

This reverts commit 1475151.

* removed internaltesting:frameworks:int command

* integrate git repo with cloudBuildRepo

* Added changes to create stack

* Added changes to create stack

* Added code to omit output fields in Stack

* Added poller operation

* Added poller operation

* Added code to integrate init flow to link Git repo and to call frameworks api

* Minor changes

* minor changes

* deleted output file

* Rearranged files

* Fix imports

* Reorganized files

* minor changes
  • Loading branch information
svnsairam authored Jun 29, 2023
1 parent 9f14838 commit 57dd7fe
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 33 deletions.
2 changes: 0 additions & 2 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,6 @@ export function load(client: any): any {
client.internaltesting.frameworks.compose = loadCommand("internaltesting-frameworks-compose");
client.internaltesting.functions = {};
client.internaltesting.functions.discover = loadCommand("internaltesting-functions-discover");
client.internaltesting.frameworks = {};
client.internaltesting.frameworks.init = loadCommand("internaltesting-frameworks-init");
}
client.login = loadCommand("login");
client.login.add = loadCommand("login-add");
Expand Down
14 changes: 0 additions & 14 deletions src/commands/internaltesting-frameworks-init.ts

This file was deleted.

24 changes: 13 additions & 11 deletions src/api/frameworks.ts → src/gcp/frameworks.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { Client } from "../apiv2";
import { frameworksOrigin } from "../api";

export const API_VERSION = "v1";
export const API_VERSION = "v2";

const client = new Client({
urlPrefix: frameworksOrigin,
auth: true,
apiVersion: API_VERSION,
});

export type State = "BUILDING" | "BUILD" | "DEPLOYING" | "READY" | "FAILED";
type State = "BUILDING" | "BUILD" | "DEPLOYING" | "READY" | "FAILED";

interface Codebase {
repository?: string;
rootDirectory: string;
}

/** A Stack, the primary resource of Frameworks. */
interface Stack {
export interface Stack {
name: string;
mode?: string;
codebase: Codebase;
Expand All @@ -29,7 +29,7 @@ interface Stack {

export type StackOutputOnlyFields = "createTime" | "updateTime" | "uri";

interface Build {
export interface Build {
name: string;
state: State;
error: Status;
Expand Down Expand Up @@ -61,7 +61,7 @@ interface CodebaseSource {
// end oneof reference
}

export interface OperationMetadata {
interface OperationMetadata {
createTime: string;
endTime: string;
target: string;
Expand All @@ -87,14 +87,15 @@ export interface Operation {
export async function createStack(
projectId: string,
location: string,
stackId: string,
stack: Stack
stackInput: Omit<Stack, StackOutputOnlyFields>
): Promise<Operation> {
const stackId = stackInput.name;
const res = await client.post<Omit<Stack, StackOutputOnlyFields>, Operation>(
`projects/${projectId}/locations/${location}/stacks`,
stack,
stackInput,
{ queryParams: { stackId } }
);

return res.body;
}

Expand All @@ -105,13 +106,14 @@ export async function createBuild(
projectId: string,
location: string,
stackId: string,
buildId: string,
build: Build
buildInput: Omit<Build, BuildOutputOnlyFields>
): Promise<Operation> {
const buildId = buildInput.name;
const res = await client.post<Omit<Build, BuildOutputOnlyFields>, Operation>(
`projects/${projectId}/locations/${location}/stacks/${stackId}/builds`,
build,
buildInput,
{ queryParams: { buildId } }
);

return res.body;
}
53 changes: 53 additions & 0 deletions src/init/features/frameworks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,26 @@ import {
DEFAULT_DEPLOY_METHOD,
ALLOWED_DEPLOY_METHODS,
} from "./constants";
import { linkGitHubRepository } from "./repo";
import { Stack, StackOutputOnlyFields } from "../../../gcp/frameworks";
import { Repository } from "../../../gcp/cloudbuild";
import * as poller from "../../../operation-poller";
import { frameworksOrigin } from "../../../api";
import * as gcp from "../../../gcp/frameworks";
import { API_VERSION } from "../../../gcp/frameworks";

const frameworksPollerOptions: Omit<poller.OperationPollerOptions, "operationResourceName"> = {
apiOrigin: frameworksOrigin,
apiVersion: API_VERSION,
masterTimeout: 25 * 60 * 1_000,
maxBackoff: 10_000,
};

/**
* Setup new frameworks project.
*/
export async function doSetup(setup: any): Promise<void> {
const projectId: string = setup?.rcfile?.projects?.default;
setup.frameworks = {};

utils.logBullet("First we need a few details to create your service.");
Expand Down Expand Up @@ -54,4 +69,42 @@ export async function doSetup(setup: any): Promise<void> {
},
setup.frameworks
);

if (setup.frameworks.deployMethod === "github") {
const cloudBuildConnRepo = await linkGitHubRepository(
projectId,
setup.frameworks.region,
setup.frameworks.serviceName
);
toStack(cloudBuildConnRepo, setup.frameworks.serviceName);
}
}

function toStack(
cloudBuildConnRepo: Repository,
stackId: string
): Omit<Stack, StackOutputOnlyFields> {
return {
name: stackId,
codebase: { repository: cloudBuildConnRepo.name, rootDirectory: "/" },
labels: {},
};
}

/**
* Creates Stack object from long running operations.
*/
export async function createStack(
projectId: string,
location: string,
stackInput: Omit<Stack, StackOutputOnlyFields>
): Promise<Stack> {
const op = await gcp.createStack(projectId, location, stackInput);
const stack = await poller.pollOperation<Stack>({
...frameworksPollerOptions,
pollerName: `create-${projectId}-${location}-${stackInput.name}`,
operationResourceName: op.name,
});

return stack;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ function extractRepoSlugFromURI(remoteUri: string): string | undefined {
return match[1];
}

function generateConnectionId(stackId: string): string {
return `composer-${stackId}-conn`;
}

/**
* Generates a repository ID.
* N.B. The deterministic nature of the repository ID implies that each
Expand All @@ -48,7 +44,7 @@ export async function linkGitHubRepository(
location: string,
stackId: string
): Promise<gcb.Repository> {
const connectionId = generateConnectionId(stackId);
const connectionId = stackId;
await getOrCreateConnection(projectId, location, connectionId);

let remoteUri = await promptRepositoryURI(projectId, location, connectionId);
Expand Down
61 changes: 61 additions & 0 deletions src/test/init/frameworks/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as sinon from "sinon";
import { expect } from "chai";

import * as gcp from "../../../gcp/frameworks";
import * as poller from "../../../operation-poller";
import { createStack } from "../../../init/features/frameworks/index";

describe("operationsConverter", () => {
const sandbox: sinon.SinonSandbox = sinon.createSandbox();

let pollOperationStub: sinon.SinonStub;
let createStackStub: sinon.SinonStub;

beforeEach(() => {
pollOperationStub = sandbox
.stub(poller, "pollOperation")
.throws("Unexpected pollOperation call");
createStackStub = sandbox.stub(gcp, "createStack").throws("Unexpected createStack call");
});

afterEach(() => {
sandbox.verifyAndRestore();
});

describe("createStack", () => {
const projectId = "projectId";
const location = "us-central1";
const stackId = "stackId";
const stackInput = {
name: stackId,
codebase: {
repository: `projects/${projectId}/locations/${location}/connections/${stackId}`,
rootDirectory: "/",
},
labels: {},
};
const op = {
name: `projects/${projectId}/locations/${location}/stacks/${stackId}`,
done: true,
};
const completeStack = {
name: `projects/${projectId}/locations/${location}/stacks/${stackId}`,
codebase: {
repository: `projects/${projectId}/locations/${location}/connections/${stackId}`,
rootDirectory: "/",
},
labels: {},
createTime: "0",
updateTime: "1",
uri: "https://placeholder.com",
};

it("checks is correct arguments are sent & creates a stack", async () => {
createStackStub.resolves(op);
pollOperationStub.resolves(completeStack);

await createStack(projectId, location, stackInput);
expect(createStackStub).to.be.calledWith(projectId, location, stackInput);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as gcb from "../../../gcp/cloudbuild";
import * as prompt from "../../../prompt";
import * as poller from "../../../operation-poller";
import { FirebaseError } from "../../../error";
import * as repo from "../../../init/features/composer/repo";
import * as repo from "../../../init/features/frameworks/repo";
import * as utils from "../../../utils";

describe("composer", () => {
Expand Down

0 comments on commit 57dd7fe

Please sign in to comment.