abstruse
Version:
Abstruse CI
339 lines (303 loc) • 10.7 kB
text/typescript
import { Build, BuildRun, Job, JobRun } from './model';
import { getLastRun } from './job';
import { getBitBucketAccessToken } from '../utils';
export function getBuilds(
limit: number,
offset: number,
filter: string,
userId?: number | null
): Promise<any> {
return new Promise((resolve, reject) => {
new Build()
.query(q => {
if (userId) {
q.innerJoin('repositories', 'repositories.id', 'builds.repositories_id')
.innerJoin('permissions', 'permissions.repositories_id', 'repositories.id')
.where('permissions.users_id', userId)
.andWhere(function () {
this.where('permissions.permission', true).orWhere('repositories.public', true);
});
} else {
q.innerJoin('repositories', 'repositories.id', 'builds.repositories_id')
.where('repositories.public', true);
}
if (filter === 'pr') {
q.whereNotNull('builds.pr');
} else if (filter === 'commits') {
q.whereNull('builds.pr');
}
q.orderBy('id', 'DESC')
.offset(offset)
.limit(limit);
})
.fetchAll({ withRelated: ['repository.permissions', 'jobs.runs'] })
.then(builds => {
if (!builds) {
reject();
}
builds = builds.toJSON();
builds = builds.map(build => {
build.jobs = build.jobs.map(job => {
if (job.runs.length > 0) {
job.end_time = job.runs[job.runs.length - 1].end_time;
job.start_time = job.runs[job.runs.length - 1].start_time;
job.status = job.runs[job.runs.length - 1].status;
}
delete job.runs;
return job;
});
userId = parseInt(<any>userId, 10);
if (build.repository.permissions && build.repository.permissions.length) {
let index = build.repository.permissions.findIndex(p => p.users_id === userId);
if (index !== -1 && build.repository.permissions[index].permission) {
build.hasPermission = true;
} else {
build.hasPermission = false;
}
} else {
build.hasPermission = false;
}
return build;
});
resolve(builds);
});
});
}
export function getBuild(id: number, userId?: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build()
.query(q => q.where('id', id))
.fetch({
withRelated: [{
'repository.permissions': (query) => {
if (userId) {
query.where('permissions.users_id', userId)
.andWhere('permissions.permission', true)
.orWhere('public', true);
}
}
},
'repository.access_token',
'jobs.runs',
'runs.job_runs']
})
.then(build => {
if (!build) {
reject();
}
build = build.toJSON();
build.jobs = build.jobs.map(job => {
job.end_time = job.runs[job.runs.length - 1].end_time;
job.start_time = job.runs[job.runs.length - 1].start_time;
job.status = job.runs[job.runs.length - 1].status;
return job;
});
build.runs = build.runs.map(run => {
if (run.job_runs) {
if (run.job_runs.findIndex(j => j.status === 'queued') !== -1) {
run.status = 'queued';
} else if (run.job_runs.findIndex(j => j.status === 'running') !== -1) {
run.status = 'running';
} else if (run.job_runs.findIndex(j => j.status === 'failed') !== -1) {
run.status = 'failed';
} else if (run.job_runs.findIndex(j => j.status === 'success') !== -1) {
run.status = 'success';
}
}
return run;
});
userId = parseInt(<any>userId, 10);
if (build.repository.permissions && build.repository.permissions.length) {
let index = build.repository.permissions.findIndex(p => p.users_id === userId);
if (index !== -1 && build.repository.permissions[index].permission) {
build.hasPermission = true;
} else {
build.hasPermission = false;
}
} else {
build.hasPermission = false;
}
if (typeof build.repository.access_token !== 'undefined') {
const token_data = build.repository.access_token;
if (token_data.type === 'bitbucket') {
build.repository.access_token = `${token_data.bitbucket_oauth_key}:${token_data.bitbucket_oauth_secret}`;
return Promise.resolve(build);
} else {
build.repository.access_token = build.repository.access_token && build.repository.access_token.token ?
build.repository.access_token.token : null;
return Promise.resolve(build);
}
} else {
build.repository.access_token = null;
return Promise.resolve(build);
}
})
.then(build => {
new BuildRun()
.query(q => {
q.innerJoin('builds', 'builds.id', 'build_runs.build_id')
.where('builds.repositories_id', build.repositories_id)
.andWhere('builds.id', '<=', build.id)
.whereNotNull('build_runs.start_time')
.whereNotNull('build_runs.end_time')
.orderBy('build_runs.id', 'desc');
})
.fetch({ withRelated: 'job_runs' })
.then(lastBuild => {
if (lastBuild) {
build.lastBuild = lastBuild.toJSON();
}
build.jobs = build.jobs.map(job => {
job.data = JSON.parse(job.data);
return job;
});
resolve(build);
});
});
});
}
export function getLastBuild(userId?: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build().query(q => q.orderBy('id', 'desc'))
.fetch({
withRelated: [{
'repository.permissions': (query) => {
if (userId) {
query.where('permissions.users_id', userId)
.andWhere('permissions.permission', true)
.orWhere('public', true);
}
}
},
'jobs.runs']
})
.then(build => {
if (!build) {
reject(build);
}
build = build.toJSON();
build.jobs = build.jobs.map(job => {
if (job.runs.length > 0) {
job.end_time = job.runs[job.runs.length - 1].end_time;
job.start_time = job.runs[job.runs.length - 1].start_time;
job.status = job.runs[job.runs.length - 1].status;
}
return job;
});
userId = parseInt(<any>userId, 10);
if (build.repository.permissions && build.repository.permissions.length) {
let index = build.repository.permissions.findIndex(p => p.users_id === userId);
if (index !== -1 && build.repository.permissions[index].permission) {
build.hasPermission = true;
} else {
build.hasPermission = false;
}
} else {
build.hasPermission = false;
}
resolve(build);
});
});
}
export function getLastRunId(buildId: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build({ id: buildId }).fetch({ withRelated: ['runs'] })
.then(build => {
if (!build) {
reject();
}
let runs = build.related('runs').toJSON();
resolve(runs.length > 0 ? runs[runs.length - 1].id : -1);
});
});
}
export function insertBuild(data: any): Promise<any> {
return new Promise((resolve, reject) => {
new Build().save(data, { method: 'insert' }).then(build => {
if (!build) {
reject(build);
} else {
resolve(build.toJSON());
}
}).catch(err => reject(err));
});
}
export function updateBuild(data: any): Promise<boolean> {
return new Promise((resolve, reject) => {
delete data.jobs;
delete data.repository;
delete data.lastBuild;
delete data.runs;
delete data.hasPermission;
new Build({ id: data.id }).save(data, { method: 'update', require: false }).then(build => {
if (!build) {
reject(build);
} else {
resolve(build.toJSON());
}
});
});
}
export function getBuildRepositoryId(buildId: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build({ id: buildId }).fetch()
.then(build => !build ? reject(build) : resolve(build.toJSON().repositories_id));
});
}
export function getBuildStatus(buildId: number): Promise<any> {
return new Promise((resolve, reject) => {
new Job()
.query(q => q.where('builds_id', buildId))
.fetchAll()
.then(jobs => {
Promise.all(jobs.map(j => getLastRun(j.id).then(r => r.status)))
.then(data => resolve(data.reduce((accu, curr) => {
if (curr === 'queued') {
return curr;
} else if (curr === 'running' && accu !== 'queued') {
return curr;
} else if (curr === 'failed' && accu !== 'running' && accu !== 'queued') {
return curr;
} else if (curr === 'success' && accu !== 'failed'
&& accu !== 'running' && accu !== 'queued') {
return curr;
}
return accu;
})));
});
});
}
export function getDepracatedBuilds(build: any): Promise<any> {
return new Promise((resolve, reject) => {
new Build({ repositories_id: build.repositories_id })
.query(q => {
q.whereNull('end_time')
.andWhereNot('id', build.id);
if (build.pr) {
q.where('pr', build.pr);
}
})
.fetchAll()
.then(builds => {
if (!builds) {
reject();
}
builds = builds.toJSON();
if (!build.pr) {
builds = builds.filter(b => {
if (build.data.before) {
return build.data.before === b.data.before;
} else if (build.data.before_sha) {
return build.data.before_sha === b.data.before_sha;
} else if (build.data.object_attributes && build.data.object_attributes.before_sha) {
return build.data.object_attributes.before_sha
=== b.data.object_attributes.before_sha;
}
return false;
});
}
builds = builds.map(b => b.id);
resolve(builds);
});
});
}