Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: start workflow with a fork #5109

Merged
merged 2 commits into from Apr 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 9 additions & 6 deletions engine/api/workflow/dao.go
Expand Up @@ -1183,6 +1183,9 @@ func checkHooks(db gorp.SqlExecutor, w *sdk.Workflow, n *sdk.Node) error {
w.HookModels[hm.ID] = *hm
h.HookModelID = hm.ID
}
if h.HookModelName == sdk.RepositoryWebHookModelName && (n.Context == nil || n.Context.ApplicationID == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a risk that we will be unable to load some existing workflows, we have to make a migration is any

return sdk.WrapError(sdk.ErrApplicationNotFound, "unable to find application for the repository web hook: %d: %s/%s", w.ID, w.Name, n.Name)
}

// Add missing default value for hook
model := w.HookModels[h.HookModelID]
Expand Down Expand Up @@ -1427,8 +1430,8 @@ func Push(ctx context.Context, db *gorp.DbMap, store cache.Store, proj *sdk.Proj
fromRepo = opts.FromRepository
}
envDB, msgList, err := environment.ParseAndImport(tx, *proj, env, environment.ImportOptions{Force: true, FromRepository: fromRepo}, decryptFunc, u)
allMsg = append(allMsg, msgList...)
if err != nil {
allMsg = append(allMsg, msgList...)
if err != nil {
return allMsg, nil, nil, sdk.ErrorWithFallback(err, sdk.ErrWrongRequest, "unable to import environment %s/%s", proj.Key, env.Name)
}
proj.SetEnvironment(*envDB)
Expand All @@ -1440,8 +1443,8 @@ func Push(ctx context.Context, db *gorp.DbMap, store cache.Store, proj *sdk.Proj
fromRepo = opts.FromRepository
}
pipDB, msgList, err := pipeline.ParseAndImport(ctx, tx, store, *proj, &pip, u, pipeline.ImportOptions{Force: true, FromRepository: fromRepo})
allMsg = append(allMsg, msgList...)
if err != nil {
allMsg = append(allMsg, msgList...)
if err != nil {
return allMsg, nil, nil, sdk.ErrorWithFallback(err, sdk.ErrWrongRequest, "unable to import pipeline %s/%s", proj.Key, pip.Name)
}
proj.SetPipeline(*pipDB)
Expand All @@ -1467,8 +1470,8 @@ func Push(ctx context.Context, db *gorp.DbMap, store cache.Store, proj *sdk.Proj
}

wf, msgList, err := ParseAndImport(ctx, tx, store, *proj, oldWf, data.Workflow, u, importOptions)
allMsg = append(allMsg, msgList...)
if err != nil {
allMsg = append(allMsg, msgList...)
if err != nil {
return allMsg, nil, nil, sdk.WrapError(err, "unable to import workflow %s", data.Workflow.GetName())
}

Expand Down
6 changes: 3 additions & 3 deletions engine/api/workflow/process_node.go
Expand Up @@ -83,7 +83,7 @@ func processNodeRun(ctx context.Context, db gorp.SqlExecutor, store cache.Store,

switch n.Type {
case sdk.NodeTypeFork, sdk.NodeTypePipeline, sdk.NodeTypeJoin:
r1, conditionOK, errT := processNode(ctx, db, store, proj, wr, mapNodes, n, subNumber, parentNodeRuns, hookEvent, manual)
r1, conditionOK, errT := processNode(ctx, db, store, proj, wr, n, subNumber, parentNodeRuns, hookEvent, manual)
if errT != nil {
return nil, false, sdk.WrapError(errT, "Unable to processNode")
}
Expand All @@ -101,7 +101,7 @@ func processNodeRun(ctx context.Context, db gorp.SqlExecutor, store cache.Store,
}

func processNode(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sdk.Project, wr *sdk.WorkflowRun,
mapNodes map[int64]*sdk.Node, n *sdk.Node, subNumber int, parents []*sdk.WorkflowNodeRun,
n *sdk.Node, subNumber int, parents []*sdk.WorkflowNodeRun,
hookEvent *sdk.WorkflowNodeRunHookEvent, manual *sdk.WorkflowNodeRunManual) (*ProcessorReport, bool, error) {
report := new(ProcessorReport)

Expand Down Expand Up @@ -361,7 +361,7 @@ func processNode(ctx context.Context, db gorp.SqlExecutor, store cache.Store, pr
or
(workflow_node_run.id <> $2 and workflow_node_run.status = $5)
)`
nbMutex, err := db.SelectInt(mutexQuery, n.WorkflowID, nr.ID, n.Name, string(sdk.StatusWaiting), string(sdk.StatusBuilding))
nbMutex, err := db.SelectInt(mutexQuery, n.WorkflowID, nr.ID, n.Name, sdk.StatusWaiting, sdk.StatusBuilding)
if err != nil {
return nil, false, sdk.WrapError(err, "unable to check mutexes")
}
Expand Down
Expand Up @@ -11,7 +11,7 @@
<div class="four wide column">
<div class="ui secondary vertical pointing menu">
<ng-container *ngIf="!hookSelected">
<ng-container *ngIf="currentNodeType === 'pipeline'">
<ng-container *ngIf="currentNodeType === 'pipeline' || currentNodeType === 'fork'">
<a class="item" [class.active]="selected === 'context'" (click)="changeView('context')">
{{ 'workflow_node_context_label' | translate }}
</a>
Expand Down
Expand Up @@ -23,7 +23,7 @@ import { PipelinesState, PipelinesStateModel } from 'app/store/pipelines.state';
import { AddEnvironmentInProject } from 'app/store/project.action';
import { ProjectState, ProjectStateModel } from 'app/store/project.state';
import cloneDeep from 'lodash-es/cloneDeep';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { Observable, of as observableOf } from 'rxjs';
import { filter, finalize, first, flatMap, map } from 'rxjs/operators';

@Component({
Expand All @@ -44,6 +44,7 @@ export class WorkflowNodeAddWizardComponent implements OnInit {
@Input() hideCancel: boolean;
@Input() hideNext: boolean;
@Input() loading: boolean;
@Input() canCreateFork: boolean;
@Output() nodeCreated: EventEmitter<WNode> = new EventEmitter<WNode>();
@Output() pipelineSectionChanged: EventEmitter<string> = new EventEmitter<string>();

Expand Down Expand Up @@ -109,7 +110,7 @@ export class WorkflowNodeAddWizardComponent implements OnInit {
_createNewEnvironment = false;
integrations: IdName[] = [];
loadingIntegrations = false;
pipSubscription: Subscription;
createFork = false;

constructor(
private _router: Router,
Expand Down Expand Up @@ -155,6 +156,8 @@ export class WorkflowNodeAddWizardComponent implements OnInit {
if (this.node.context.pipeline_id) {
this.node.type = WNodeType.PIPELINE;
this.node.context.pipeline_id = Number(this.node.context.pipeline_id);
} else {
this.node.type = WNodeType.FORK;
}
if (this.node.context.application_id) {
this.node.context.application_id = Number(this.node.context.application_id);
Expand Down
43 changes: 28 additions & 15 deletions ui/src/app/shared/workflow/wizard/node-add/node.wizard.html
Expand Up @@ -49,15 +49,24 @@
<div *ngSwitchCase="'pipeline'">
<div class="ui row mb20">
<div class="ui sixteen wide column">
<div class="two ui buttons">
<div class="ui buttons" [class.three]="canCreateFork" [class.two]="!canCreateFork">
<button *ngIf="canCreateFork"
class="ui button"
type="button"
[class.active]="createFork && !createNewPipeline"
[class.blue]="createFork"
(click)="createFork = true"
>
{{ 'workflow_start_with_fork' | translate}}
</button>
<button class="ui button"
type="button"
[class.active]="!createNewPipeline" [class.blue]="!createNewPipeline"
[class.active]="!createNewPipeline && !createFork" [class.blue]="!createNewPipeline && !createFork"
[class.disabled]="!project.pipeline_names || !project.pipeline_names.length"
(click)="createNewPipeline = false">
(click)="createNewPipeline = false; createFork = false">
{{'common_select' | translate}}
</button>
<button class="ui button" type="button" [class.active]="createNewPipeline" [class.blue]="createNewPipeline" (click)="createNewPipeline = true">
<button class="ui button" type="button" [class.active]="createNewPipeline" [class.blue]="createNewPipeline" (click)="createNewPipeline = true; createFork = false">
{{'common_create' | translate}}
</button>
</div>
Expand All @@ -68,8 +77,8 @@
<ng-container >
<div class="fields">
<div class="six wide field">
<label>{{'pipeline_name' | translate}}</label>
<ng-container *ngIf="!createNewPipeline">
<ng-container *ngIf="!createNewPipeline && !createFork">
<label>{{'pipeline_name' | translate}}</label>
<sm-select
class="search"
placeholder="{{ 'common_pipeline' | translate }}"
Expand All @@ -80,13 +89,17 @@
</sm-select>
</ng-container>
<ng-container *ngIf="createNewPipeline">
<input type="text" name="pipname" [(ngModel)]="newPipeline.name" [placeholder]="'pipeline_name_new' | translate">
<div class="ui error message" *ngIf="errorPipelineNamePattern">
{{ 'pipeline_name_error' | translate }}
</div>
<label>{{'pipeline_name' | translate}}</label>
<input type="text" name="pipname" [(ngModel)]="newPipeline.name" [placeholder]="'pipeline_name_new' | translate">
<div class="ui error message" *ngIf="errorPipelineNamePattern">
{{ 'pipeline_name_error' | translate }}
</div>
</ng-container>
<ng-container *ngIf="createFork">

</ng-container>
</div>
<div class="ten wide field right aligned">
<div class="ten wide field right aligned" *ngIf="!createFork">
<div class="ui toggle checkbox ml10">
<input type="checkbox" id="mutex" name="mutex" [(ngModel)]="node.context.mutex">
<label for="mutex">
Expand All @@ -106,7 +119,7 @@
<button class="ui button" type="button" (click)="goToProject()" *ngIf="!hideCancel">{{ 'btn_cancel' | translate }}</button>
<button class="ui right floated green button" type="button" (click)="goToNextSection().subscribe()"
*ngIf="!hideNext"
[disabled]="!node.context.pipeline_id && !newPipeline.name" [class.loading]="loadingCreatePipeline">
[disabled]="!node.context.pipeline_id && !newPipeline.name && !createFork" [class.loading]="loadingCreatePipeline">
{{ 'btn_next' | translate }}
</button>
</div>
Expand Down Expand Up @@ -164,7 +177,7 @@
<button class="ui button" type="button" (click)="goToProject()" *ngIf="!hideCancel">{{ 'btn_cancel' | translate }}</button>
<button class="ui right floated green button" type="button" (click)="goToNextSection().subscribe()"
*ngIf="!hideNext"
[disabled]="!node.context.pipeline_id && !newPipeline.name" [class.loading]="loadingCreatePipeline">
[disabled]="!node.context.pipeline_id && !newPipeline.name && !createFork" [class.loading]="loadingCreatePipeline">
{{ 'btn_next' | translate }}
</button>
</div>
Expand Down Expand Up @@ -217,7 +230,7 @@
<div class="ui sixteen wide column">
<button class="ui button" type="button" (click)="goToProject()" *ngIf="!hideCancel">{{ 'btn_cancel' | translate }}</button>
<button class="ui right floated green button" type="button" *ngIf="!hideNext" (click)="goToNextSection().subscribe()"
[disabled]="!node.context.pipeline_id && !newPipeline.name" [class.loading]="loadingCreateEnvironment || loading">
[disabled]="!createFork && !node.context.pipeline_id && !newPipeline.name" [class.loading]="loadingCreateEnvironment || loading">
<span *ngIf="node.context.application_id && (loadingIntegrations || (integrations && integrations.length))">{{ 'btn_next' | translate }}</span>
<span *ngIf="!node.context.application_id || (!loadingIntegrations && (!integrations || !integrations.length))">{{ 'btn_finish' | translate }}</span>
</button>
Expand Down Expand Up @@ -249,7 +262,7 @@
<div class="ui sixteen wide column">
<button class="ui button" type="button" (click)="goToProject()" *ngIf="!hideCancel">{{ 'btn_cancel' | translate }}</button>
<button class="ui right floated green button" type="button" *ngIf="!hideNext" (click)="goToNextSection().subscribe()"
[disabled]="!node.context.pipeline_id && !newPipeline.name" [class.loading]="loading">
[disabled]="!createFork && !node.context.pipeline_id && !newPipeline.name" [class.loading]="loading">
{{ 'btn_finish' | translate }}
</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/views/workflow/add/workflow.add.html
Expand Up @@ -316,7 +316,7 @@ <h2>{{ 'workflow_create' | translate }}</h2>

<!-- ######### WORKFLOW PIPELINE SECOND STEP ######### -->
<ng-container *ngSwitchCase="1">
<app-workflow-node-add-wizard [project]="project" [loading]="loading"
<app-workflow-node-add-wizard [project]="project" [loading]="loading" [canCreateFork]="true"
(nodeCreated)="createWorkflow($event)"></app-workflow-node-add-wizard>
</ng-container>
</div>
Expand Down
1 change: 1 addition & 0 deletions ui/src/assets/i18n/en.json
Expand Up @@ -886,6 +886,7 @@
"workflow_logs_pretty_ansi": "Show pretty logs with ANSI interpreter",
"workflow_logs_pretty_html": "Show pretty logs with HTML interpreter",
"workflow_logs_raw": "Show raw logs (without ANSI and HTML interpreter)",
"workflow_start_with_fork": "Start with a fork",
"workflow_wizard_select_repo_man": "Select a repository manager",
"workflow_wizard_select_repo": "Select a repository",
"workflow_wizard_select_repo_loading": "Loading repositories...",
Expand Down
1 change: 1 addition & 0 deletions ui/src/assets/i18n/fr.json
Expand Up @@ -893,6 +893,7 @@
"workflow_run_with_parameters": "Lancer le workflow",
"workflow_runnumber_title": "Numéro de run courant",
"workflow_sidebar_tag_zone": "Tags à afficher dans la sidebar (ordonnés par priorité)",
"workflow_start_with_fork": "Commencer avec un embranchement",
"workflow_stopped": "Workflow arrêté",
"workflow_tag_dragdrop": "Drag & drop sur les tags pour modifier l'ordre",
"workflow_template_apply_detach": "Détacher le workflow généré du template.",
Expand Down