CI: Make the downstream enterprise test a check instead of comments (#59071)

This commit is contained in:
Kevin Minehart
2022-11-24 08:17:12 -06:00
committed by GitHub
parent 76372a240c
commit 45c759eb59
14 changed files with 681 additions and 8 deletions
+143
View File
@@ -0,0 +1,143 @@
package git
import (
"context"
"errors"
"fmt"
"net/http"
"regexp"
"github.com/google/go-github/v45/github"
"github.com/grafana/grafana/pkg/build/stringutil"
"golang.org/x/oauth2"
)
const (
MainBranch = "main"
HomeDir = "."
RepoOwner = "grafana"
OSSRepo = "grafana"
EnterpriseRepo = "grafana-enterprise"
EnterpriseCheckName = "Grafana Enterprise"
EnterpriseCheckDescription = "Downstream tests to ensure that your changes are compatible with Grafana Enterprise"
)
var EnterpriseCheckLabels = []string{"enterprise-ok", "enterprise-failed", "enterprise-override"}
var (
ErrorNoDroneBuildLink = errors.New("no drone build link")
)
type GitService interface {
DeleteRef(ctx context.Context, owner string, repo string, ref string) (*github.Response, error)
}
type LabelsService interface {
ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *github.ListOptions) ([]*github.Label, *github.Response, error)
RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*github.Response, error)
AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*github.Label, *github.Response, error)
}
type CommentService interface {
CreateComment(ctx context.Context, owner string, repo string, number int, comment *github.IssueComment) (*github.IssueComment, *github.Response, error)
}
type StatusesService interface {
CreateStatus(ctx context.Context, owner, repo, ref string, status *github.RepoStatus) (*github.RepoStatus, *github.Response, error)
}
// NewGitHubClient creates a new Client using the provided GitHub token if not empty.
func NewGitHubClient(ctx context.Context, token string) *github.Client {
var tc *http.Client
if token != "" {
ts := oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: token,
})
tc = oauth2.NewClient(ctx, ts)
}
return github.NewClient(tc)
}
func PRCheckRegexp() *regexp.Regexp {
reBranch, err := regexp.Compile(`^pr-check-([0-9]+)\/(.+)$`)
if err != nil {
panic(fmt.Sprintf("Failed to compile regexp: %s", err))
}
return reBranch
}
func AddLabelToPR(ctx context.Context, client LabelsService, prID int, newLabel string) error {
// Check existing labels
labels, _, err := client.ListLabelsByIssue(ctx, RepoOwner, OSSRepo, prID, nil)
if err != nil {
return err
}
duplicate := false
for _, label := range labels {
if *label.Name == newLabel {
duplicate = true
continue
}
// Delete existing "enterprise-xx" labels
if stringutil.Contains(EnterpriseCheckLabels, *label.Name) {
_, err := client.RemoveLabelForIssue(ctx, RepoOwner, OSSRepo, prID, *label.Name)
if err != nil {
return err
}
}
}
if duplicate {
return nil
}
_, _, err = client.AddLabelsToIssue(ctx, RepoOwner, OSSRepo, prID, []string{newLabel})
if err != nil {
return err
}
return nil
}
func DeleteEnterpriseBranch(ctx context.Context, client GitService, branchName string) error {
ref := "heads/" + branchName
_, err := client.DeleteRef(ctx, RepoOwner, EnterpriseRepo, ref)
if err != nil {
return err
}
return nil
}
// CreateEnterpriseStatus sets the status on a commit for the enterprise build check.
func CreateEnterpriseStatus(ctx context.Context, client StatusesService, sha, link, status string) (*github.RepoStatus, error) {
check, _, err := client.CreateStatus(ctx, RepoOwner, OSSRepo, sha, &github.RepoStatus{
Context: github.String(EnterpriseCheckName),
Description: github.String(EnterpriseCheckDescription),
TargetURL: github.String(link),
State: github.String(status),
})
if err != nil {
return nil, err
}
return check, nil
}
func CreateEnterpriseBuildFailedComment(ctx context.Context, client CommentService, link string, prID int) error {
body := fmt.Sprintf("Drone build failed: %s", link)
_, _, err := client.CreateComment(ctx, RepoOwner, OSSRepo, prID, &github.IssueComment{
Body: &body,
})
if err != nil {
return err
}
return nil
}
+55
View File
@@ -0,0 +1,55 @@
package git_test
import (
"context"
"errors"
"testing"
"github.com/google/go-github/v45/github"
"github.com/grafana/grafana/pkg/build/git"
"github.com/stretchr/testify/require"
)
type TestChecksService struct {
CreateCheckRunError error
}
func (s *TestChecksService) CreateStatus(ctx context.Context, owner, repo, ref string, status *github.RepoStatus) (*github.RepoStatus, *github.Response, error) {
if s.CreateCheckRunError != nil {
return nil, nil, s.CreateCheckRunError
}
return &github.RepoStatus{
ID: github.Int64(1),
URL: status.URL,
}, nil, nil
}
func TestCreateEnterpriseRepoStatus(t *testing.T) {
t.Run("It should create a repo status", func(t *testing.T) {
var (
ctx = context.Background()
client = &TestChecksService{}
link = "http://example.com"
sha = "1234"
)
_, err := git.CreateEnterpriseStatus(ctx, client, link, sha, "success")
require.NoError(t, err)
})
t.Run("It should return an error if GitHub fails to create the status", func(t *testing.T) {
var (
ctx = context.Background()
createCheckError = errors.New("create check run error")
client = &TestChecksService{
CreateCheckRunError: createCheckError,
}
link = "http://example.com"
sha = "1234"
)
_, err := git.CreateEnterpriseStatus(ctx, client, link, sha, "success")
require.ErrorIs(t, err, createCheckError)
})
}
+134
View File
@@ -0,0 +1,134 @@
package git_test
import (
"context"
"errors"
"testing"
"github.com/google/go-github/v45/github"
"github.com/grafana/grafana/pkg/build/git"
"github.com/stretchr/testify/require"
)
type TestLabelsService struct {
Labels []*github.Label
ListLabelsError error
RemoveLabelError error
AddLabelsError error
}
func (s *TestLabelsService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opts *github.ListOptions) ([]*github.Label, *github.Response, error) {
if s.ListLabelsError != nil {
return nil, nil, s.ListLabelsError
}
labels := s.Labels
if labels == nil {
labels = []*github.Label{}
}
return labels, nil, nil
}
func (s *TestLabelsService) RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*github.Response, error) {
if s.RemoveLabelError != nil {
return nil, s.RemoveLabelError
}
return &github.Response{}, nil
}
func (s *TestLabelsService) AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*github.Label, *github.Response, error) {
if s.AddLabelsError != nil {
return nil, nil, s.AddLabelsError
}
l := make([]*github.Label, len(labels))
for i, v := range labels {
l[i] = &github.Label{
Name: github.String(v),
}
}
return l, nil, nil
}
func TestAddLabelToPR(t *testing.T) {
t.Run("It should add a label to a pull request", func(t *testing.T) {
var (
ctx = context.Background()
client = &TestLabelsService{}
pr = 20
label = "test-label"
)
require.NoError(t, git.AddLabelToPR(ctx, client, pr, label))
})
t.Run("It should not return an error if the label already exists", func(t *testing.T) {
var (
ctx = context.Background()
client = &TestLabelsService{
Labels: []*github.Label{
{
Name: github.String("test-label"),
},
},
}
pr = 20
label = "test-label"
)
require.NoError(t, git.AddLabelToPR(ctx, client, pr, label))
})
t.Run("It should return an error if GitHub returns an error when listing labels", func(t *testing.T) {
var (
ctx = context.Background()
listLabelsError = errors.New("list labels error")
client = &TestLabelsService{
ListLabelsError: listLabelsError,
Labels: []*github.Label{},
}
pr = 20
label = "test-label"
)
require.ErrorIs(t, git.AddLabelToPR(ctx, client, pr, label), listLabelsError)
})
t.Run("It should not return an error if there are existing enterprise-check labels.", func(t *testing.T) {
var (
ctx = context.Background()
client = &TestLabelsService{
Labels: []*github.Label{
{
Name: github.String("enterprise-failed"),
},
},
}
pr = 20
label = "test-label"
)
require.NoError(t, git.AddLabelToPR(ctx, client, pr, label))
})
t.Run("It should return an error if GitHub returns an error when removing existing enterprise-check labels", func(t *testing.T) {
var (
ctx = context.Background()
removeLabelError = errors.New("remove label error")
client = &TestLabelsService{
RemoveLabelError: removeLabelError,
Labels: []*github.Label{
{
Name: github.String("enterprise-failed"),
},
},
}
pr = 20
label = "test-label"
)
require.ErrorIs(t, git.AddLabelToPR(ctx, client, pr, label), removeLabelError)
})
}
+25
View File
@@ -0,0 +1,25 @@
package git_test
import (
"testing"
"github.com/grafana/grafana/pkg/build/git"
"github.com/stretchr/testify/assert"
)
func TestPRCheckRegexp(t *testing.T) {
var (
shouldMatch = []string{"pr-check-1/branch-name", "pr-check-111/branch/name", "pr-check-102930122/branch-name"}
shouldNotMatch = []string{"pr-check-a/branch", "km/test", "test", "pr-check", "pr-check/test", "price"}
)
regex := git.PRCheckRegexp()
for _, v := range shouldMatch {
assert.Truef(t, regex.MatchString(v), "regex should match %s", v)
}
for _, v := range shouldNotMatch {
assert.False(t, regex.MatchString(v), "regex should not match %s", v)
}
}