Skip to content

Commit dc7444b

Browse files
authored
fix(api): include repo type for run result unicity (#6184)
1 parent a070b16 commit dc7444b

13 files changed

+221
-42
lines changed

contrib/integrations/artifactory/plugin-artifactory-release/main.go

+9
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ func (e *artifactoryReleasePlugin) Run(ctx context.Context, opts *integrationplu
8686
return fail("unable to list run results: %v", err)
8787
}
8888

89+
fmt.Printf("Found %d run results\n", len(runResult))
90+
8991
log.SetLogger(log.NewLogger(log.INFO, os.Stdout))
9092
if distributionURL == "" {
9193
fmt.Printf("Using %s to release\n", artifactoryURL)
@@ -137,8 +139,15 @@ func (e *artifactoryReleasePlugin) Run(ctx context.Context, opts *integrationplu
137139
break
138140
}
139141
}
142+
name, err := r.ComputeName()
143+
if err != nil {
144+
return fail("unable to read result %s: %v", r.ID, err)
145+
}
140146
if skip {
147+
fmt.Printf("Result %q skipped\n", name)
141148
continue
149+
} else {
150+
fmt.Printf("Result %q to promote\n", name)
142151
}
143152
switch rData.RepoType {
144153
case "docker":

engine/api/workflow/workflow_run_results.go

+17-21
Original file line numberDiff line numberDiff line change
@@ -354,42 +354,38 @@ func insertResult(tx gorpmapper.SqlExecutorWithTx, runResult *sdk.WorkflowRunRes
354354
return nil
355355
}
356356

357-
func getAll(ctx context.Context, db gorp.SqlExecutor, query gorpmapping.Query) ([]sdk.WorkflowRunResult, error) {
357+
func getAll(ctx context.Context, db gorp.SqlExecutor, query gorpmapping.Query) (sdk.WorkflowRunResults, error) {
358358
var dbResults []dbRunResult
359359
if err := gorpmapping.GetAll(ctx, db, query, &dbResults); err != nil {
360360
return nil, err
361361
}
362-
results := make([]sdk.WorkflowRunResult, 0, len(dbResults))
362+
results := make(sdk.WorkflowRunResults, 0, len(dbResults))
363363
for _, r := range dbResults {
364364
results = append(results, sdk.WorkflowRunResult(r))
365365
}
366366
return results, nil
367367
}
368368

369-
func LoadRunResultsByRunID(ctx context.Context, db gorp.SqlExecutor, runID int64) ([]sdk.WorkflowRunResult, error) {
370-
dbQuery := `
371-
WITH allResults AS (
372-
SELECT data->>'name' AS name, sub_num, id
373-
FROM workflow_run_result
374-
WHERE workflow_run_id = $1
375-
),
376-
deduplication AS (
377-
SELECT distinct on (name) *
378-
FROM allResults
379-
ORDER BY name, sub_num DESC
380-
)
381-
SELECT * FROM workflow_run_result WHERE id IN (SELECT id FROM deduplication);`
382-
query := gorpmapping.NewQuery(dbQuery).Args(runID)
369+
func LoadRunResultsByRunID(ctx context.Context, db gorp.SqlExecutor, runID int64) (sdk.WorkflowRunResults, error) {
370+
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result WHERE workflow_run_id = $1 ORDER BY sub_num DESC").Args(runID)
383371
return getAll(ctx, db, query)
384372
}
385373

386-
func LoadRunResultsByNodeRunID(ctx context.Context, db gorp.SqlExecutor, nodeRunID int64) ([]sdk.WorkflowRunResult, error) {
387-
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result where workflow_node_run_id = $1").Args(nodeRunID)
388-
return getAll(ctx, db, query)
374+
func LoadRunResultsByRunIDUnique(ctx context.Context, db gorp.SqlExecutor, runID int64) (sdk.WorkflowRunResults, error) {
375+
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result WHERE workflow_run_id = $1 ORDER BY sub_num DESC").Args(runID)
376+
rs, err := getAll(ctx, db, query)
377+
if err != nil {
378+
return nil, err
379+
}
380+
return rs.Unique()
389381
}
390382

391-
func LoadRunResultsByRunIDAndType(ctx context.Context, db gorp.SqlExecutor, runID int64, t sdk.WorkflowRunResultType) ([]sdk.WorkflowRunResult, error) {
392-
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result where workflow_run_id = $1 AND type = $2").Args(runID, t)
383+
func LoadRunResultsByNodeRunID(ctx context.Context, db gorp.SqlExecutor, nodeRunID int64) (sdk.WorkflowRunResults, error) {
384+
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result WHERE workflow_node_run_id = $1").Args(nodeRunID)
393385
return getAll(ctx, db, query)
386+
}
394387

388+
func LoadRunResultsByRunIDAndType(ctx context.Context, db gorp.SqlExecutor, runID int64, t sdk.WorkflowRunResultType) (sdk.WorkflowRunResults, error) {
389+
query := gorpmapping.NewQuery("SELECT * FROM workflow_run_result WHERE workflow_run_id = $1 AND type = $2").Args(runID, t)
390+
return getAll(ctx, db, query)
395391
}

engine/api/workflow/workflow_run_results_test.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ func TestCanUploadArtifactAlreadyExist(t *testing.T) {
125125
Type: sdk.WorkflowRunResultTypeArtifact,
126126
}
127127
artiData := sdk.WorkflowRunResultArtifact{
128-
Name: "myartifact",
128+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
129+
Name: "myartifact",
130+
},
129131
CDNRefHash: "123",
130132
MD5: "123",
131133
Size: 1,
@@ -171,7 +173,9 @@ func TestCanUploadArtifactAlreadyExistInMoreRecentSubNum(t *testing.T) {
171173
Type: sdk.WorkflowRunResultTypeArtifact,
172174
}
173175
artiData := sdk.WorkflowRunResultArtifact{
174-
Name: "myartifact",
176+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
177+
Name: "myartifact",
178+
},
175179
CDNRefHash: "123",
176180
MD5: "123",
177181
Size: 1,
@@ -230,7 +234,9 @@ func TestCanUploadArtifactAlreadyExistInAPreviousSubNum(t *testing.T) {
230234
Type: sdk.WorkflowRunResultTypeArtifact,
231235
}
232236
artiData := sdk.WorkflowRunResultArtifact{
233-
Name: "myartifact",
237+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
238+
Name: "myartifact",
239+
},
234240
CDNRefHash: "123",
235241
MD5: "123",
236242
Size: 1,
@@ -275,7 +281,9 @@ func TestCanUploadStaticFile(t *testing.T) {
275281
Type: sdk.WorkflowRunResultTypeStaticFile,
276282
}
277283
artiData := sdk.WorkflowRunResultStaticFile{
278-
Name: "my title static file",
284+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
285+
Name: "my title static file",
286+
},
279287
RemoteURL: "https://foo/bar",
280288
}
281289
bts, err := json.Marshal(artiData)
@@ -309,7 +317,9 @@ func TestCanUploadStaticFileInvalid(t *testing.T) {
309317
Type: sdk.WorkflowRunResultTypeStaticFile,
310318
}
311319
artiData := sdk.WorkflowRunResultStaticFile{
312-
Name: "my title static file",
320+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
321+
Name: "my title static file",
322+
},
313323
RemoteURL: "",
314324
}
315325
bts, err := json.Marshal(artiData)

engine/api/workflow_purge_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,10 @@ func Test_Purge_DeleteArtifactsFromRepositoryManager(t *testing.T) {
234234
require.NoError(t, err)
235235

236236
data := sdk.WorkflowRunResultArtifactManager{
237+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
238+
Name: "foo",
239+
},
237240
Path: "path/to/foo",
238-
Name: "foo",
239241
RepoName: "repository",
240242
}
241243
rawData, _ := json.Marshal(data)

engine/api/workflow_queue_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1556,10 +1556,12 @@ func Test_workflowRunResultsAdd(t *testing.T) {
15561556
}
15571557

15581558
artiData := sdk.WorkflowRunResultArtifact{
1559+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
1560+
Name: "myartifact",
1561+
},
15591562
Size: 1,
15601563
MD5: "AA",
15611564
CDNRefHash: "AA",
1562-
Name: "myartifact",
15631565
Perm: 0777,
15641566
}
15651567
bts, err := json.Marshal(artiData)

engine/api/workflow_run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ func (api *API) getWorkflowRunResultsHandler() service.Handler {
13481348
return sdk.WrapError(err, "unable to load workflow run for workflow %s and number %d", name, number)
13491349
}
13501350

1351-
results, err := workflow.LoadRunResultsByRunID(ctx, api.mustDB(), wr.ID)
1351+
results, err := workflow.LoadRunResultsByRunIDUnique(ctx, api.mustDB(), wr.ID)
13521352
if err != nil {
13531353
return err
13541354
}

engine/api/workflow_run_result_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ func Test_getWorkflowRunAndNodeRunResults(t *testing.T) {
3838
require.NoError(t, err)
3939

4040
artiData := sdk.WorkflowRunResultArtifact{
41-
Name: "myarti",
41+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
42+
Name: "myarti",
43+
},
4244
CDNRefHash: "123",
4345
MD5: "123",
4446
Size: 1,

engine/cdn/cdn_file.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,19 @@ func (s *Service) storeFile(ctx context.Context, sig cdn.Signature, reader io.Re
152152
switch runResultApiRef.RunResultType {
153153
case sdk.WorkflowRunResultTypeArtifact:
154154
result = sdk.WorkflowRunResultArtifact{
155-
Name: apiRef.ToFilename(),
155+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
156+
Name: apiRef.ToFilename(),
157+
},
156158
Size: it.Size,
157159
MD5: it.MD5,
158160
CDNRefHash: it.APIRefHash,
159161
Perm: runResultApiRef.Perm,
160162
}
161163
case sdk.WorkflowRunResultTypeCoverage:
162164
result = sdk.WorkflowRunResultCoverage{
163-
Name: apiRef.ToFilename(),
165+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
166+
Name: apiRef.ToFilename(),
167+
},
164168
Size: it.Size,
165169
MD5: it.MD5,
166170
CDNRefHash: it.APIRefHash,

engine/worker/cmd_run_result.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ func addStaticFileRunResultCmd() func(cmd *cobra.Command, args []string) {
6868
}
6969

7070
payload := sdk.WorkflowRunResultStaticFile{
71-
Name: name,
71+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
72+
Name: name,
73+
},
7274
RemoteURL: remoteURL.String(),
7375
}
7476
data, _ := json.Marshal(payload)
@@ -109,7 +111,9 @@ func addArtifactManagerRunResultCmd() func(cmd *cobra.Command, args []string) {
109111
}
110112

111113
payload := sdk.WorkflowRunResultArtifactManager{
112-
Name: fileName,
114+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
115+
Name: fileName,
116+
},
113117
Perm: 0,
114118
Path: filePath,
115119
RepoName: repositoryName,

engine/worker/internal/action/builtin_artifact_upload.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ func addWorkflowRunResult(ctx context.Context, wk workerruntime.Runtime, filePat
250250
}
251251

252252
data := sdk.WorkflowRunResultArtifactManager{
253-
Name: uploadResult.Outputs[sdk.ArtifactUploadPluginOutputPathFileName],
253+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
254+
Name: uploadResult.Outputs[sdk.ArtifactUploadPluginOutputPathFileName],
255+
},
254256
Perm: uint32(perm),
255257
RepoName: uploadResult.Outputs[sdk.ArtifactUploadPluginOutputPathRepoName],
256258
Path: uploadResult.Outputs[sdk.ArtifactUploadPluginOutputPathFilePath],

engine/worker/internal/handler_run_result_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ func Test_addRunResultStaticFileHandler(t *testing.T) {
5454
).Times(1)
5555

5656
v := sdk.WorkflowRunResultStaticFile{
57-
Name: "foo",
57+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
58+
Name: "foo",
59+
},
5860
RemoteURL: "http://locat.local/static/foo.html",
5961
}
6062
buf, err := json.Marshal(v)
@@ -107,7 +109,9 @@ func Test_addRunResultArtifactManagerHandler(t *testing.T) {
107109
).Times(1)
108110

109111
v := sdk.WorkflowRunResultArtifactManager{
110-
Name: "foo",
112+
WorkflowRunResultArtifactCommon: sdk.WorkflowRunResultArtifactCommon{
113+
Name: "foo",
114+
},
111115
RepoName: "my-repo",
112116
}
113117
buf, err := json.Marshal(v)

sdk/workflow_run_result.go

+68-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package sdk
22

33
import (
44
"encoding/json"
5+
"fmt"
6+
"sort"
57
"time"
68
)
79

@@ -15,6 +17,28 @@ const (
1517
type WorkflowRunResultType string
1618
type WorkflowRunResultDataKey string
1719

20+
type WorkflowRunResults []WorkflowRunResult
21+
22+
// Unique returns the last version of each results
23+
func (w WorkflowRunResults) Unique() (WorkflowRunResults, error) {
24+
m := make(map[string]WorkflowRunResult, len(w))
25+
for i := range w {
26+
key, err := w[i].ComputeUniqueKey()
27+
if err != nil {
28+
return nil, err
29+
}
30+
if v, ok := m[key]; !ok || v.SubNum < w[i].SubNum {
31+
m[key] = w[i]
32+
}
33+
}
34+
filtered := make(WorkflowRunResults, 0, len(m))
35+
for _, v := range m {
36+
filtered = append(filtered, v)
37+
}
38+
sort.Slice(filtered, func(i, j int) bool { return filtered[i].Created.Before(filtered[j].Created) })
39+
return filtered, nil
40+
}
41+
1842
type WorkflowRunResult struct {
1943
ID string `json:"id" db:"id"`
2044
Created time.Time `json:"created" db:"created"`
@@ -26,12 +50,47 @@ type WorkflowRunResult struct {
2650
DataRaw json.RawMessage `json:"data" db:"data"`
2751
}
2852

53+
func (r WorkflowRunResult) ComputeUniqueKey() (string, error) {
54+
key := fmt.Sprintf("%d-%s", r.WorkflowRunID, r.Type)
55+
switch r.Type {
56+
case WorkflowRunResultTypeArtifactManager:
57+
var data WorkflowRunResultArtifactManager
58+
if err := json.Unmarshal(r.DataRaw, &data); err != nil {
59+
return "", WithStack(err)
60+
}
61+
key = key + "-" + data.Name + "-" + data.RepoType
62+
default:
63+
var data WorkflowRunResultArtifactCommon
64+
if err := json.Unmarshal(r.DataRaw, &data); err != nil {
65+
return "", WithStack(err)
66+
}
67+
key = key + "-" + data.Name
68+
}
69+
return key, nil
70+
}
71+
72+
func (r WorkflowRunResult) ComputeName() (string, error) {
73+
switch r.Type {
74+
case WorkflowRunResultTypeArtifactManager:
75+
var data WorkflowRunResultArtifactManager
76+
if err := json.Unmarshal(r.DataRaw, &data); err != nil {
77+
return "", WithStack(err)
78+
}
79+
return fmt.Sprintf("%s (%s: %s)", data.Name, r.Type, data.RepoType), nil
80+
default:
81+
var data WorkflowRunResultArtifactCommon
82+
if err := json.Unmarshal(r.DataRaw, &data); err != nil {
83+
return "", WithStack(err)
84+
}
85+
return fmt.Sprintf("%s (%s)", data.Name, r.Type), nil
86+
}
87+
}
88+
2989
func (r *WorkflowRunResult) GetArtifact() (WorkflowRunResultArtifact, error) {
3090
var data WorkflowRunResultArtifact
3191
if err := JSONUnmarshal(r.DataRaw, &data); err != nil {
3292
return data, WithStack(err)
3393
}
34-
3594
return data, nil
3695
}
3796

@@ -70,8 +129,12 @@ type WorkflowRunResultCheck struct {
70129
ResultType WorkflowRunResultType `json:"result_type"`
71130
}
72131

132+
type WorkflowRunResultArtifactCommon struct {
133+
Name string `json:"name"`
134+
}
135+
73136
type WorkflowRunResultArtifactManager struct {
74-
Name string `json:"name"`
137+
WorkflowRunResultArtifactCommon
75138
Size int64 `json:"size"`
76139
MD5 string `json:"md5"`
77140
Path string `json:"path"`
@@ -98,7 +161,7 @@ func (a *WorkflowRunResultArtifactManager) IsValid() error {
98161
}
99162

100163
type WorkflowRunResultStaticFile struct {
101-
Name string `json:"name"`
164+
WorkflowRunResultArtifactCommon
102165
RemoteURL string `json:"remote_url"`
103166
}
104167

@@ -113,7 +176,7 @@ func (a *WorkflowRunResultStaticFile) IsValid() error {
113176
}
114177

115178
type WorkflowRunResultArtifact struct {
116-
Name string `json:"name"`
179+
WorkflowRunResultArtifactCommon
117180
Size int64 `json:"size"`
118181
MD5 string `json:"md5"`
119182
CDNRefHash string `json:"cdn_hash"`
@@ -138,7 +201,7 @@ func (a *WorkflowRunResultArtifact) IsValid() error {
138201
}
139202

140203
type WorkflowRunResultCoverage struct {
141-
Name string `json:"name"`
204+
WorkflowRunResultArtifactCommon
142205
Size int64 `json:"size"`
143206
MD5 string `json:"md5"`
144207
CDNRefHash string `json:"cdn_hash"`

0 commit comments

Comments
 (0)