Skip to content

Commit

Permalink
fix(api,ui): fix to handle custom workflow name change in template (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Jan 15, 2019
1 parent 12c9388 commit 7a538e2
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 98 deletions.
40 changes: 11 additions & 29 deletions engine/api/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,43 +313,25 @@ func (api *API) applyTemplateHandler() service.Handler {
return err
}

// check if a workflow exists with given slug
wf, err := workflow.Load(ctx, api.mustDB(), api.Cache, p, req.WorkflowName, u, workflow.LoadOptions{})
if err != nil && !sdk.ErrorIs(err, sdk.ErrWorkflowNotFound) {
return err
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WrapError(err, "Cannot start transaction")
}
defer func() { _ = tx.Rollback() }()

var wti *sdk.WorkflowTemplateInstance
if wf != nil {
// check if workflow is a generated one for the current template
wti, err = workflowtemplate.GetInstanceByWorkflowIDAndTemplateID(tx, wf.ID, wt.ID)
if err != nil {
return err
}
// try to get a instance not assign to a workflow but with the same slug
wtis, err := workflowtemplate.GetInstancesByTemplateIDAndProjectIDAndRequestWorkflowName(tx, wt.ID, p.ID, req.WorkflowName)
if err != nil {
return err
}
if wti == nil {
// try to get a instance not assign to a workflow but with the same slug
wtis, err := workflowtemplate.GetInstancesByTemplateIDAndProjectIDAndWorkflowIDNull(tx, wt.ID, p.ID)
if err != nil {
return err
}

for _, res := range wtis {
if res.Request.WorkflowName == req.WorkflowName {
if wti == nil {
wti = &res
} else {
// if there are more than one instance found, delete others
if err := workflowtemplate.DeleteInstance(tx, &res); err != nil {
return err
}
}
for _, res := range wtis {
if wti == nil {
wti = &res
} else {
// if there are more than one instance found, delete others
if err := workflowtemplate.DeleteInstance(tx, &res); err != nil {
return err
}
}
}
Expand Down
25 changes: 4 additions & 21 deletions engine/api/workflowtemplate/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,13 @@ func GetInstancesByTemplateIDAndProjectIDs(db gorp.SqlExecutor, templateID int64
return wtis, nil
}

// GetInstancesByTemplateIDAndProjectIDAndWorkflowIDNull returns all workflow template instances by template id, project id and workflow id null.
func GetInstancesByTemplateIDAndProjectIDAndWorkflowIDNull(db gorp.SqlExecutor, templateID, projectID int64) ([]sdk.WorkflowTemplateInstance, error) {
// GetInstancesByTemplateIDAndProjectIDAndRequestWorkflowName returns all workflow template instances by template id, project id and request workflow name.
func GetInstancesByTemplateIDAndProjectIDAndRequestWorkflowName(db gorp.SqlExecutor, templateID, projectID int64, workflowName string) ([]sdk.WorkflowTemplateInstance, error) {
wtis := []sdk.WorkflowTemplateInstance{}

if _, err := db.Select(&wtis,
"SELECT * FROM workflow_template_instance WHERE workflow_id IS NULL AND workflow_template_id = $1 AND project_id = $2",
templateID, projectID,
"SELECT * FROM workflow_template_instance WHERE workflow_template_id = $1 AND project_id = $2 AND (request->>'workflow_name')::text = $3",
templateID, projectID, workflowName,
); err != nil {
return nil, sdk.WrapError(err, "Cannot get workflow template instances")
}
Expand All @@ -199,23 +199,6 @@ func GetInstancesByWorkflowIDs(db gorp.SqlExecutor, workflowIDs []int64) ([]sdk.
return wtis, nil
}

// GetInstanceByWorkflowIDAndTemplateID returns a workflow template instance by workflow and template ids.
func GetInstanceByWorkflowIDAndTemplateID(db gorp.SqlExecutor, workflowID, templateID int64) (*sdk.WorkflowTemplateInstance, error) {
wti := sdk.WorkflowTemplateInstance{}

if err := db.SelectOne(&wti,
"SELECT * FROM workflow_template_instance WHERE workflow_id = $1 AND workflow_template_id = $2",
workflowID, templateID,
); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, sdk.WrapError(err, "Cannot get workflow template instance")
}

return &wti, nil
}

// GetInstanceByWorkflowID returns a workflow template instance by workflow id.
func GetInstanceByWorkflowID(db gorp.SqlExecutor, workflowID int64) (*sdk.WorkflowTemplateInstance, error) {
wti := sdk.WorkflowTemplateInstance{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
WorkflowTemplateInstance,
WorkflowTemplateRequest
} from '../../../model/workflow-template.model';
import { Workflow } from '../../../model/workflow.model';
import { RepoManagerService } from '../../../service/repomanager/project.repomanager.service';
import { WorkflowTemplateService } from '../../../service/workflow-template/workflow-template.service';

Expand All @@ -28,17 +29,21 @@ export class WorkflowTemplateApplyFormComponent {
}
get project() { return this._project; }

@Input() workflow: Workflow;

_workflowTemplate: WorkflowTemplate;
@Input() set workflowTemplate(wt: WorkflowTemplate) {
this._workflowTemplate = wt;

this.parameterValues = {};

this._workflowTemplate.parameters.forEach(parameter => {
if (parameter.type === 'boolean') {
this.parameterValues[parameter.key] = new FormControl();
}
});
if (this._workflowTemplate.parameters) {
this._workflowTemplate.parameters.forEach(parameter => {
if (parameter.type === 'boolean') {
this.parameterValues[parameter.key] = new FormControl();
}
});
}

this.fillFormWithInstanceData();
}
Expand Down Expand Up @@ -75,33 +80,42 @@ export class WorkflowTemplateApplyFormComponent {
req.workflow_name = this.parameterName;
req.parameters = {};

this._workflowTemplate.parameters.forEach(parameter => {
if (this.parameterValues[parameter.key]) {
switch (parameter.type) {
case 'boolean':
req.parameters[parameter.key] = this.parameterValues[parameter.key] &&
!!this.parameterValues[parameter.key].value ? 'true' : 'false';
break;
case 'repository':
if (this.parameterValues[parameter.key + '-repository']) {
req.parameters[parameter.key] = this.parameterValues[parameter.key] + '/' +
this.parameterValues[parameter.key + '-repository'];
}
break;
default:
req.parameters[parameter.key] = this.parameterValues[parameter.key];
break;
if (this._workflowTemplate.parameters) {
this._workflowTemplate.parameters.forEach(parameter => {
if (this.parameterValues[parameter.key]) {
switch (parameter.type) {
case 'boolean':
req.parameters[parameter.key] = this.parameterValues[parameter.key] &&
!!this.parameterValues[parameter.key].value ? 'true' : 'false';
break;
case 'repository':
if (this.parameterValues[parameter.key + '-repository']) {
req.parameters[parameter.key] = this.parameterValues[parameter.key] + '/' +
this.parameterValues[parameter.key + '-repository'];
}
break;
default:
req.parameters[parameter.key] = this.parameterValues[parameter.key];
break;
}
}
}
});
});
}

this.result = null;
this.loading = true;
this._workflowTemplateService.applyWorkflowTemplate(this._workflowTemplate.group.name, this._workflowTemplate.slug, req)
.pipe(first(), finalize(() => this.loading = false))
.subscribe(res => {
// if the workflow name changed move to new workflow page
this.result = res;
this.apply.emit();

// specific check for case where workflow name change in template
if (res.workflow_name !== this.workflow.name) {
this._router.navigate(['/project', this.project.key, 'workflow', res.workflow_name]);
} else {
this.apply.emit();
}
});
}

Expand Down Expand Up @@ -143,30 +157,32 @@ export class WorkflowTemplateApplyFormComponent {
fillFormWithInstanceData(): void {
if (this._workflowTemplate && this._workflowTemplateInstance) {
this.parameterName = this._workflowTemplateInstance.request.workflow_name;
this._workflowTemplate.parameters.forEach(parameter => {

let v = this._workflowTemplateInstance.request.parameters[parameter.key];
if (v) {
switch (parameter.type) {
case 'boolean':
this.parameterValues[parameter.key].setValue(v === 'true');
break;
case 'repository':
let s = v.split('/');
if (s.length > 1) {
let existingVcs = this.vcsNames.find(vcs => vcs === s[0]);
if (existingVcs) {
this.parameterValues[parameter.key] = existingVcs;
this.fetchRepos(parameter.key, existingVcs);
if (this._workflowTemplate.parameters) {
this._workflowTemplate.parameters.forEach(parameter => {

let v = this._workflowTemplateInstance.request.parameters[parameter.key];
if (v) {
switch (parameter.type) {
case 'boolean':
this.parameterValues[parameter.key].setValue(v === 'true');
break;
case 'repository':
let s = v.split('/');
if (s.length > 1) {
let existingVcs = this.vcsNames.find(vcs => vcs === s[0]);
if (existingVcs) {
this.parameterValues[parameter.key] = existingVcs;
this.fetchRepos(parameter.key, existingVcs);
}
}
}
break;
default:
this.parameterValues[parameter.key] = v;
break;
break;
default:
this.parameterValues[parameter.key] = v;
break;
}
}
}
});
});
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<label>{{'workflow_name' | translate}}*</label>
<input class="ui input" type="text" name="workflow_name" [(ngModel)]="parameterName" [disabled]="_workflowTemplateInstance">
</div>
<div *ngIf="workflowTemplate.parameters.length > 0" class="wide field">
<div *ngIf="workflowTemplate.parameters && workflowTemplate.parameters.length > 0" class="wide field">
<label>{{'common_parameters' | translate}}</label>
</div>
<ng-container *ngFor="let parameter of workflowTemplate.parameters; let index = index">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<div *ngIf="diffVisible" class="ui wide sixteen field">
<app-diff-list [items]="diffItems"></app-diff-list>
</div>
<app-workflow-template-apply-form [project]="project" [workflowTemplate]="workflowTemplate"
<app-workflow-template-apply-form [project]="project" [workflow]="workflow" [workflowTemplate]="workflowTemplate"
[workflowTemplateInstance]="workflowTemplateInstance" [withClose]="true" (close)="close()"
(apply)="load()"></app-workflow-template-apply-form>
</div>
Expand Down

0 comments on commit 7a538e2

Please sign in to comment.