Skip to content

Commit

Permalink
Methods to interact with BuildEngine
Browse files Browse the repository at this point in the history
  • Loading branch information
FyreByrd committed Oct 1, 2024
1 parent 3dd3423 commit c3b0bb7
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 0 deletions.
2 changes: 2 additions & 0 deletions source/SIL.AppBuilder.Portal/common/build-engine-api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * as Types from './types.js';
export * as Requests from './requests.js';
157 changes: 157 additions & 0 deletions source/SIL.AppBuilder.Portal/common/build-engine-api/requests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import prisma from '../prisma.js';
import * as Types from './types.js';

export async function request(
resource: string,
organizationId: number,
method: string = 'GET',
body?: any
) {
const { url, token } = await getURLandToken(organizationId);
return await fetch(`${url}/${resource}`, {
method: method,
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json'
},
body: body ? JSON.stringify(body) : undefined
});
}
export async function getURLandToken(organizationId: number) {
const org = await prisma.organizations.findUnique({
where: {
Id: organizationId
},
select: {
BuildEngineUrl: true,
BuildEngineApiAccessToken: true
}
});

return { url: org.BuildEngineUrl, token: org.BuildEngineApiAccessToken };
}

export async function systemCheck(organizationId: number) {
return (await request('system/check', organizationId)).status;
}

export async function createProject(
organizationId: number,
project: Types.ProjectConfig
): Promise<Types.ProjectResponse | Types.ErrorResponse> {
const res = await request('project', organizationId, 'POST', project);
return res.ok ? ((await res.json()) as Types.ProjectResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function getProjects(
organizationId: number
): Promise<Types.ProjectResponse[] | Types.ErrorResponse> {
const res = await request('project', organizationId);
return res.ok ? ((await res.json()) as Types.ProjectResponse[]) : ((await res.json()) as Types.ErrorResponse);
}
export async function getProject(
organizationId: number,
projectId: number
): Promise<Types.ProjectResponse | Types.ErrorResponse> {
const res = await request(`project/${projectId}`, organizationId);
return res.ok ? ((await res.json()) as Types.ProjectResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function deleteProject(organizationId: number, projectId: number): Promise<number> {
const res = await request(`project/${projectId}`, organizationId, 'DELETE');
return res.status;
}

export async function getProjectAccessToken(
organizationId: number,
projectId: number,
token: Types.TokenConfig
): Promise<Types.TokenResponse | Types.ErrorResponse> {
const res = await request(`project/${projectId}/token`, organizationId, 'POST', token);
return res.ok ? ((await res.json()) as Types.TokenResponse) : ((await res.json()) as Types.ErrorResponse);
}

export async function createJob(
organizationId: number,
job: Types.JobConfig
): Promise<Types.JobResponse | Types.ErrorResponse> {
const res = await request('job', organizationId, 'POST', job);
return res.ok ? ((await res.json()) as Types.JobResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function getJobs(organizationId: number): Promise<Types.JobResponse[] | Types.ErrorResponse> {
const res = await request('job', organizationId);
return res.ok ? ((await res.json()) as Types.JobResponse[]) : ((await res.json()) as Types.ErrorResponse);
}
export async function getJob(
organizationId: number,
jobId: number
): Promise<Types.JobResponse | Types.ErrorResponse> {
const res = await request(`job/${jobId}`, organizationId);
return res.ok ? ((await res.json()) as Types.JobResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function deleteJob(organizationId: number, jobId: number): Promise<number> {
const res = await request(`job/${jobId}`, organizationId, 'DELETE');
return res.status;
}

export async function createBuild(
organizationId: number,
jobId: number,
build: Types.BuildConfig
): Promise<Types.BuildResponse | Types.ErrorResponse> {
const res = await request(`job/${jobId}/build`, organizationId, 'POST', build);
return res.ok ? ((await res.json()) as Types.BuildResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function getBuild(
organizationId: number,
jobId: number,
buildId: number
): Promise<Types.BuildResponse | Types.ErrorResponse> {
const res = await request(`job/${jobId}/build/${buildId}`, organizationId);
return res.ok ? ((await res.json()) as Types.BuildResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function getBuilds(
organizationId: number,
jobId: number
): Promise<Types.BuildResponse[] | Types.ErrorResponse> {
const res = await request(`job/${jobId}/build`, organizationId);
return res.ok ? ((await res.json()) as Types.BuildResponse[]) : ((await res.json()) as Types.ErrorResponse);
}
export async function deleteBuild(
organizationId: number,
jobId: number,
buildId: number
): Promise<number> {
const res = await request(`job/${jobId}/build/${buildId}`, organizationId, 'DELETE');
return res.status;
}

export async function createRelease(
organizationId: number,
jobId: number,
buildId: number,
release: Types.ReleaseConfig
): Promise<Types.ReleaseResponse | Types.ErrorResponse> {
const res = await request(`job/${jobId}/build/${buildId}`, organizationId, 'PUT', release);
return res.ok ? ((await res.json()) as Types.ReleaseResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function getRelease(
organizationId: number,
jobId: number,
buildId: number,
releaseId: number
): Promise<Types.ReleaseResponse | Types.ErrorResponse> {
const res = await request(`job/${jobId}/build/${buildId}/release/${releaseId}`, organizationId);
return res.ok ? ((await res.json()) as Types.ReleaseResponse) : ((await res.json()) as Types.ErrorResponse);
}
export async function deleteRelease(
organizationId: number,
jobId: number,
buildId: number,
releaseId: number
): Promise<number> {
const res = await request(
`job/${jobId}/build/${buildId}/release/${releaseId}`,
organizationId,
'DELETE'
);
return res.status;
}
105 changes: 105 additions & 0 deletions source/SIL.AppBuilder.Portal/common/build-engine-api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
export type Response =
| ErrorResponse
| ProjectResponse
| TokenResponse
| BuildResponse
| ReleaseResponse;

export type ErrorResponse = {
responseType: 'error';
name: string;
message: string;
code: number;
status: number;
type: string;
};

type SuccessResponse = {
responseType: 'project' | 'token' | 'job' | 'build' | 'release';
id: number;
created: Date;
updated: Date;
_links: {
self?: {
href: string;
};
job?: {
href: string;
};
};
};

export type ProjectConfig = {
user_id: string;
group_id: string;
app_id: string;
project_name: string;
language_code: string;
publishing_key: string;
storage_type: string;
};
export type ProjectResponse = SuccessResponse &
ProjectConfig & {
responseType: 'project';
status: 'initialized' | 'accepted' | 'complete' | 'delete' | 'deleting';
result: 'SUCCESS' | 'FAILURE' | null;
error: string | null;
url: string;
};

export type TokenConfig = {
name: string;
};
export type TokenResponse = {
responseType: 'token';
session_token: string;
secret_access_key: string;
access_key_id: string;
expiration: string;
region: string;
};

export type JobConfig = {
request_id: string;
git_url: string;
app_id: string;
publisher_id: string;
};
export type JobResponse = SuccessResponse &
JobConfig & {
responseType: 'job';
};

type BuildCommon = {
targets: string;
};
export type BuildConfig = BuildCommon & {
environment: { [key: string]: string };
};
export type BuildResponse = SuccessResponse &
BuildCommon & {
responseType: 'build';
job_id: number;
status: 'initialized' | 'accepted' | 'active' | 'expired' | 'postprocessing' | 'completed';
result: 'SUCCESS' | 'FAILURE' | 'ABORTED' | null;
error: string | null;
artifacts: { [key: string]: string };
};

type ReleaseCommon = {
channel: 'production' | 'beta' | 'alpha';
targets: string;
};
export type ReleaseConfig = ReleaseCommon & {
environment: { [key: string]: string };
};
export type ReleaseResponse = SuccessResponse &
ReleaseCommon & {
responseType: 'release';
buildId: number;
status: 'initialized' | 'accepted' | 'active' | 'expired' | 'completed' | 'postprocessing';
result: 'SUCCESS' | 'FAILURE' | 'EXCEPTION' | null;
error: string | null;
console_text: string;
artifacts: { [key: string]: string };
};
1 change: 1 addition & 0 deletions source/SIL.AppBuilder.Portal/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { scriptoriaQueue } from './bullmq.js';
export { default as DatabaseWrites } from './databaseProxy/index.js';
export { readonlyPrisma as prisma } from './prisma.js';
export { Workflow } from './workflow/index.js';
export * as BuildEngine from './build-engine-api/index.js';

0 comments on commit c3b0bb7

Please sign in to comment.