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
6 changes: 3 additions & 3 deletions internal/notifier/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ func (b Bitbucket) Post(ctx context.Context, event eventv1.Event) error {
return err
}

name, desc := formatNameAndDescription(event)
// Use CommitStatus as Name (and its SHA-1 as Key) so commitStatusExpr is visible.
_, desc := formatNameAndDescription(event)
id := b.CommitStatus
// key has a limitation of 40 characters in bitbucket api
key := sha1String(id)

cmo := &bitbucket.CommitsOptions{
Expand All @@ -122,7 +122,7 @@ func (b Bitbucket) Post(ctx context.Context, event eventv1.Event) error {
cso := &bitbucket.CommitStatusOptions{
State: state,
Key: key,
Name: name,
Name: id,
Description: desc,
Url: "https://bitbucket.org",
}
Expand Down
65 changes: 65 additions & 0 deletions internal/notifier/bitbucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ limitations under the License.
package notifier

import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
)

func TestNewBitbucketBasic(t *testing.T) {
Expand Down Expand Up @@ -48,3 +57,59 @@ func TestNewBitbucketInvalidToken(t *testing.T) {
_, err := NewBitbucket("kustomization/gitops-system/0c9c2e41", "https://bitbucket.org/foo/bar", "bar", nil)
g.Expect(err).To(HaveOccurred())
}

func TestBitbucket_Post_UsesCommitStatusAsName(t *testing.T) {
g := NewWithT(t)

commitStatus := "custom/status/from-expr"
var gotName, gotKey string

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/statuses/build/"):
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte(`{"error":{"message":"Not found"}}`))
case r.Method == http.MethodPost && strings.HasSuffix(r.URL.Path, "/statuses/build"):
body, err := io.ReadAll(r.Body)
g.Expect(err).ToNot(HaveOccurred())
var payload map[string]any
g.Expect(json.Unmarshal(body, &payload)).To(Succeed())
gotName, _ = payload["name"].(string)
gotKey, _ = payload["key"].(string)
w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte(`{}`))
default:
w.WriteHeader(http.StatusNotFound)
}
}))
defer ts.Close()

b, err := NewBitbucket(commitStatus, "https://bitbucket.org/foo/bar", "foo:bar", nil)
g.Expect(err).ToNot(HaveOccurred())

apiURL, err := url.Parse(ts.URL + "/2.0")
g.Expect(err).ToNot(HaveOccurred())
b.Client.SetApiBaseURL(*apiURL)
b.Client.HttpClient = ts.Client()

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",
}

err = b.Post(context.Background(), event)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(gotName).To(Equal(commitStatus))
g.Expect(gotKey).To(Equal(sha1String(commitStatus)))

// Regression guard: Name must not fall back to formatNameAndDescription.
formattedName, _ := formatNameAndDescription(event)
g.Expect(gotName).ToNot(Equal(formattedName))
}
6 changes: 4 additions & 2 deletions internal/notifier/bitbucketserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,11 @@ func (b BitbucketServer) Post(ctx context.Context, event eventv1.Event) error {
return fmt.Errorf("couldn't convert to bitbucket server state: %w", err)
}

name, desc := formatNameAndDescription(event)
name = name + " [" + desc + "]" //Bitbucket server displays this data on browser. Thus adding description here.
// Use CommitStatus as Name (plus Description for the Bitbucket Server UI), matching
// Bitbucket Cloud / GitHub / GitLab / Azure DevOps so commitStatusExpr is visible.
_, desc := formatNameAndDescription(event)
id := b.CommitStatus
name := id + " [" + desc + "]" // Bitbucket Server shows Name in the browser.
// key has a limitation of 40 characters in bitbucket api
key := sha1String(id)

Expand Down
48 changes: 44 additions & 4 deletions internal/notifier/bitbucketserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,46 @@ func TestNewBitbucketServerEmptyCommitStatus(t *testing.T) {
g.Expect(err.Error()).To(Equal("commit status cannot be empty"))
}

func TestBitbucketServer_Post_UsesCommitStatusAsName(t *testing.T) {
g := NewWithT(t)

commitStatus := "custom/status/from-expr"
var gotName, gotKey string

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
w.WriteHeader(http.StatusNotFound)
case http.MethodPost:
body, err := io.ReadAll(r.Body)
g.Expect(err).ToNot(HaveOccurred())
var payload bbServerBuildStatusSetRequest
g.Expect(json.Unmarshal(body, &payload)).To(Succeed())
gotName = payload.Name
gotKey = payload.Key
w.WriteHeader(http.StatusNoContent)
default:
w.WriteHeader(http.StatusNotFound)
}
}))
defer ts.Close()

b, err := NewBitbucketServer(commitStatus, ts.URL+"/scm/projectfoo/repobar.git", "token", nil, "", "")
g.Expect(err).ToNot(HaveOccurred())

event := generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
})
g.Expect(b.Post(context.Background(), event)).To(Succeed())

_, desc := formatNameAndDescription(event)
g.Expect(gotName).To(Equal(commitStatus + " [" + desc + "]"))
g.Expect(gotKey).To(Equal(sha1String(commitStatus)))

formattedName, _ := formatNameAndDescription(event)
g.Expect(gotName).ToNot(Equal(formattedName + " [" + desc + "]"))
}

func TestPostBitbucketServerBadCommitHash(t *testing.T) {
g := NewWithT(t)
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
Expand Down Expand Up @@ -368,8 +408,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
if tt.name == "Validate duplicate commit status successful match" {
w.WriteHeader(http.StatusOK)
w.Header().Add("Content-Type", "application/json")
name, desc := formatNameAndDescription(tt.event)
name = name + " [" + desc + "]"
_, desc := formatNameAndDescription(tt.event)
name := tt.commitStatus + " [" + desc + "]"
jsondata, _ := json.Marshal(&bbServerBuildStatus{
Name: name,
Description: desc,
Expand Down Expand Up @@ -439,8 +479,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
// Validate description
g.Expect(payload.Description).To(Equal("reason"))

// Validate name(with description appended)
g.Expect(payload.Name).To(Equal("kustomization/hello-world" + " [" + payload.Description + "]"))
// Name must use CommitStatus (commitStatusExpr), not formatNameAndDescription.
g.Expect(payload.Name).To(Equal(tt.commitStatus + " [" + payload.Description + "]"))

g.Expect(payload.Url).To(ContainSubstring("/scm/projectfoo/repobar.git"))

Expand Down