Skip to content

Commit

Permalink
add prow autobump review
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Hiller <[email protected]>
  • Loading branch information
dhiller committed Jun 23, 2023
1 parent 6210402 commit dca64ec
Show file tree
Hide file tree
Showing 35 changed files with 10,805 additions and 72 deletions.
67 changes: 55 additions & 12 deletions external-plugins/botreview/review/bump_kubevirtci.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,41 @@ import (
)

const (
BumpKubevirtCIApproveComment = `This looks like a simple prow job image bump. The bot approves.
bumpKubevirtCIApproveComment = `This looks like a simple kubevirtci bump. The bot approves.
/lgtm
/approve
`
BumpKubevirtCIDisapproveComment = `This doesn't look like a simple prow job image bump.
bumpKubevirtCIDisapproveComment = `This doesn't look like a simple kubevirtci bump.
These are the suspicious hunks I found:
`
)

var bumpKubevirtCIHunkBodyMatcher *regexp.Regexp
var bumpKubevirtCIHackConfigDefaultMatcher *regexp.Regexp
var bumpKubevirtCIClusterUpShaMatcher *regexp.Regexp
var bumpKubevirtCIClusterUpVersionMatcher *regexp.Regexp

func init() {
bumpKubevirtCIHunkBodyMatcher = regexp.MustCompile(`(?m)^(-[\s]+- image: [^\s]+$[\n]^\+[\s]+- image: [^\s]+|-[\s]+image: [^\s]+$[\n]^\+[\s]+image: [^\s]+)$`)
bumpKubevirtCIHackConfigDefaultMatcher = regexp.MustCompile(`(?m)^-[\s]*kubevirtci_git_hash=\"[^\s]+\"$[\n]^\+[\s]*kubevirtci_git_hash=\"[^\s]+\"$`)
bumpKubevirtCIClusterUpShaMatcher = regexp.MustCompile(`(?m)^-[\s]*[^\s]+$[\n]^\+[^\s]+$`)
bumpKubevirtCIClusterUpVersionMatcher = regexp.MustCompile(`(?m)^-[0-9]+-[a-z0-9]+$[\n]^\+[0-9]+-[a-z0-9]+$`)
}

type BumpKubevirtCIResult struct {
notMatchingHunks []*diff.Hunk
}

func (r BumpKubevirtCIResult) String() string {
if len(r.notMatchingHunks) == 0 {
return bumpKubevirtCIApproveComment
} else {
comment := bumpKubevirtCIDisapproveComment
for _, hunk := range r.notMatchingHunks {
comment += fmt.Sprintf("\n```\n%s\n```", string(hunk.Body))
}
return comment
}
}

type BumpKubevirtCI struct {
Expand All @@ -56,27 +76,50 @@ func (t *BumpKubevirtCI) IsRelevant() bool {
func (t *BumpKubevirtCI) AddIfRelevant(fileDiff *diff.FileDiff) {
fileName := strings.TrimPrefix(fileDiff.NewName, "b/")

// disregard all files
// * where the full path is not cluster-up-sha.txt and
// * where the path is not below cluster-up/
if fileName != "cluster-up-sha.txt" || !strings.HasPrefix(fileName, "cluster-up/") {
// store all hunks for unwanted files
if fileName != "cluster-up-sha.txt" &&
fileName != "hack/config-default.sh" &&
!strings.HasPrefix(fileName, "cluster-up/") {
for _, hunk := range fileDiff.Hunks {
t.notMatchingHunks = append(t.notMatchingHunks, hunk)
}
return
}

t.relevantFileDiffs = append(t.relevantFileDiffs, fileDiff)
}

func (t *BumpKubevirtCI) Review() BotReviewResult {
result := &Result{}
result := &BumpKubevirtCIResult{}

for _, fileDiff := range t.relevantFileDiffs {
for _, hunk := range fileDiff.Hunks {
if !bumpKubevirtCIHunkBodyMatcher.Match(hunk.Body) {
result.notMatchingHunks = append(result.notMatchingHunks, hunk)
fileName := strings.TrimPrefix(fileDiff.NewName, "b/")
switch fileName {
case "cluster-up-sha.txt":
for _, hunk := range fileDiff.Hunks {
if !bumpKubevirtCIClusterUpShaMatcher.Match(hunk.Body) {
result.notMatchingHunks = append(result.notMatchingHunks, hunk)
}
}
case "hack/config-default.sh":
for _, hunk := range fileDiff.Hunks {
if !bumpKubevirtCIHackConfigDefaultMatcher.Match(hunk.Body) {
result.notMatchingHunks = append(result.notMatchingHunks, hunk)
}
}
case "cluster-up/version.txt":
for _, hunk := range fileDiff.Hunks {
if !bumpKubevirtCIClusterUpVersionMatcher.Match(hunk.Body) {
result.notMatchingHunks = append(result.notMatchingHunks, hunk)
}
}
default:
// no checks since we can't do anything reasonable here
}
}

result.notMatchingHunks = append(result.notMatchingHunks, t.notMatchingHunks...)

return result
}

Expand Down
101 changes: 101 additions & 0 deletions external-plugins/botreview/review/bump_kubevirtci_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* This file is part of the KubeVirt project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2022 Red Hat, Inc.
*
*/

package review

import (
"github.com/sourcegraph/go-diff/diff"
"os"
"path/filepath"
"reflect"
"testing"
)

func TestBumpKubevirtCI_Review(t1 *testing.T) {
diffFilePathes := []string{}
entries, err := os.ReadDir("testdata/kubevirtci-bump")
if err != nil {
t1.Errorf("failed to read files: %v", err)
}
for _, entry := range entries {
diffFilePathes = append(diffFilePathes, filepath.Join("testdata/kubevirtci-bump", entry.Name()))
}
diffFilePathes = append(diffFilePathes, "testdata/mixed_bump_prow_job.patch0")
diffFilePathesToDiffs := map[string]*diff.FileDiff{}
for _, diffFile := range diffFilePathes {
bump_images_diff_file, err := os.ReadFile(diffFile)
if err != nil {
t1.Errorf("failed to read diff: %v", err)
}
bump_file_diffs, err := diff.ParseFileDiff(bump_images_diff_file)
if err != nil {
t1.Errorf("failed to read diff: %v", err)
}
diffFilePathesToDiffs[diffFile] = bump_file_diffs
}
type fields struct {
relevantFileDiffs []*diff.FileDiff
}
tests := []struct {
name string
fields fields
want *BumpKubevirtCIResult
}{
{
name: "simple prow autobump",
fields: fields{
relevantFileDiffs: []*diff.FileDiff{
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up-sha.txt"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_cluster_kind-1.22-sriov_provider.sh"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_cluster_kind-1.22-sriov_sriov-node_node.sh"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_cluster_kind_common.sh"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_cluster_kind_configure-registry-proxy.sh"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_hack_common.sh"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_version.txt"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/hack_config-default.sh"],
},
},
want: &BumpKubevirtCIResult{},
},
{
name: "mixed image bump",
fields: fields{
relevantFileDiffs: []*diff.FileDiff{
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up-sha.txt"],
diffFilePathesToDiffs["testdata/kubevirtci-bump/cluster-up_cluster_kind-1.22-sriov_provider.sh"],
diffFilePathesToDiffs["testdata/mixed_bump_prow_job.patch0"],
},
},
want: &BumpKubevirtCIResult{
notMatchingHunks: diffFilePathesToDiffs["testdata/mixed_bump_prow_job.patch0"].Hunks,
},
},
}
for _, tt := range tests {
t1.Run(tt.name, func(t1 *testing.T) {
t := &BumpKubevirtCI{}
for _, diff := range tt.fields.relevantFileDiffs {
t.AddIfRelevant(diff)
}
if got := t.Review(); !reflect.DeepEqual(got, tt.want) {
t1.Errorf("Review() = %v, want %v", got, tt.want)
}
})
}
}
18 changes: 17 additions & 1 deletion external-plugins/botreview/review/image_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ func init() {
prowJobImageUpdateHunkBodyMatcher = regexp.MustCompile(`(?m)^(-[\s]+- image: [^\s]+$[\n]^\+[\s]+- image: [^\s]+|-[\s]+image: [^\s]+$[\n]^\+[\s]+image: [^\s]+)$`)
}

type ProwJobImageUpdateResult struct {
notMatchingHunks []*diff.Hunk
}

func (r ProwJobImageUpdateResult) String() string {
if len(r.notMatchingHunks) == 0 {
return prowJobImageUpdateApproveComment
} else {
comment := prowJobImageUpdateDisapproveComment
for _, hunk := range r.notMatchingHunks {
comment += fmt.Sprintf("\n```\n%s\n```", string(hunk.Body))
}
return comment
}
}

type ProwJobImageUpdate struct {
relevantFileDiffs []*diff.FileDiff
notMatchingHunks []*diff.Hunk
Expand All @@ -70,7 +86,7 @@ func (t *ProwJobImageUpdate) AddIfRelevant(fileDiff *diff.FileDiff) {
}

func (t *ProwJobImageUpdate) Review() BotReviewResult {
result := &Result{}
result := &ProwJobImageUpdateResult{}

for _, fileDiff := range t.relevantFileDiffs {
for _, hunk := range fileDiff.Hunks {
Expand Down
6 changes: 3 additions & 3 deletions external-plugins/botreview/review/image_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestProwJobImageUpdate_Review(t1 *testing.T) {
tests := []struct {
name string
fields fields
want *Result
want *ProwJobImageUpdateResult
}{
{
name: "simple image bump",
Expand All @@ -60,7 +60,7 @@ func TestProwJobImageUpdate_Review(t1 *testing.T) {
diffFilePathesToDiffs["testdata/simple_bump-prow-job-images_sh.patch1"],
},
},
want: &Result{},
want: &ProwJobImageUpdateResult{},
},
{
name: "mixed image bump",
Expand All @@ -69,7 +69,7 @@ func TestProwJobImageUpdate_Review(t1 *testing.T) {
diffFilePathesToDiffs["testdata/mixed_bump_prow_job.patch0"],
},
},
want: &Result{
want: &ProwJobImageUpdateResult{
notMatchingHunks: []*diff.Hunk{
diffFilePathesToDiffs["testdata/mixed_bump_prow_job.patch0"].Hunks[0],
},
Expand Down
23 changes: 18 additions & 5 deletions external-plugins/botreview/review/prow_autobump.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ func init() {
prowAutobumpHunkBodyMatcher = regexp.MustCompile(`(?m)^(-[\s]+- image: [^\s]+$[\n]^\+[\s]+- image: [^\s]+|-[\s]+image: [^\s]+$[\n]^\+[\s]+image: [^\s]+)$`)
}

type ProwAutobumpResult struct {
notMatchingHunks []*diff.Hunk
}

func (r ProwAutobumpResult) String() string {
if len(r.notMatchingHunks) == 0 {
return prowAutobumpApproveComment
} else {
comment := prowAutobumpDisapproveComment
for _, hunk := range r.notMatchingHunks {
comment += fmt.Sprintf("\n```\n%s\n```", string(hunk.Body))
}
return comment
}
}

type ProwAutobump struct {
relevantFileDiffs []*diff.FileDiff
notMatchingHunks []*diff.Hunk
Expand All @@ -60,18 +76,15 @@ func (t *ProwAutobump) IsRelevant() bool {
func (t *ProwAutobump) AddIfRelevant(fileDiff *diff.FileDiff) {
fileName := strings.TrimPrefix(fileDiff.NewName, "b/")

// disregard all files
// * where the full path is not cluster-up-sha.txt and
// * where the path is not below cluster-up/
if fileName != "cluster-up-sha.txt" || !strings.HasPrefix(fileName, "cluster-up/") {
if !strings.HasPrefix(fileName, "github/ci/prow-deploy/kustom") {
return
}

t.relevantFileDiffs = append(t.relevantFileDiffs, fileDiff)
}

func (t *ProwAutobump) Review() BotReviewResult {
result := &Result{}
result := &ProwAutobumpResult{}

for _, fileDiff := range t.relevantFileDiffs {
for _, hunk := range fileDiff.Hunks {
Expand Down
Loading

0 comments on commit dca64ec

Please sign in to comment.