Skip to content

Commit fd87f07

Browse files
committed
feat(): list of previous build and job runs
1 parent 82857e6 commit fd87f07

File tree

8 files changed

+125
-68
lines changed

8 files changed

+125
-68
lines changed

e2e/070_job.e2e.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ describe('Job Details', () => {
1717

1818
it('should see console log and then collapse last command output', () => {
1919
return browser.get('/job/15')
20-
.then((): any => browser.wait(() => {
21-
return element.all(by.css('.terminal .command')).count().then(cnt => cnt === 6);
22-
}))
23-
.then((): any => browser.wait(() => {
24-
return element.all(by.css('.terminal .output.is-hidden')).count().then(cnt => {
25-
return cnt === 5;
26-
});
27-
}))
28-
.then((): any => element.all(by.css('.terminal .command-line')).first().click())
29-
.then((): any => browser.wait(() => {
30-
return element.all(by.css('.terminal .command')).count().then(cnt => cnt === 6);
31-
}))
32-
.then((): any => browser.wait(() => {
33-
return element.all(by.css('.terminal .output.is-hidden')).count().then(cnt => {
34-
return cnt === 4;
35-
});
36-
}));
20+
.then((): any => browser.wait(() => {
21+
return element.all(by.css('.terminal .command')).count().then(cnt => cnt === 6);
22+
}))
23+
.then((): any => browser.wait(() => {
24+
return element.all(by.css('.terminal .output.is-hidden')).count().then(cnt => {
25+
return cnt === 5;
26+
});
27+
}))
28+
.then((): any => element.all(by.css('.terminal .command-line')).first().click())
29+
.then((): any => browser.wait(() => {
30+
return element.all(by.css('.terminal .command')).count().then(cnt => cnt === 6);
31+
}))
32+
.then((): any => browser.wait(() => {
33+
return element.all(by.css('.terminal .output.is-hidden')).count().then(cnt => {
34+
return cnt === 4;
35+
});
36+
}));
3737
});
3838

3939
it('should restart job watch console log until it matches expected output', () => {

src/api/db/build.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,21 @@ export function getBuilds(limit: number, offset: number): Promise<any> {
3030

3131
export function getBuild(id: number): Promise<any> {
3232
return new Promise((resolve, reject) => {
33-
new Build({ id: id }).fetch({ withRelated: ['repository', 'jobs.runs'] }).then(build => {
34-
if (!build) {
35-
reject();
36-
}
33+
new Build({ id: id }).fetch({ withRelated: ['repository', 'jobs.runs', 'runs'] })
34+
.then(build => {
35+
if (!build) {
36+
reject();
37+
}
3738

38-
build = build.toJSON();
39-
build.jobs = build.jobs.map(job => {
40-
job.end_time = job.runs[job.runs.length - 1].end_time;
41-
job.start_time = job.runs[job.runs.length - 1].start_time;
42-
job.status = job.runs[job.runs.length - 1].status;
43-
return job;
44-
});
39+
build = build.toJSON();
40+
build.jobs = build.jobs.map(job => {
41+
job.end_time = job.runs[job.runs.length - 1].end_time;
42+
job.start_time = job.runs[job.runs.length - 1].start_time;
43+
job.status = job.runs[job.runs.length - 1].status;
44+
return job;
45+
});
4546

46-
return build;
47+
return build;
4748
})
4849
.then(build => {
4950
new BuildRun()
@@ -96,6 +97,7 @@ export function updateBuild(data: any): Promise<boolean> {
9697
delete data.jobs;
9798
delete data.repository;
9899
delete data.lastBuild;
100+
delete data.runs;
99101

100102
new Build({ id: data.id }).save(data, { method: 'update', require: false }).then(build => {
101103
if (!build) {

src/api/db/job-run.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,3 @@ export function updateJobRun(data: any): Promise<any> {
3131
.then(job => resolve(job.toJSON()));
3232
});
3333
}
34-
35-
export function resetJobRun(runId: number): Promise<any> {
36-
return new Promise((resolve, reject) => {
37-
const data = {
38-
start_time: new Date(),
39-
end_time: null,
40-
status: 'queued',
41-
log: '',
42-
id: runId
43-
};
44-
45-
updateJobRun(data);
46-
});
47-
}

src/api/db/migrations.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export function create(): Promise<null> {
116116
t.text('log');
117117
t.integer('job_id').notNullable();
118118
t.foreign('job_id').references('job.id');
119+
t.integer('build_run_id').notNullable();
120+
t.foreign('build_run_id').references('build_run.id');
119121
t.timestamps();
120122
}))
121123
.then(() => schema.createTableIfNotExists('permissions', (t: knex.TableBuilder) => {

src/api/db/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ export class JobRun extends Bookshelf.Model<any> {
3737
get tableName() { return 'job_runs'; }
3838
get hasTimestamps() { return true; }
3939
job() { return this.belongsTo(Job, 'job_id'); }
40+
build_run() { return this.belongsTo(BuildRun, 'build_run_id'); }
4041
}

src/api/process-manager.ts

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,30 @@ export function startBuild(data: any): Promise<any> {
147147
builds_id: build.id
148148
};
149149

150-
return dbJob.insertJob(jobData).then(job => {
151-
const jobRunData = {
152-
start_time: new Date(),
153-
end_time: null,
154-
status: 'queued',
155-
log: '',
156-
job_id: job.id
157-
};
158-
return dbJobRuns.insertJobRun(jobRunData).then(() => {
159-
jobEvents.next({
160-
type: 'process',
161-
build_id: build.id,
162-
job_id: job.id,
163-
data: 'jobAdded'
150+
return dbJob.insertJob(jobData)
151+
.then(job => {
152+
getLastRunId(build.id).then(buildRunId => {
153+
const jobRunData = {
154+
start_time: new Date(),
155+
end_time: null,
156+
status: 'queued',
157+
log: '',
158+
build_run_id: buildRunId,
159+
job_id: job.id
160+
};
161+
162+
return dbJobRuns.insertJobRun(jobRunData).then(() => {
163+
jobEvents.next({
164+
type: 'process',
165+
build_id: build.id,
166+
job_id: job.id,
167+
data: 'jobAdded'
168+
});
169+
170+
return queueJob(build.id, job.id);
171+
});
164172
});
165-
166-
return queueJob(build.id, job.id);
167173
});
168-
});
169174
});
170175
}, Promise.resolve());
171176
});
@@ -356,10 +361,22 @@ export function restartBuild(buildId: number): Promise<any> {
356361

357362
return updateBuild(build)
358363
.then(() => {
359-
jobs.forEach(job => {
360-
dbJobRuns.insertJobRun(
361-
{ start_time: new Date(), end_time: null, status: 'queued', log: '', job_id: job.id }
362-
);
364+
build.build_id = buildId;
365+
delete build.repositories_id;
366+
delete build.jobs;
367+
insertBuildRun(build);
368+
})
369+
.then(() => getLastRunId(build.id))
370+
.then(buildRunId => {
371+
return jobs.forEach(job => {
372+
dbJobRuns.insertJobRun({
373+
start_time: new Date(),
374+
end_time: null,
375+
status: 'queued',
376+
log: '',
377+
build_run_id: buildRunId,
378+
job_id: job.id
379+
});
363380
});
364381
})
365382
.then(() => {
@@ -382,8 +399,14 @@ export function stopBuild(buildId: number): Promise<any> {
382399
export function restartJob(jobId: number): Promise<void> {
383400
let jobData = null;
384401
return stopJob(jobId)
385-
.then(() => dbJobRuns.insertJobRun(
386-
{ start_time: new Date(), end_time: null, status: 'queued', log: '', job_id: jobId }))
402+
.then(() => dbJob.getLastRun(jobId))
403+
.then(lastRun => dbJobRuns.insertJobRun({
404+
start_time: new Date(),
405+
end_time: null,
406+
status: 'queued',
407+
log: '',
408+
build_run_id: lastRun.build_run_id,
409+
job_id: jobId }))
387410
.then(job => jobData = job)
388411
.then(() => queueJob(jobData.builds_id, jobId))
389412
.then(() => {
@@ -399,8 +422,14 @@ export function restartJob(jobId: number): Promise<void> {
399422
export function restartJobWithSshAndVnc(jobId: number): Promise<void> {
400423
let jobData = null;
401424
return stopJob(jobId)
402-
.then(() => dbJobRuns.insertJobRun(
403-
{ start_time: new Date(), end_time: null, status: 'queued', log: '', job_id: jobId }))
425+
.then(() => dbJob.getLastRun(jobId))
426+
.then(lastRun => dbJobRuns.insertJobRun({
427+
start_time: new Date(),
428+
end_time: null,
429+
status: 'queued',
430+
log: '',
431+
build_run_id: lastRun.build_run_id,
432+
job_id: jobId }))
404433
.then(job => jobData = job)
405434
.then(() => queueJob(jobData.builds_id, jobId, true))
406435
.then(() => {

src/app/components/app-build-details/app-build-details.component.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,26 @@ <h2>{{ build?.message }}</h2>
131131
</div>
132132
</div>
133133
</div>
134+
<div class="column is-12" *ngIf="build.runs && build.runs.length > 1">
135+
<div class="build-top-container">
136+
<div class="build-top-content">
137+
<h1 class="bold">
138+
<span>Previous Runs:</span>
139+
</h1>
140+
<hr/>
141+
<div class="columns list-item"
142+
*ngFor="let run of build.runs; let i = index;"
143+
[ngClass]="{ 'is-queued': run.status === 'queued', 'is-success': run.status === 'success', 'is-running': run.status === 'running', 'is-errored': true }">
144+
<div class="column is-4">
145+
<span>{{ run.start_time | date:'dd MM yyyy hh:mm:ss' }} - {{ run.end_time | date:'dd MM yyyy hh:mm:ss' }}</span>
146+
</div>
147+
<div class="column is-8">
148+
<span>{{ run.message }} ({{ run.sha}})</span>
149+
</div>
150+
</div>
151+
</div>
152+
</div>
153+
</div>
134154
</div>
135155
</div>
136156
</div>

src/app/components/app-job/app-job.component.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ <h2>{{ job?.build?.message }}</h2>
104104
<div class="column is-12">
105105
<app-terminal [data]="terminalInput" (outputData)="terminalOutput($event)" [options]="terminalOptions"></app-terminal>
106106
</div>
107+
<div class="column is-12" *ngIf="job.runs && job.runs.length > 1">
108+
<div class="build-top-container">
109+
<div class="build-top-content">
110+
<h1 class="bold">
111+
<span>Previous Runs:</span>
112+
</h1>
113+
<hr/>
114+
<div class="columns list-item"
115+
*ngFor="let run of job.runs; let i = index;"
116+
[ngClass]="{ 'is-queued': run.status === 'queued', 'is-success': run.status === 'success', 'is-running': run.status === 'running', 'is-errored': run.status === 'failed' }">
117+
<div class="column is-8">
118+
<span>{{ run.start_time | date:'dd MM yyyy hh:mm:ss' }} - {{ run.end_time | date:'dd MM yyyy hh:mm:ss' }}</span>
119+
</div>
120+
</div>
121+
</div>
122+
</div>
123+
</div>
107124
</div>
108125
</div>
109126
</div>

0 commit comments

Comments
 (0)