diff --git a/provider_tekton.go b/provider_tekton.go index 41f1587..d886f68 100644 --- a/provider_tekton.go +++ b/provider_tekton.go @@ -370,17 +370,38 @@ func buildTektonPipelineRun( if cfg.ServiceAccount != "" { spec["serviceAccountName"] = cfg.ServiceAccount } + + // Merge user-defined params with the built-in ones (commit, + // branch, actor). User params that collide with a built-in name + // win, so callers can override the defaults when the upstream + // Tekton Pipeline expects a different shape. if len(cfg.Params) > 0 { - keys := make([]string, 0, len(cfg.Params)) - for key := range cfg.Params { + builtins := map[string]string{ + "commit": commit, + "branch": branch, + "actor": actor, + } + + // Collect all param names, user params override built-ins. + merged := make(map[string]string, len(builtins)+len(cfg.Params)) + for k, v := range builtins { + merged[k] = v + } + for k, v := range cfg.Params { + merged[k] = v + } + + keys := make([]string, 0, len(merged)) + for key := range merged { keys = append(keys, key) } sort.Strings(keys) + params := make([]any, 0, len(keys)) for _, key := range keys { params = append(params, map[string]any{ "name": key, - "value": cfg.Params[key], + "value": merged[key], }) } spec["params"] = params diff --git a/provider_tekton_test.go b/provider_tekton_test.go index 1021ab6..2fbe56b 100644 --- a/provider_tekton_test.go +++ b/provider_tekton_test.go @@ -117,9 +117,12 @@ func TestTektonBuildPipelineRun(t *testing.T) { if !ok || sa != "runner" { t.Fatalf("serviceAccountName = %q", sa) } + // With cfg.Params={"image": "example/app"}, the merged params + // should contain the 3 built-ins (actor, branch, commit) plus + // the user-supplied "image" — 4 total, sorted alphabetically. params, ok := obj.NestedSlice("spec", "params") - if !ok || len(params) != 1 { - t.Fatalf("params = %+v", params) + if !ok || len(params) != 4 { + t.Fatalf("params count = %d, want 4: %+v", len(params), params) } if obj.GetAnnotations()[tektonAnnotationActor] != "did:plc:actor" || obj.GetAnnotations()[tektonAnnotationCommit] != "abcdef" { @@ -127,6 +130,42 @@ func TestTektonBuildPipelineRun(t *testing.T) { } } +func TestTektonBuildPipelineRunParamsOverride(t *testing.T) { + // When a user param collides with a built-in name, the user's + // value should win so callers can customize what the upstream + // Tekton Pipeline receives. + cfg := &tektonWorkflowConfig{ + Pipeline: "repo-ci", + Params: map[string]string{ + "commit": "user-override-sha", + "extra": "bonus", + }, + } + obj := buildTektonPipelineRun("ci", "run-1", cfg, + "knot.example.com", "rkey-1", "did:plc:actor", + "original-sha", "main", + &tangled.Pipeline_Workflow{Name: "ci.yml"}, + ) + params, ok := obj.NestedSlice("spec", "params") + if !ok { + t.Fatal("params missing") + } + // Expect 4: actor, branch, commit (overridden), extra. + if len(params) != 4 { + t.Fatalf("params count = %d, want 4: %+v", len(params), params) + } + // Verify the user override took effect. + for _, raw := range params { + p, _ := raw.(map[string]any) + if p["name"] == "commit" && p["value"] != "user-override-sha" { + t.Fatalf( + "commit param = %q, want user-override-sha", + p["value"], + ) + } + } +} + func TestTektonBuildPipelineRunWorkspaces(t *testing.T) { storage := "5Gi" pvc := "shared-cache"