From 73499fb6a4471c2d038badd4e2b21aeb83211be7 Mon Sep 17 00:00:00 2001 From: Kevin McDermott Date: Thu, 27 Apr 2023 10:49:04 +0100 Subject: [PATCH] Add the event summary into the genre. This appends the metadata summary field in the genre (if one exists) otherwise retains the fluxcd entry. Signed-off-by: Kevin McDermott --- internal/notifier/azure_devops.go | 26 +++++-- internal/notifier/azure_devops_test.go | 99 ++++++++++++++++++++++++++ internal/notifier/util_test.go | 30 ++++++++ 3 files changed, 150 insertions(+), 5 deletions(-) diff --git a/internal/notifier/azure_devops.go b/internal/notifier/azure_devops.go index e42217600..d28e21617 100644 --- a/internal/notifier/azure_devops.go +++ b/internal/notifier/azure_devops.go @@ -33,12 +33,17 @@ import ( const genre string = "fluxcd" -// AzureDevOps is a Azure DevOps notifier. +type azureDevOpsClient interface { + CreateCommitStatus(context.Context, git.CreateCommitStatusArgs) (*git.GitStatus, error) + GetStatuses(context.Context, git.GetStatusesArgs) (*[]git.GitStatus, error) +} + +// AzureDevOps is an Azure DevOps notifier. type AzureDevOps struct { Project string Repo string ProviderUID string - Client git.Client + Client azureDevOpsClient } // NewAzureDevOps creates and returns a new AzureDevOps notifier. @@ -100,7 +105,8 @@ func (a AzureDevOps) Post(ctx context.Context, event eventv1.Event) error { } // Check if the exact status is already set - g := genre + g := commitStatusGenre(event) + _, desc := formatNameAndDescription(event) id := generateCommitStatusID(a.ProviderUID, event) createArgs := git.CreateCommitStatusArgs{ @@ -123,8 +129,9 @@ func (a AzureDevOps) Post(ctx context.Context, event eventv1.Event) error { } statuses, err := a.Client.GetStatuses(ctx, getArgs) if err != nil { - return fmt.Errorf("could not list commit statuses: %v", err) + return fmt.Errorf("could not list commit statuses: %w", err) } + if duplicateAzureDevOpsStatus(statuses, createArgs.GitCommitStatusToCreate) { return nil } @@ -132,7 +139,7 @@ func (a AzureDevOps) Post(ctx context.Context, event eventv1.Event) error { // Create a new status _, err = a.Client.CreateCommitStatus(ctx, createArgs) if err != nil { - return fmt.Errorf("could not create commit status: %v", err) + return fmt.Errorf("could not create commit status: %w", err) } return nil } @@ -172,3 +179,12 @@ func duplicateAzureDevOpsStatus(statuses *[]git.GitStatus, status *git.GitStatus return false } + +func commitStatusGenre(event eventv1.Event) string { + summary, ok := event.Metadata["summary"] + if ok { + return fmt.Sprintf("%s:%s", genre, summary) + } + + return genre +} diff --git a/internal/notifier/azure_devops_test.go b/internal/notifier/azure_devops_test.go index 0e5ebca24..8a9a51435 100644 --- a/internal/notifier/azure_devops_test.go +++ b/internal/notifier/azure_devops_test.go @@ -17,10 +17,13 @@ limitations under the License. package notifier import ( + "context" "testing" + eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" "github.com/microsoft/azure-devops-go-api/azuredevops/v6/git" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" ) func TestNewAzureDevOpsBasic(t *testing.T) { @@ -60,6 +63,89 @@ func TestDuplicateAzureDevOpsStatus(t *testing.T) { } } +func TestAzureDevOps_Post(t *testing.T) { + strPtr := func(s string) *string { + return &s + } + + postTests := []struct { + name string + event eventv1.Event + want git.CreateCommitStatusArgs + }{ + { + name: "event with no summary", + event: eventv1.Event{ + Severity: eventv1.EventSeverityInfo, + InvolvedObject: corev1.ObjectReference{ + Kind: "Kustomization", + Name: "gitops-system", + }, + Metadata: map[string]string{ + eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3", + }, + Reason: "ApplySucceeded", + }, + want: git.CreateCommitStatusArgs{ + CommitId: strPtr("69b59063470310ebbd88a9156325322a124e55a3"), + Project: strPtr("bar"), + RepositoryId: strPtr("baz"), + GitCommitStatusToCreate: &git.GitStatus{ + Description: strPtr("apply succeeded"), + State: &git.GitStatusStateValues.Succeeded, + Context: &git.GitStatusContext{ + Genre: strPtr("fluxcd"), + Name: strPtr("kustomization/gitops-system/0c9c2e41"), + }, + }, + }, + }, + { + name: "event with summary", + event: eventv1.Event{ + Severity: eventv1.EventSeverityInfo, + InvolvedObject: corev1.ObjectReference{ + Kind: "Kustomization", + Name: "gitops-system", + }, + Metadata: map[string]string{ + eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3", + "summary": "test summary", + }, + Reason: "ApplySucceeded", + }, + want: git.CreateCommitStatusArgs{ + CommitId: strPtr("69b59063470310ebbd88a9156325322a124e55a3"), + Project: strPtr("bar"), + RepositoryId: strPtr("baz"), + GitCommitStatusToCreate: &git.GitStatus{ + Description: strPtr("apply succeeded"), + State: &git.GitStatusStateValues.Succeeded, + Context: &git.GitStatusContext{ + Genre: strPtr("fluxcd:test summary"), + Name: strPtr("kustomization/gitops-system/0c9c2e41"), + }, + }, + }, + }, + } + + for _, tt := range postTests { + t.Run(tt.name, func(t *testing.T) { + a, err := NewAzureDevOps("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com/foo/bar/_git/baz", "foo", nil) + fakeClient := &fakeDevOpsClient{} + a.Client = fakeClient + assert.Nil(t, err) + + err = a.Post(context.TODO(), tt.event) + assert.Nil(t, err) + + want := []git.CreateCommitStatusArgs{tt.want} + assert.Equal(t, want, fakeClient.created) + }) + } +} + func azStatus(state git.GitStatusState, context string, description string) *git.GitStatus { genre := "fluxcd" return &git.GitStatus{ @@ -71,3 +157,16 @@ func azStatus(state git.GitStatusState, context string, description string) *git State: &state, } } + +type fakeDevOpsClient struct { + created []git.CreateCommitStatusArgs +} + +func (c *fakeDevOpsClient) CreateCommitStatus(ctx context.Context, args git.CreateCommitStatusArgs) (*git.GitStatus, error) { + c.created = append(c.created, args) + return nil, nil +} + +func (c *fakeDevOpsClient) GetStatuses(context.Context, git.GetStatusesArgs) (*[]git.GitStatus, error) { + return nil, nil +} diff --git a/internal/notifier/util_test.go b/internal/notifier/util_test.go index 40d358465..247d39e23 100644 --- a/internal/notifier/util_test.go +++ b/internal/notifier/util_test.go @@ -150,3 +150,33 @@ func TestUtil_BasicAuth(t *testing.T) { s := basicAuth(username, password) require.Equal(t, "dXNlcjpwYXNzd29yZA==", s) } + +func TestUtil_GenerateCommitStatusID(t *testing.T) { + statusIDTests := []struct { + name string + providerUID string + event eventv1.Event + want string + }{ + { + name: "simple event case", + providerUID: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", + event: eventv1.Event{ + InvolvedObject: corev1.ObjectReference{ + Kind: "Kustomization", + Name: "gitops-system", + }, + Reason: "ApplySucceeded", + }, + want: "kustomization/gitops-system/0c9c2e41", + }, + } + + for _, tt := range statusIDTests { + t.Run(tt.name, func(t *testing.T) { + id := generateCommitStatusID(tt.providerUID, tt.event) + + require.Equal(t, tt.want, id) + }) + } +}