Skip to content

Commit

Permalink
us #1790005: Upgrade of existing pipelines - extension side
Browse files Browse the repository at this point in the history
us #1790002: extension side
us #1790006: extension side
  • Loading branch information
lazara3 committed Jun 26, 2022
1 parent 8b1b36a commit 33719ff
Show file tree
Hide file tree
Showing 6 changed files with 1,793 additions and 53 deletions.
110 changes: 97 additions & 13 deletions src/BaseTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ export class BaseTask {
let ret = await octaneSDKConnection._requestHandler._requestor.put(eventObj);

this.logger.debug('sendEvent response:' + ret);
this.logger.debug('sendEvent response:' + ret);
}

public async sendTestResult(octaneSDKConnection, testResult: string) {
let testResultsApiUrl = this.analyticsCiInternalApiUrlPart + '/test-results?skip-errors=true&instance-id=' +
this.instanceId + '&job-ci-id=' + this.jobFullName + '&build-ci-id=' + this.buildId;
this.instanceId + '&job-ci-id=' + this.getJobCiId() + '&build-ci-id=' + this.buildId;

this.logger.debug('Sending results to:' + testResultsApiUrl + '\nThe result string is:\n' + testResult);

Expand Down Expand Up @@ -325,7 +326,7 @@ export class BaseTask {
'name': this.projectFullName,
'instance_id': this.instanceId,
'server_type': CI_SERVER_INFO.CI_SERVER_TYPE,
'url': serverUrl
'url': encodeURI(serverUrl),
};

let ciServers = [
Expand All @@ -343,10 +344,29 @@ export class BaseTask {
return ciServers;
}

protected getJobCiId(){
if(this.experiments.support_azure_multi_branch){
return this.projectId + '.'+this.definitionId +'.' +this.sourceBranchName;
} else {
return this.jobFullName;
}
}

protected getParentJobCiId(){
if(this.experiments.support_azure_multi_branch){
return this.projectId + '.' + this.definitionId;
} else {
return this.projectFullName + '.' + this.buildDefinitionName;
}
}

protected async getPipeline(octaneSDKConnection, pipelineName, rootJobName, ciServer, createOnAbsence,workspaceId) {
let pipelines;
if(this.experiments.run_azure_pipeline){
const pipelineQuery = Query.field('ci_id').equal(BaseTask.escapeOctaneQueryValue(this.projectFullName + '.' + this.buildDefinitionName))

await this.upgradePipelinesIfNeeded(octaneSDKConnection,ciServer,workspaceId);

const pipelineQuery = Query.field('ci_id').equal(BaseTask.escapeOctaneQueryValue(this.getParentJobCiId()))
.and(Query.field(EntityTypeConstants.CI_SERVER_ENTITY_TYPE).equal(Query.field('id').equal(ciServer.id))).build();
const ciJobs = await octaneSDKConnection.get(EntityTypeRestEndpointConstants.CI_JOB_REST_API_NAME)
.fields('pipeline,definition_id')
Expand Down Expand Up @@ -441,20 +461,72 @@ export class BaseTask {
return version1Spl.length >= version2Spl.length;
}


protected async upgradePipelinesIfNeeded(octaneSDKConnection,ciServer,workspaceId){
if(this.experiments.support_azure_multi_branch) {
//check if the parent exists in old format:
const pipelineQuery = Query.field('ci_id').equal(BaseTask.escapeOctaneQueryValue(this.projectFullName + '.' + this.buildDefinitionName))
.and(Query.field(EntityTypeConstants.CI_SERVER_ENTITY_TYPE).equal(Query.field('id').equal(ciServer.id))).build();
const ciJobs = await octaneSDKConnection.get(EntityTypeRestEndpointConstants.CI_JOB_REST_API_NAME)
.fields('pipeline,definition_id')
.query(pipelineQuery).execute();

//if yes - should upgrade the parent
if (ciJobs && ciJobs.total_count > 0 && ciJobs.data) {
//should update the ciJobs with new id.
this.logger.info("start upgrade of ciJob and his pipelines");
await this.updateExistCIJobs(ciJobs.data, ciServer.id, workspaceId, octaneSDKConnection);

let pipelines = ciJobs.data.filter(ciJob => ciJob.pipeline).map(ciJob => ciJob.pipeline);

if (pipelines && pipelines.length > 0) {
//should update the pipelines to be a multibranch parent
this.logger.info("start upgrade of pipelines to be multibranch pipelines ");
await this.upgradePipelines(pipelines, octaneSDKConnection);
}
}
}
}

private async upgradePipelines(pipelines,octaneSDKConnection): Promise<void>{
let pipelinesToUpdate = [];
pipelines.forEach(pipeline => pipelinesToUpdate.push(this.createPipelineBody(pipeline)));
this.logger.debug('Pipelines update body:' + pipelines);

if(pipelinesToUpdate.length >0) {
let pipelinesData = '{ "data":' + JSON.stringify(pipelinesToUpdate) + ',"total_count":' + pipelinesToUpdate.length + '}';

let results = [
await octaneSDKConnection.update(EntityTypeRestEndpointConstants.PIPELINES_REST_API_NAME, JSON.parse(pipelinesData)).execute()
];

if (results.length === pipelinesToUpdate.length) {
this.logger.info("Pipelines have been upgraded successfully ");

}
}
}

private async updateExistCIJobs(ciJobs,ciServerId,workspaceId,octaneSDKConnection): Promise<void> {
let ciJobsToUpdate = [];
ciJobs.forEach(ciJob => ciJobsToUpdate.push(this.createCiJobBody(ciJob)));
this.logger.debug('CI Jobs update body:' + ciJobs);

const url = this.ciInternalAzureApiUrlPart.replace('{workspace_id}',workspaceId) + '/ci_job_update?ci-server-id=' + ciServerId;
await octaneSDKConnection._requestHandler.update(url,ciJobsToUpdate);
}

private createCiJobBody(ciJob){
private createPipelineBody(pipeline){
return {
'id': ciJob.id,
'definitionId': this.definitionId,
'jobCiId': this.projectFullName + '.' + this.buildDefinitionName,
'parameters': [
'id': pipeline.id,
'multi_branch_type': 'PARENT',
}
}
private createCiJobBody(ciJob){
let jobCiId = this.getParentJobCiId();
let parameters = []
if(!this.experiments.support_azure_multi_branch){
parameters = [
{
'name': 'branch',
'type': 'string',
Expand All @@ -463,6 +535,12 @@ export class BaseTask {
'choices': [],
}
]
}
return {
'jobId': ciJob.id,
'definitionId': this.definitionId,
'jobCiId': jobCiId,
'parameters': parameters,

}
}
Expand Down Expand Up @@ -499,20 +577,22 @@ export class BaseTask {
const api: WebApi = ConnectionUtils.getWebApiWithProxy(this.collectionUri, this.authenticationService.getAzureAccessToken());

if(this.experiments.run_azure_pipeline_with_parameters){
const parameters = await this.parametersService.getDefinedParameters(api,this.definitionId,this.projectName,this.sourceBranch);
const parameters = await this.parametersService.getDefinedParametersWithBranch(api,this.definitionId,this.projectName,this.sourceBranch,this.experiments.support_azure_multi_branch?false:true);

pipeline = {
'name': pipelineName,
'ci_server': {'type': EntityTypeConstants.CI_SERVER_ENTITY_TYPE, 'id': ciServer.id},
'jobs': [{
'name':this.agentJobName,
'jobCiId': this.projectFullName + '.' + this.buildDefinitionName,
'name': this.agentJobName,
'jobCiId': this.getParentJobCiId(),
'definitionId': this.definitionId,
'parameters': parameters,
}],
'root_job_ci_id': this.projectFullName + '.' + this.buildDefinitionName,
'root_job_ci_id': this.getParentJobCiId(),
'notification_track': false,
'notification_track_tester': false
'notification_track_tester': false
};

} else {
pipeline = {
'name': pipelineName,
Expand All @@ -523,6 +603,10 @@ export class BaseTask {
};
}

if(this.experiments.support_azure_multi_branch){
pipeline.multi_branch_type = 'PARENT';
}

let pipelines = [
await octaneSDKConnection.create(EntityTypeRestEndpointConstants.PIPELINES_REST_API_NAME, pipeline).execute()
];
Expand Down
18 changes: 15 additions & 3 deletions src/EndTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,21 @@ export class EndTask extends BaseTask {
let buildResult = await this.getStatus(api);
let duration = await this.getDuration(api);
const parameters:CiParameter[] = this.experiments.run_azure_pipeline_with_parameters ?
await this.parametersService.getParameters(api,this.definitionId,this.buildId,this.projectName,this.sourceBranch) :
undefined;
let endEvent = new CiEvent(this.agentJobName, CiEventType.FINISHED, this.buildId, this.buildId, this.jobFullName, buildResult, new Date().getTime(), null, duration, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL, causes,parameters);
await this.parametersService.getParametersWithBranch(api,this.definitionId,this.buildId,this.projectName,this.sourceBranch, this.experiments.support_azure_multi_branch?false:true)
:undefined;

let endEvent;

if(this.experiments.support_azure_multi_branch){
let jobCiId = this.getJobCiId();
endEvent = new CiEvent(this.buildDefinitionName + " " +this.sourceBranchName , CiEventType.FINISHED, this.buildId, this.buildId, jobCiId,
buildResult, new Date().getTime(), null, duration, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL,
causes,parameters,'CHILD',this.getParentJobCiId(), this.sourceBranch);
} else {
endEvent = new CiEvent(this.agentJobName , CiEventType.FINISHED, this.buildId, this.buildId, this.jobFullName, buildResult, new Date().getTime(), null, duration, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL, causes,parameters);

}

await this.sendEvent(this.octaneSDKConnections[ws], endEvent);
}
break; // events are sent to the sharedspace, thus sending event to a single connection is enough
Expand Down
26 changes: 22 additions & 4 deletions src/StartTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,35 @@ export class StartTask extends BaseTask {
let causes = await CiEventCauseBuilder.buildCiEventCauses(this.isPipelineJob, api, this.projectName, this.rootJobFullName, parseInt(this.buildId));

const parameters: CiParameter[] = this.experiments.run_azure_pipeline_with_parameters ?
await this.parametersService.getParameters(api, this.definitionId, this.buildId, this.projectName, this.sourceBranch) :
undefined;
await this.parametersService.getParametersWithBranch(api,this.definitionId,this.buildId,this.projectName,this.sourceBranch,this.experiments.support_azure_multi_branch?false:true)
:undefined;

let startEvent;
if(this.experiments.support_azure_multi_branch){
let jobCiId = this.getJobCiId();
startEvent = new CiEvent(this.buildDefinitionName + " " +this.sourceBranchName, CiEventType.STARTED, this.buildId, this.buildId, jobCiId, null, new Date().getTime(),
null, null, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL, causes, parameters,
'CHILD',this.getParentJobCiId(), this.sourceBranch);
} else{
startEvent = new CiEvent(this.agentJobName, CiEventType.STARTED, this.buildId, this.buildId,this.jobFullName, null, new Date().getTime(),
null, null, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL, causes, parameters)
}

let startEvent = new CiEvent(this.agentJobName, CiEventType.STARTED, this.buildId, this.buildId, this.jobFullName, null, new Date().getTime(), null, null, null, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL, causes,parameters);
await this.sendEvent(this.octaneSDKConnections[ws], startEvent);
}

if (this.isPipelineStartJob) {
let scmData = await ScmBuilder.buildScmData(api, this.projectName, parseInt(this.buildId), this.sourceBranchName, this.tl, this.logger);
this.logger.debug(scmData);
let scmEvent = new CiEvent(this.agentJobName, CiEventType.SCM, this.buildId, this.buildId, this.jobFullName, null, new Date().getTime(), null, null, scmData, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL);
let scmEvent;
if(this.experiments.support_azure_multi_branch){
let jobCiId = this.getJobCiId();
scmEvent = new CiEvent(this.buildDefinitionName + " " +this.sourceBranchName, CiEventType.SCM, this.buildId, this.buildId,jobCiId, null, new Date().getTime(), null, null, scmData, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL);

} else {
scmEvent = new CiEvent(this.agentJobName, CiEventType.SCM, this.buildId, this.buildId,this.jobFullName, null, new Date().getTime(), null, null, scmData, this.isPipelineJob ? PhaseType.POST : PhaseType.INTERNAL);

}
await this.sendEvent(this.octaneSDKConnections[ws], scmEvent);
}
break; // events are sent to the sharedspace, thus sending event to a single connection is enough
Expand Down
9 changes: 8 additions & 1 deletion src/dto/events/CiEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ export class CiEvent extends DtoObject {
phaseType: PhaseType;
causes: CiEventCause[];
parameters: CiParameter[] = [];
multiBranchType: string;
parentCiId: string;
branch: string;

constructor(project_display_name: string, ci_event_type: CiEventType, build_ci_id: string, number: string, project: string, result: Result,
start_time: number, estimated_duration?: number, duration?: number, scm_data?: ScmData, phase_type?: PhaseType, causes?: CiEventCause[], parameters?: any[]) {
start_time: number, estimated_duration?: number, duration?: number, scm_data?: ScmData, phase_type?: PhaseType, causes?: CiEventCause[],
parameters?: any[],multiBranchType?:string ,parentCiId?:string, branch?:string) {
super();
this.projectDisplayName = project_display_name;
this.eventType = ci_event_type;
Expand All @@ -35,5 +39,8 @@ export class CiEvent extends DtoObject {
this.phaseType = phase_type;
this.causes = causes;
this.parameters = parameters;
this.multiBranchType = multiBranchType;
this.parentCiId = parentCiId;
this.branch =branch;
}
}
Loading

0 comments on commit 33719ff

Please sign in to comment.