feat: add trigger reason to give a better overview to the user

Signed-off-by: djamaile <rdjamaile@gmail.com>
This commit is contained in:
djamaile
2022-03-30 17:34:33 +02:00
committed by Fredrik Adelöw
parent d9a4b672c2
commit 0e8b8472fc
2 changed files with 196 additions and 0 deletions
@@ -0,0 +1,89 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { pipelinesToBuilds, jobsToStages } from './utils';
import { Types } from '@gitbeaker/core';
const pipelineMock: Types.PipelineSchema[] = [
{
id: 1000,
iid: 1,
project_id: 1,
sha: 'd40',
ref: 'main',
status: 'success',
source: 'schedule',
created_at: '2022-03-30T13:03:09.846Z',
updated_at: '2022-03-30T13:07:49.248Z',
web_url: 'https://gitlab.com/backstage/app/-/pipelines/1000',
user: {
name: 'user',
avatar_url: 'avatar_user',
},
},
];
// cast to unknown so we can omit a lot unused vars but also keep the type
const jobMock = [
{
id: 6962883,
status: 'success',
stage: 'build',
name: 'docker',
ref: 'refs/merge-requests/209/train',
tag: false,
allow_failure: false,
created_at: new Date('2022-03-30T08:35:15.394Z'),
started_at: new Date('2022-03-30T08:35:16.532Z'),
finished_at: new Date('2022-03-30T08:35:37.731Z'),
duration: 21.199465,
queued_duration: 0.976313,
},
] as unknown as Array<Types.JobSchema>;
describe('util functionality', () => {
it('transforms the pipeline object to the build object', () => {
const builds = pipelinesToBuilds(pipelineMock);
expect(builds).toEqual([
{
id: '1000',
status: 'succeeded',
branchType: 'master',
duration: 0,
requestedAt: new Date('2022-03-30T13:03:09.846Z'),
stages: [],
},
]);
});
it('transforms the job object to the stage object', () => {
const stages = jobsToStages(jobMock);
expect(stages).toEqual([
{
name: 'build',
status: 'succeeded',
duration: 21199.465,
stages: [
{
name: 'docker',
status: 'succeeded',
duration: 21199.465,
},
],
},
]);
});
});
@@ -0,0 +1,107 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Build,
FilterStatusType,
TriggerReason,
Stage,
} from '@backstage/plugin-cicd-statistics';
import { Types } from '@gitbeaker/core';
const statusMap: Record<string, FilterStatusType> = {
manual: 'unknown',
created: 'enqueued',
waiting_for_resource: 'stalled',
preparing: 'unknown',
pending: 'scheduled',
running: 'running',
success: 'succeeded',
failed: 'failed',
canceled: 'aborted',
skipped: 'aborted',
scheduled: 'scheduled',
};
// all gitlab trigger reasons can be found here: https://docs.gitlab.com/ee/api/pipelines.html#list-project-pipelines
const triggerReasonMap: Record<string, TriggerReason> = {
push: 'scm',
trigger: 'manual',
merge_request_event: 'scm',
schedule: 'internal',
};
/**
* Takes the Pipeline object from Gitlab and transforms it to the Build object
*
* @param pipelines - Pipeline object that gets returned from Gitlab
*
* @public
*/
export function pipelinesToBuilds(
pipelines: Array<Types.PipelineSchema>,
): Build[] {
return pipelines.map(pipeline => {
return {
id: pipeline.id.toString(),
status: statusMap[pipeline.status],
branchType: 'master',
duration: 0, // will get filled in later in a seperate API call
requestedAt: new Date(pipeline.created_at),
triggeredBy: triggerReasonMap[pipeline.source as string] ?? 'other',
stages: [],
};
});
}
/**
* Takes the Job object from Gitlab and transforms it to the Stage object
*
* @param jobs - Job object that gets returned from Gitlab
*
* @public
*
* @remarks
*
* The Gitlab API can only return the job (sub-stage) of a pipeline and not a whole stage a pipeline
* The job does return from which stage it is
* So, for the stage name we use the parent stage name and in the sub-stages we add the current job
* In the end the cicd-statistics plugin will calculate the right durations for each stage
*
* Furthermore, we don't add the job to the sub-stage if it is has the same name as the parent stage
* We then assume that the stage has no sub-stages
*/
export function jobsToStages(jobs: Array<Types.JobSchema>): Stage[] {
return jobs.map(job => {
const status = statusMap[job.status] ? statusMap[job.status] : 'unknown';
const duration = job.duration ? ((job.duration * 1000) as number) : 0;
return {
name: job.stage,
status,
duration,
stages:
job.name !== job.stage
? [
{
name: job.name,
status,
duration,
},
]
: [],
};
});
}