Skip to content

Commit 35bd553

Browse files
committed
fix(opscomments): skip key=value args as PR names
When a user posts "/test custom1=value", the key=value argument was being treated as a PipelineRun name, which bypassed on-comment annotation matching. Return empty string when the first argument contains "=" so the comment falls through to on-comment handling. Signed-off-by: Akshay Pant <akpant@redhat.com> Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e951778 commit 35bd553

6 files changed

Lines changed: 134 additions & 4 deletions

File tree

pkg/opscomments/comments.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ func getNameFromComment(typeOfComment, comment string) string {
182182
return ""
183183
}
184184

185-
// trim spaces
186-
return strings.TrimSpace(firstArg[1])
185+
name := strings.TrimSpace(firstArg[1])
186+
if strings.Contains(name, "=") {
187+
return ""
188+
}
189+
return name
187190
}

pkg/opscomments/comments_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ func TestGetNameFromFunction(t *testing.T) {
8686
expected: "prname",
8787
commentType: testComment,
8888
},
89+
{
90+
name: "key value arg is not a pipeline name",
91+
comment: "/test custom1=value",
92+
expected: "",
93+
commentType: testComment,
94+
},
95+
{
96+
name: "key value args without pipeline name",
97+
comment: "/test foo=bar hello=moto",
98+
expected: "",
99+
commentType: testComment,
100+
},
89101
{
90102
name: "get name from cancel comment",
91103
comment: "/cancel prname",
@@ -295,6 +307,12 @@ func TestSetEventTypeTestPipelineRun(t *testing.T) {
295307
wantType: TestSingleCommentEventType.String(),
296308
wantTestPr: "prname",
297309
},
310+
{
311+
name: "test with key value arg treated as test all",
312+
comment: "/test custom1=value",
313+
wantType: TestSingleCommentEventType.String(),
314+
wantTestPr: "",
315+
},
298316
{
299317
name: "cancel single pr",
300318
comment: "/cancel prname",

pkg/provider/provider.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,18 @@ func getNameFromComment(typeOfComment, comment string) string {
106106
splitTest := strings.Split(comment, typeOfComment)
107107
// now get the first line
108108
getFirstLine := strings.Split(splitTest[1], "\n")
109-
// trim spaces
110-
return strings.TrimSpace(getFirstLine[0])
109+
110+
// and the first argument
111+
firstArg := strings.Split(getFirstLine[0], " ")
112+
if len(firstArg) < 2 {
113+
return ""
114+
}
115+
116+
name := strings.TrimSpace(firstArg[1])
117+
if strings.Contains(name, "=") {
118+
return ""
119+
}
120+
return name
111121
}
112122

113123
func GetPipelineRunAndBranchOrTagNameFromTestComment(comment, prefix string) (string, string, string, error) {
@@ -157,6 +167,9 @@ func getPipelineRunAndBranchOrTagNameFromComment(typeOfComment, comment string)
157167
prData := strings.Split(strings.TrimSpace(branchData[0]), " ")
158168
if len(prData) > 1 {
159169
prName = strings.TrimSpace(prData[0])
170+
if strings.Contains(prName, "=") {
171+
prName = ""
172+
}
160173
}
161174
} else {
162175
// get the second part of the typeOfComment (/test, /retest or /cancel)
@@ -166,6 +179,9 @@ func getPipelineRunAndBranchOrTagNameFromComment(typeOfComment, comment string)
166179
// trim spaces
167180
// adapt for the comment contains the key=value pair
168181
prName = strings.Split(strings.TrimSpace(getFirstLine[0]), " ")[0]
182+
if strings.Contains(prName, "=") {
183+
prName = ""
184+
}
169185
}
170186
return prName, branchName, tagName, nil
171187
}

pkg/provider/provider_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ func TestGetPipelineRunFromComment(t *testing.T) {
214214
comment: "before \n /test abc-01-pr \n after",
215215
want: "abc-01-pr",
216216
},
217+
{
218+
name: "test with key value is not a pipeline name",
219+
comment: "/test custom1=value",
220+
want: "",
221+
},
217222
{
218223
name: "retest a pipeline",
219224
comment: "/retest abc-01-pr",
@@ -260,6 +265,11 @@ func TestGetPipelineRunFromCancelComment(t *testing.T) {
260265
comment: "/cancel abc-01-pr",
261266
want: "abc-01-pr",
262267
},
268+
{
269+
name: "cancel with key value is not a pipeline name",
270+
comment: "/cancel custom1=value",
271+
want: "",
272+
},
263273
{
264274
name: "string before cancel command",
265275
comment: "abc \n /cancel abc-01-pr",
@@ -365,6 +375,19 @@ func TestGetPipelineRunAndBranchNameFromTestComment(t *testing.T) {
365375
branchName: "",
366376
wantError: false,
367377
},
378+
{
379+
name: "test with only key value is not a pipeline name",
380+
comment: "/test custom1=value",
381+
prName: "",
382+
wantError: false,
383+
},
384+
{
385+
name: "test with key value and branch is not a pipeline name",
386+
comment: "/test custom1=value branch:nightly",
387+
prName: "",
388+
branchName: "nightly",
389+
wantError: false,
390+
},
368391
{
369392
name: "string before retest command",
370393
comment: "abc \n /retest abc-01-pr",

test/gitea_gitops_commands_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,57 @@ func TestGiteaOnCommentAnnotation(t *testing.T) {
130130
assert.NilError(t, err)
131131
}
132132

133+
// TestGiteaOnCommentTestOverride tests that a PipelineRun with
134+
// on-comment: "^/test.*" is triggered when posting "/test custom1=value".
135+
// This verifies that key=value arguments are not mistaken for a PipelineRun
136+
// name, which would bypass the on-comment annotation matching entirely.
137+
func TestGiteaOnCommentTestOverride(t *testing.T) {
138+
var err error
139+
ctx := context.Background()
140+
topts := &tgitea.TestOpts{
141+
TargetRefName: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-test"),
142+
RepoCRParams: &[]v1alpha1.Params{
143+
{
144+
Name: "custom1",
145+
Value: "default",
146+
},
147+
},
148+
}
149+
topts.TargetNS = topts.TargetRefName
150+
topts.ParamsRun, topts.Opts, topts.GiteaCNX, err = tgitea.Setup(ctx)
151+
assert.NilError(t, err, fmt.Errorf("cannot do gitea setup: %w", err))
152+
ctx, err = cctx.GetControllerCtxInfo(ctx, topts.ParamsRun)
153+
assert.NilError(t, err)
154+
assert.NilError(t, pacrepo.CreateNS(ctx, topts.TargetNS, topts.ParamsRun))
155+
assert.NilError(t, secret.Create(ctx, topts.ParamsRun, map[string]string{"secret": "SHHHHHHH"}, topts.TargetNS, "pac-secret"))
156+
topts.TargetEvent = triggertype.PullRequest.String()
157+
topts.YAMLFiles = map[string]string{
158+
".tekton/on-comment-test-override.yaml": "testdata/pipelinerun-on-comment-test-override.yaml",
159+
}
160+
topts.ExpectEvents = false
161+
_, f := tgitea.TestPR(t, topts)
162+
defer f()
163+
164+
tgitea.PostCommentOnPullRequest(t, topts, "/test custom1=overridden")
165+
waitOpts := twait.Opts{
166+
RepoName: topts.TargetNS,
167+
Namespace: topts.TargetNS,
168+
MinNumberStatus: 1,
169+
PollTimeout: twait.DefaultTimeout,
170+
}
171+
repo, err := twait.UntilRepositoryUpdated(context.Background(), topts.ParamsRun.Clients, waitOpts)
172+
assert.NilError(t, err)
173+
assert.Equal(t, len(repo.Status), 1, "should have exactly 1 status")
174+
assert.Equal(t, *repo.Status[0].EventType, opscomments.OnCommentEventType.String(),
175+
"should have matched via on-comment annotation, not built-in /test handler")
176+
177+
last := repo.Status[0]
178+
err = twait.RegexpMatchingInPodLog(context.Background(), topts.ParamsRun, topts.TargetNS,
179+
fmt.Sprintf("tekton.dev/pipelineRun=%s", last.PipelineRunName), "step-task",
180+
*regexp.MustCompile("custom1 is overridden"), "", 2, nil)
181+
assert.NilError(t, err)
182+
}
183+
133184
// TestGiteaTestPipelineRunExplicitlyWithTestComment will test a pipelinerun
134185
// even if it hasn't matched when we are doing a /test comment.
135186
func TestGiteaTestPipelineRunExplicitlyWithTestComment(t *testing.T) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
apiVersion: tekton.dev/v1beta1
3+
kind: PipelineRun
4+
metadata:
5+
name: "on-comment-test-override"
6+
annotations:
7+
pipelinesascode.tekton.dev/target-namespace: "\\ .TargetNamespace //"
8+
pipelinesascode.tekton.dev/on-comment: "^/test.*"
9+
spec:
10+
pipelineSpec:
11+
tasks:
12+
- name: task
13+
taskSpec:
14+
steps:
15+
- name: task
16+
image: registry.access.redhat.com/ubi10/ubi-micro
17+
script: |
18+
echo "event_type is {{ event_type }}"
19+
echo "custom1 is {{ custom1 }}"

0 commit comments

Comments
 (0)