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
13 changes: 9 additions & 4 deletions cmd/release-controller/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,16 @@ func (c *Controller) syncJira(key queueKey) error {

klog.V(4).Infof("Verifying fixed issues in %s", release.Config.Name)

// get accepted tags
acceptedTags := releasecontroller.SortedRawReleaseTags(release, releasecontroller.ReleasePhaseAccepted)
tag, prevTag := getNonVerifiedTagsJira(acceptedTags)
// Include both accepted and rejected tags when looking for bugs to verify.
// Bugs are pre-merge verified by QA on ephemeral clusters (via qe-approved/verified PR labels),
// so no additional payload-level QA verification is needed. The payload phase check here simply
// confirms that all blocking tests have been executed (accepted or rejected) and that the code
// fix is present in the payload, allowing the bug status to be automatically transitioned to
// VERIFIED and notifying assignees which payload contains their fix.
completedTags := releasecontroller.SortedRawReleaseTags(release, releasecontroller.ReleasePhaseAccepted, releasecontroller.ReleasePhaseRejected)
tag, prevTag := getNonVerifiedTagsJira(completedTags)
if tag == nil {
klog.V(6).Infof("jira: All accepted tags for %s have already been verified", release.Config.Name)
klog.V(6).Infof("jira: All accepted/rejected tags for %s have already been verified", release.Config.Name)
return nil
}
if prevTag == nil {
Expand Down
7 changes: 5 additions & 2 deletions pkg/jira/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,11 @@ func (c *Verifier) commentOnPR(extPR pr, message string) (error, bool) {
return err, false
}
// Check to see if the same message has already been posted.
// Also check the legacy message format ("accepted release") to avoid duplicates
// after the wording change from "Fix included in accepted release" to "Fix included in release".
legacyMessage := strings.Replace(message, "in release ", "in accepted release ", 1)
for _, comment := range comments {
if strings.Contains(comment.Body, message) {
if strings.Contains(comment.Body, message) || strings.Contains(comment.Body, legacyMessage) {
Comment on lines +97 to +99
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There should be a test for this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added TestCommentOnPRLegacyDedupe to verify that commentOnPR does not post a duplicate comment when an existing PR comment uses the legacy "Fix included in accepted release" wording.

return nil, true
}
}
Expand All @@ -107,7 +110,7 @@ func (c *Verifier) commentOnPR(extPR pr, message string) (error, bool) {

func (c *Verifier) verifyExtPRs(issue *jiraBaseClient.Issue, extPRs []pr, errs *[]error, tagName string) (ticketMessage string, isSuccess, verifiedLater bool) {
var success bool
message := fmt.Sprintf("Fix included in accepted release %s", tagName)
message := fmt.Sprintf("Fix included in release %s", tagName)
var unApprovedPRs []pr
if !strings.EqualFold(issue.Fields.Status.Name, jira.StatusOnQA) && !strings.EqualFold(issue.Fields.Status.Name, jira.StatusModified) {
klog.V(4).Infof("Issue %s is in %s status; ignoring", issue.Key, issue.Fields.Status.Name)
Expand Down
50 changes: 40 additions & 10 deletions pkg/jira/jira_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,36 @@ func TestCommentOnPR(t *testing.T) {
}
}

// TestCommentOnPRLegacyDedupe tests that commentOnPR does not post a duplicate
// comment when an existing comment uses the legacy "accepted release" wording,
// after the message was changed to "Fix included in release".
func TestCommentOnPRLegacyDedupe(t *testing.T) {
tagName := "4.20.0-0.nightly-2026-04-01-022028"
newMessage := fmt.Sprintf("Fix included in release %s", tagName)
legacyMessage := fmt.Sprintf("Fix included in accepted release %s", tagName)

// Seed the fake client with an existing comment using the legacy wording
existingComments := map[int][]github.IssueComment{
1: {{Body: legacyMessage}},
}
mockClient := &fakegithub.FakeClient{IssueComments: existingComments}
verifier := &Verifier{ghClient: mockClient}
extPR := pr{org: "testOrg", repo: "testRepo", prNum: 1}

// commentOnPR should detect the legacy comment and not post a duplicate
err, created := verifier.commentOnPR(extPR, newMessage)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if !created {
t.Errorf("Expected created=true (comment already exists), but got false")
}
// Verify no new comment was posted
if len(mockClient.IssueComments[1]) != 1 {
t.Errorf("Expected 1 comment (no duplicate), but got %d", len(mockClient.IssueComments[1]))
}
}

func TestGetPRS(t *testing.T) {
issue := jira.Issue{ID: "OCPBUGS-0000"}
removeLinkArray := []jira.RemoteLink{
Expand Down Expand Up @@ -295,7 +325,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "",
message: "Fix included in accepted release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
message: "Fix included in release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
},
},
{
Expand All @@ -312,7 +342,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
message: "Fix included in release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
},
},
{
Expand All @@ -327,7 +357,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.10",
message: "Fix included in release 4.10",
},
},
{
Expand All @@ -342,7 +372,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.13.0-0.nightly-2022-11-12",
message: "Fix included in release 4.13.0-0.nightly-2022-11-12",
},
},
{
Expand Down Expand Up @@ -411,7 +441,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
message: "Fix included in release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
},
},
{
Expand All @@ -430,7 +460,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
message: "Fix included in release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
},
},
{
Expand All @@ -447,7 +477,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: nil,
status: "Verified",
message: "Fix included in accepted release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
message: "Fix included in release 4.10\nAll linked GitHub PRs have been approved by a QA contact; updating bug status to VERIFIED",
},
},
{
Expand All @@ -467,7 +497,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: []error{},
status: "ON_QA",
message: "Fix included in accepted release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
message: "Fix included in release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
},
},
{
Expand All @@ -487,7 +517,7 @@ func TestVerifyIssues(t *testing.T) {
expected: expectedResult{
errors: []error{},
status: "ON_QA",
message: "Fix included in accepted release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
message: "Fix included in release 4.10\nJira issue will not be automatically moved to VERIFIED for the following reasons:\n- PR openshift/vmware-vsphere-csi-driver-operator#105 not approved by the QA Contact\n\nThis issue must now be manually moved to VERIFIED by Jack Smith",
},
},
}
Expand Down Expand Up @@ -1035,7 +1065,7 @@ const (
"active": true,
"timeZone": "America/New_York"
},
"body": "Fix included in accepted release 4.13.0-0.nightly-2022-11-12",
"body": "Fix included in release 4.13.0-0.nightly-2022-11-12",
"updateAuthor": {
"self": "https://issues.redhat.com/rest/api/2/user?username=openshift-crt-jira-release-controller",
"name": "openshift-crt-jira-release-controller",
Expand Down