diff --git a/cli/cdsctl/workflow_run_result.go b/cli/cdsctl/workflow_run_result.go index 3708feaecc..a1edc390d9 100644 --- a/cli/cdsctl/workflow_run_result.go +++ b/cli/cdsctl/workflow_run_result.go @@ -244,6 +244,7 @@ func toCLIRunResult(results []sdk.WorkflowRunResult) ([]RunResultCli, error) { return nil, err } name = artiResult.Name + artiType = artiResult.RepoType } cliresults = append(cliresults, RunResultCli{ diff --git a/ui/src/app/model/workflow.run.model.ts b/ui/src/app/model/workflow.run.model.ts index cf4b78b417..e31f5b5d30 100644 --- a/ui/src/app/model/workflow.run.model.ts +++ b/ui/src/app/model/workflow.run.model.ts @@ -146,6 +146,14 @@ export class WorkflowRunResult { data: any; } +export class UIArtifact { + name: string; + md5: string; + size: number; + link: string; + type: string; +} + export class WorkflowRunResultArtifact { name: string @@ -154,6 +162,15 @@ export class WorkflowRunResultArtifact { cdn_hash: string; } +export class WorkflowRunResultArtifactManager { + name: string; + size: number; + md5: string; + path: string; + repository_name: string; + repository_type: string; +} + export class WorkflowNodeOutgoingHookRunCallback { workflow_node_outgoing_hook_id: number; start: Date; diff --git a/ui/src/app/shared/table/data-table.html b/ui/src/app/shared/table/data-table.html index 58bb223d27..92aaea4095 100644 --- a/ui/src/app/shared/table/data-table.html +++ b/ui/src/app/shared/table/data-table.html @@ -99,11 +99,13 @@ {{' '}}{{l.title | translate}}
- - + + + +
{{c.selector.value | diff --git a/ui/src/app/views/workflow/run/node/artifact/artifact.list.component.ts b/ui/src/app/views/workflow/run/node/artifact/artifact.list.component.ts index 02c94a1709..7984b8dbfb 100644 --- a/ui/src/app/views/workflow/run/node/artifact/artifact.list.component.ts +++ b/ui/src/app/views/workflow/run/node/artifact/artifact.list.component.ts @@ -1,16 +1,18 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { Select, Store } from '@ngxs/store'; import { + UIArtifact, WorkflowNodeRun, WorkflowNodeRunArtifact, - WorkflowNodeRunStaticFiles, - WorkflowRunResultArtifact + WorkflowNodeRunStaticFiles, WorkflowRunResult, + WorkflowRunResultArtifact, WorkflowRunResultArtifactManager } from 'app/model/workflow.run.model'; import { AutoUnsubscribe } from 'app/shared/decorator/autoUnsubscribe'; import { Column, ColumnType, Filter } from 'app/shared/table/data-table.component'; import { WorkflowState } from 'app/store/workflow.state'; import { Observable, Subscription } from 'rxjs'; +import { Workflow } from 'app/model/workflow.model'; @Component({ selector: 'app-workflow-artifact-list', @@ -23,42 +25,46 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy { @Select(WorkflowState.getSelectedNodeRun()) nodeRun$: Observable; nodeRunSubs: Subscription; + runResult: Array artifacts: Array; + + uiArtifacts: Array; staticFiles: Array; - filter: Filter; - columns: Array>; + filter: Filter; + columns: Array>; constructor(private _cd: ChangeDetectorRef, private _store: Store) { this.filter = f => { const lowerFilter = f.toLowerCase(); return d => d.name.toLowerCase().indexOf(lowerFilter) !== -1 || - d.sha512sum.toLowerCase().indexOf(lowerFilter) !== -1 + d.md5.toLowerCase().indexOf(lowerFilter) !== -1 }; this.columns = [ - >{ + >{ type: ColumnType.LINK, name: 'artifact_name', - selector: (a: WorkflowNodeRunArtifact) => { + selector: (a: UIArtifact) => { let size = this.getHumainFileSize(a.size); - let link = `./cdsapi/workflow/artifact/${a.download_hash}` - if (!a.id) { - link = `./cdscdn/item/run-result/${a.download_hash}/download` + let link = a.link; + let value = a.name; + if (size) { + value += ` (${size})`; } return { link, - value: `${a.name} (${size})` + value }; } }, - >{ - name: 'artifact_tag', - selector: (a: WorkflowNodeRunArtifact) => a.tag + >{ + name: 'Type of artifact', + selector: (a: UIArtifact) => a.type }, - >{ + >{ type: ColumnType.TEXT_COPY, name: 'MD5 Sum', - selector: (a: WorkflowNodeRunArtifact) => a.md5sum + selector: (a: UIArtifact) => a.md5 } ]; } @@ -70,16 +76,36 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy { if (!nr) { return; } - let resultArtifacts = nr?.results.filter(r => r.type === 'artifact').map(r => r.data); - if (!resultArtifacts) { - resultArtifacts = new Array(); + + let computeArtifact = false; + if (nr.results && (!this.runResult || nr.results.length !== this.runResult.length)) { + computeArtifact = true + } + if (nr.artifacts && (!this.artifacts || nr.artifacts.length !== this.artifacts.length)) { + computeArtifact = true } - if ( (!this.artifacts && (nr.artifacts || resultArtifacts.length > 0)) || (this.artifacts && nr.artifacts && this.artifacts.length !== (nr.artifacts.length + resultArtifacts.length))) { - this.artifacts = new Array(); + if (computeArtifact) { + let uiArtifacts: Array; + let uiRunResults: Array; + this.uiArtifacts = new Array(); + if (nr.results) { + let w = this._store.selectSnapshot(WorkflowState.workflowRunSnapshot).workflow + uiRunResults = this.toUIArtifact(w, nr.results); + this.uiArtifacts.push(...uiRunResults); + } + if (nr.artifacts) { - this.artifacts.push(...nr.artifacts); + uiArtifacts = nr.artifacts.map(a => { + let uiArt = new UIArtifact(); + uiArt.name = a.name; + uiArt.size = a.size; + uiArt.md5 = a.md5sum; + uiArt.type = 'file'; + uiArt.link = `./cdscdn/item/artifact/${a.download_hash}/download`; + return uiArt; + }); + this.uiArtifacts.push(...uiArtifacts) } - this.artifacts.push(...this.toWorkflowNodeRunArtifacts(resultArtifacts)); this._cd.markForCheck(); } if ((!this.staticFiles && nr.static_files) || @@ -90,25 +116,52 @@ export class WorkflowRunArtifactListComponent implements OnInit, OnDestroy { }); } - toWorkflowNodeRunArtifacts(results: Array): Array { - let arts = new Array(); - results.forEach(r => { - let a = new WorkflowNodeRunArtifact(); - a.download_hash = r.cdn_hash; - a.md5sum = r.md5; - a.size = r.size; - a.name = r.name; - arts.push(a); - }) - return arts; - } - getHumainFileSize(size: number): string { if (size === 0) { - return '0B'; + return ''; } let i = Math.floor(Math.log(size) / Math.log(1024)); let hSize = (size / Math.pow(1024, i)).toFixed(2); return hSize + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; } + + private toUIArtifact(w: Workflow, results: Array): Array { + if (!results) { + return []; + } + let integrationArtifactManagerURL = ''; + if (w?.integrations) { + for (let i = 0; i < w.integrations.length; i++) { + let integ = w.integrations[i]; + if (!integ.project_integration.model.artifact_manager) { + continue + } + integrationArtifactManagerURL = integ?.project_integration?.config['url']?.value; + } + } + + return results.map(r => { + switch (r.type) { + case 'artifact': + case 'coverage': + let data = r.data; + let uiArtifact = new UIArtifact(); + uiArtifact.link = `./cdscdn/item/run-result/${data.cdn_hash}/download`; + uiArtifact.md5 = data.md5; + uiArtifact.name = data.name; + uiArtifact.size = data.size; + uiArtifact.type = 'file'; + return uiArtifact; + case 'artifact-manager': + let dataAM = r.data; + let uiArtifactAM = new UIArtifact(); + uiArtifactAM.link = `${integrationArtifactManagerURL}${dataAM.repository_name}/${dataAM.path}`; + uiArtifactAM.md5 = dataAM.md5; + uiArtifactAM.name = dataAM.name; + uiArtifactAM.size = dataAM.size; + uiArtifactAM.type = dataAM.repository_type; + return uiArtifactAM; + } + }) + } } diff --git a/ui/src/app/views/workflow/run/node/artifact/artifact.list.html b/ui/src/app/views/workflow/run/node/artifact/artifact.list.html index b387a4ad91..1e9895b1a0 100644 --- a/ui/src/app/views/workflow/run/node/artifact/artifact.list.html +++ b/ui/src/app/views/workflow/run/node/artifact/artifact.list.html @@ -1,4 +1,4 @@ -
+
@@ -21,5 +21,5 @@
- -
\ No newline at end of file + +
diff --git a/ui/src/app/views/workflow/run/node/workflow.run.node.component.ts b/ui/src/app/views/workflow/run/node/workflow.run.node.component.ts index 594766e938..aaadeed5a4 100644 --- a/ui/src/app/views/workflow/run/node/workflow.run.node.component.ts +++ b/ui/src/app/views/workflow/run/node/workflow.run.node.component.ts @@ -124,16 +124,13 @@ export class WorkflowNodeRunComponent implements OnInit, OnDestroy { refresh = true; } - let artiResults = nr?.results?.filter(r => r.type === 'artifact'); - let artiResultsLength = 0; - if (artiResults) { - artiResultsLength = artiResults.length - } + + let artiResultsLength = nr?.results?.length ?? 0 let oldArtiLength = 0; if (nr.artifacts) { oldArtiLength = nr.artifacts.length; } - if ((nr.artifacts || artiResults) && (oldArtiLength + artiResultsLength) !== this.artifactLength) { + if ((nr.artifacts || artiResultsLength > 0) && (oldArtiLength + artiResultsLength) !== this.artifactLength) { this.artifactLength = oldArtiLength + artiResultsLength; refresh = true; } diff --git a/ui/src/assets/i18n/en.json b/ui/src/assets/i18n/en.json index 4deaf86a85..8a8bf7ede7 100644 --- a/ui/src/assets/i18n/en.json +++ b/ui/src/assets/i18n/en.json @@ -98,7 +98,6 @@ "application_variable_list_title": "List of application variables: ", "application_variable_form_title": "Add a new variable: ", "artifact_name": "Artifact name", - "artifact_tag": "Tag", "ascode_error_unknown_type": "Cannot determine the resource to update", "ascode_modal_title": "Save as code", "ascode_modal_label_branch": "Select or create a branch",