Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/302-pac-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ data:
# step of a task using StepActions. Set it to false to only report the tasks.
status-show-steps: "true"

# Enable or disable the feature to support edited comments events.
# When enabled, edited comments will be processed and PipelineRuns will be triggered on them.
# Default: false
support-edited-comments: "false"

kind: ConfigMap
metadata:
name: pipelines-as-code
Expand Down
16 changes: 16 additions & 0 deletions docs/content/docs/api/configmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,22 @@ require-ok-to-test-sha: "false"

{{< /param >}}

{{< tech_preview "Support for edited comments" >}}

{{< param name="support-edited-comments" type="boolean" default="false" id="param-support-edited-comments" >}}

Enables processing of edited comment events. When enabled, editing a comment that contains a GitOps command (such as `/test` or `/retest`) triggers the command as if it were a new comment. This is useful when you need to fix a typo in a command or change a PipelineRun name without posting a new comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the distinction of author's permissions, not the editor, being used should be documented given how this is worded "... as if it were a new comment"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider the scenario you mentioned in an earlier comment, comment author (without permissions on the repo) has a typo /ok-ot-test which is corrected by a repo maintainer, nothing will happen.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can hold off on this until the original query is addressed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

nothing will happen.

No, it will trigger PipelineRuns


When disabled (the default), only newly created comments trigger PipelineRuns. Edited comments are ignored.

Currently supported on GitHub only.

```yaml
support-edited-comments: "false"
```

{{< /param >}}

{{< param name="skip-push-event-for-pr-commits" type="boolean" default="true" id="param-skip-push-event-for-pr-commits" >}}
Prevents duplicate PipelineRuns when a commit appears in both a push event and a pull request. When a push event arrives from a commit that belongs to an open pull request, Pipelines-as-Code skips the push event.

Expand Down
21 changes: 21 additions & 0 deletions docs/content/docs/guides/gitops-commands/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,24 @@ Pipeline execution appears to be unstable due to external factors. Retesting thi
{{< callout type="info" >}}
GitOps commands such as `/test` and others do not work on closed pull requests or merge requests.
{{< /callout >}}

### Edited Comments

{{< tech_preview "Support for edited comments" >}}
{{< support_matrix github_app="true" github_webhook="true" forgejo="false" gitlab="false" bitbucket_cloud="false" bitbucket_datacenter="false" >}}

By default, Pipelines-as-Code only processes **newly created** comments. If you edit an existing comment to add or change a GitOps command, it is ignored.

When the `support-edited-comments` setting is enabled in the [Pipelines-as-Code ConfigMap]({{< relref "/docs/api/configmap" >}}), edited comments are processed just like new ones. This means you can edit a comment to fix a typo in a command or change a PipelineRun name, and Pipelines-as-Code triggers the updated command.

To enable this feature, set the following in the `pipelines-as-code` ConfigMap:

```yaml
support-edited-comments: "true"
```

Pipelines-as-Code fetches pull request details from the GitHub API before checking a comment for GitOps commands. Enabling edited comment support also makes this API request for each processed comment edit, including edits to ordinary comments or commands intended for other CI systems. Each request counts toward the API rate limit of the token used by Pipelines-as-Code.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice, thanks!


{{< callout type="warning" >}}
Enabling edited comment support means that editing any comment on a pull request that contains a GitOps command (such as `/test` or `/retest`) will re-trigger the associated PipelineRuns. Be cautious when editing older comments that contain commands.
{{< /callout >}}
5 changes: 3 additions & 2 deletions pkg/adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (l listener) handleEvent(ctx context.Context) http.HandlerFunc {
if isIncoming {
gitProvider, logger, err = l.processIncoming(event, targettedRepo)
} else {
gitProvider, logger, err = l.detectProvider(request, string(payload))
gitProvider, logger, err = l.detectProvider(request, string(payload), &pacInfo)
}

// figure out which provider request coming from
Expand Down Expand Up @@ -335,7 +335,7 @@ func (l listener) processRes(processEvent bool, provider provider.Interface, log
return nil, logger, fmt.Errorf("skipping non supported event")
}

func (l listener) detectProvider(req *http.Request, reqBody string) (provider.Interface, *zap.SugaredLogger, error) {
func (l listener) detectProvider(req *http.Request, reqBody string, pacInfo *info.PacOpts) (provider.Interface, *zap.SugaredLogger, error) {
log := *l.logger

// payload validation
Expand All @@ -346,6 +346,7 @@ func (l listener) detectProvider(req *http.Request, reqBody string) (provider.In

gitHub := github.New()
gitHub.Run = l.run
gitHub.SetPacInfo(pacInfo)
isGH, processReq, logger, reason, err := gitHub.Detect(req, reqBody, &log)
if isGH {
return l.processRes(processReq, gitHub, logger, reason, err)
Expand Down
5 changes: 3 additions & 2 deletions pkg/adapter/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func TestWhichProvider(t *testing.T) {
Header: tt.header,
}

_, _, err = l.detectProvider(req, string(jeez))
_, _, err = l.detectProvider(req, string(jeez), &info.PacOpts{})
if tt.wantErrString != "" {
assert.ErrorContains(t, err, tt.wantErrString)
return
Expand Down Expand Up @@ -359,9 +359,10 @@ func TestDetectProviderAdditionalProviders(t *testing.T) {
assert.NilError(t, err)
body = string(payload)
}
pacInfo := &info.PacOpts{}

req := &http.Request{Header: tt.header}
gotProvider, gotLogger, err := l.detectProvider(req, body)
gotProvider, gotLogger, err := l.detectProvider(req, body, pacInfo)
assert.NilError(t, err)
assert.Assert(t, gotProvider != nil)
assert.Assert(t, gotLogger != nil)
Expand Down
3 changes: 3 additions & 0 deletions pkg/params/settings/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ type Settings struct {
RememberOKToTest bool `json:"remember-ok-to-test"`
RequireOkToTestSHA bool `json:"require-ok-to-test-sha"`

// SupportEditedComments enables or disables the feature to support edited comments events.
SupportEditedComments bool `default:"false" json:"support-edited-comments"`

// Retry Git provider API requests on rate limits and transient errors.
// Disabled by default.
EnableAPIRetry bool `default:"false" json:"enable-api-retry"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/params/settings/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestSyncConfig(t *testing.T) {
EnableCancelInProgressOnPullRequests: false,
EnableCancelInProgressOnPush: false,
SkipPushEventForPRCommits: true,
SupportEditedComments: false,
StatusShowSteps: true,
CustomConsoleName: "",
CustomConsoleURL: "",
Expand Down Expand Up @@ -80,6 +81,7 @@ func TestSyncConfig(t *testing.T) {
"custom-console-url-namespace": "https://custom-console-namespace",
"remember-ok-to-test": "false",
"skip-push-event-for-pr-commits": "true",
"support-edited-comments": "false",
"require-ok-to-test-sha": "true",
},
expectedStruct: Settings{
Expand All @@ -105,6 +107,7 @@ func TestSyncConfig(t *testing.T) {
EnableCancelInProgressOnPullRequests: false,
EnableCancelInProgressOnPush: false,
SkipPushEventForPRCommits: true,
SupportEditedComments: false,
StatusShowSteps: true,
CustomConsoleName: "custom-console",
CustomConsoleURL: "https://custom-console",
Expand Down
6 changes: 4 additions & 2 deletions pkg/provider/github/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func (v *Provider) detectTriggerTypeFromPayload(ghEventType string, eventInt any
}
return "", fmt.Sprintf("pull_request: unsupported action \"%s\"", event.GetAction())
case *github.IssueCommentEvent:
if event.GetAction() != "created" {
isEdiCommentEvent := event.GetAction() == "edited" && v.pacInfo.SupportEditedComments
if event.GetAction() != "created" && !isEdiCommentEvent {
return "", fmt.Sprintf("issue_comment: unsupported action \"%s\"", event.GetAction())
}

Expand Down Expand Up @@ -104,7 +105,8 @@ func (v *Provider) detectTriggerTypeFromPayload(ghEventType string, eventInt any
}
return "", fmt.Sprintf("check_run: unsupported action \"%s\"", event.GetAction())
case *github.CommitCommentEvent:
if event.GetAction() != "created" {
isEdiCommentEvent := event.GetAction() == "edited" && v.pacInfo.SupportEditedComments
if event.GetAction() != "created" && !isEdiCommentEvent {
return "", fmt.Sprintf("commit_comment: unsupported action \"%s\"", event.GetAction())
}

Expand Down
90 changes: 82 additions & 8 deletions pkg/provider/github/detect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ import (
"testing"

"github.com/google/go-github/v91/github"
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
"github.com/openshift-pipelines/pipelines-as-code/pkg/test/logger"
"gotest.tools/v3/assert"
)

func TestProviderDetect(t *testing.T) {
idd := int64(123)
tests := []struct {
name string
wantErrString string
isGH bool
processReq bool
event any
eventType string
wantReason string
name string
wantErrString string
isGH bool
processReq bool
event any
supportEditedComments bool
eventType string
wantReason string
}{
{
name: "not a github Event",
Expand Down Expand Up @@ -267,6 +269,47 @@ func TestProviderDetect(t *testing.T) {
isGH: true,
processReq: true,
},
{
name: "issue comment Event with edited action",
event: github.IssueCommentEvent{
Action: new("edited"),
Issue: &github.Issue{
PullRequestLinks: &github.PullRequestLinks{
URL: new("url"),
},
State: new("open"),
},
Installation: &github.Installation{
ID: &idd,
},
Comment: &github.IssueComment{Body: new("I am edited")},
},
eventType: "issue_comment",
supportEditedComments: true,
isGH: true,
processReq: true,
},
{
name: "issue comment Event with edited action and support edited comments is disabled",
event: github.IssueCommentEvent{
Action: new("edited"),
Issue: &github.Issue{
PullRequestLinks: &github.PullRequestLinks{
URL: new("url"),
},
State: new("open"),
},
Installation: &github.Installation{
ID: &idd,
},
Comment: &github.IssueComment{Body: new("I am edited")},
},
eventType: "issue_comment",
supportEditedComments: false,
isGH: true,
processReq: false,
wantReason: "issue_comment: unsupported action \"edited\"",
},
{
name: "commit comment event with cancel comment",
event: github.CommitCommentEvent{
Expand All @@ -280,6 +323,33 @@ func TestProviderDetect(t *testing.T) {
isGH: true,
processReq: true,
},
{
name: "commit comment Event with edited action",
event: github.CommitCommentEvent{
Action: new("edited"),
Installation: &github.Installation{
ID: &idd,
},
},
eventType: "commit_comment",
supportEditedComments: true,
isGH: true,
processReq: true,
},
{
name: "commit comment Event with edited action and support edited comments is disabled",
event: github.CommitCommentEvent{
Action: new("edited"),
Installation: &github.Installation{
ID: &idd,
},
},
eventType: "commit_comment",
supportEditedComments: false,
isGH: true,
processReq: false,
wantReason: "commit_comment: unsupported action \"edited\"",
},
{
name: "commit comment Event with retest",
event: github.CommitCommentEvent{
Expand Down Expand Up @@ -323,7 +393,11 @@ func TestProviderDetect(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gprovider := Provider{}
gprovider := Provider{
pacInfo: &info.PacOpts{
SupportEditedComments: tt.supportEditedComments,
},
}
logger, logCatcher := logger.GetLogger()
jeez, err := json.Marshal(tt.event)
if err != nil {
Expand Down
Loading
Loading