Skip to content

Commit

Permalink
github: Split the interfaces
Browse files Browse the repository at this point in the history
In an upcoming commit we will be testing the `ci` and `pr` subcommands.
Splitting the interfaces into smaller components will make this a bit
easier, since those testsuites will only have to fake what they need.
  • Loading branch information
iainlane committed Jun 27, 2023
1 parent 8ef8cd6 commit 04e405d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion cmd/wait-for-github/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func handleCIStatus(status github.CIStatus, recheckInterval time.Duration) cli.E
}

type checkSpecificCI struct {
githubClient github.GithubClient
githubClient github.CheckCIStatus
owner string
repo string
ref string
Expand Down
2 changes: 1 addition & 1 deletion cmd/wait-for-github/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type commitInfo struct {
type prCheck struct {
prConfig

githubClient github.GithubClient
githubClient github.CheckPRMerged
}

func (pr prCheck) Check(ctx context.Context, recheckInterval time.Duration) error {
Expand Down
40 changes: 29 additions & 11 deletions internal/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ import (
log "github.com/sirupsen/logrus"
)

type GithubClient interface {
type CheckPRMerged interface {
IsPRMergedOrClosed(ctx context.Context, owner, repo string, pr int) (string, bool, int64, error)
}

type CheckCIStatus interface {
GetCIStatus(ctx context.Context, owner, repo string, commitHash string) (CIStatus, error)
GetCIStatusForChecks(ctx context.Context, owner, repo string, commitHash string, checkNames []string) (CIStatus, []string, error)
}
Expand All @@ -48,7 +51,7 @@ type GHClient struct {
client *github.Client
}

func NewGithubClient(ctx context.Context, authInfo AuthInfo) (GithubClient, error) {
func NewGithubClient(ctx context.Context, authInfo AuthInfo) (GHClient, error) {
// If a GitHub token is provided, use it to authenticate in preference to
// App authentication
if authInfo.GithubToken != "" {
Expand All @@ -72,30 +75,30 @@ func cachingRetryableTransport() http.RoundTripper {
}

// AuthenticateWithToken authenticates with a GitHub token
func AuthenticateWithToken(ctx context.Context, token string) GithubClient {
func AuthenticateWithToken(ctx context.Context, token string) GHClient {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
ctx = context.WithValue(ctx, oauth2.HTTPClient, &http.Client{Transport: cachingRetryableTransport()})
httpClient := oauth2.NewClient(ctx, src)
githubClient := github.NewClient(httpClient)

return &GHClient{client: githubClient}
return GHClient{client: githubClient}
}

// AuthenticateWithApp authenticates with a GitHub App
func AuthenticateWithApp(ctx context.Context, privateKey []byte, appID, installationID int64) (GithubClient, error) {
func AuthenticateWithApp(ctx context.Context, privateKey []byte, appID, installationID int64) (GHClient, error) {
itr, err := ghinstallation.New(cachingRetryableTransport(), appID, installationID, privateKey)
if err != nil {
return nil, fmt.Errorf("failed to create transport: %w", err)
return GHClient{}, fmt.Errorf("failed to create transport: %w", err)
}

githubClient := github.NewClient(&http.Client{Transport: itr})

return &GHClient{client: githubClient}, nil
return GHClient{client: githubClient}, nil
}

func (c *GHClient) IsPRMergedOrClosed(ctx context.Context, owner, repo string, prNumber int) (string, bool, int64, error) {
func (c GHClient) IsPRMergedOrClosed(ctx context.Context, owner, repo string, prNumber int) (string, bool, int64, error) {
pr, _, err := c.client.PullRequests.Get(ctx, owner, repo, prNumber)
if err != nil {
return "", false, -1, fmt.Errorf("failed to query GitHub: %w", err)
Expand Down Expand Up @@ -123,7 +126,22 @@ const (
CIStatusUnknown
)

func (c *GHClient) GetCIStatus(ctx context.Context, owner, repoName string, ref string) (CIStatus, error) {
func (c CIStatus) String() string {
switch c {
case CIStatusPassed:
return "passed"
case CIStatusFailed:
return "failed"
case CIStatusPending:
return "pending"
case CIStatusUnknown:
return "unknown"
default:
return "unknown"
}
}

func (c GHClient) GetCIStatus(ctx context.Context, owner, repoName string, ref string) (CIStatus, error) {
opt := &github.ListOptions{
PerPage: 100,
}
Expand All @@ -145,7 +163,7 @@ func (c *GHClient) GetCIStatus(ctx context.Context, owner, repoName string, ref
return CIStatusUnknown, nil
}

func (c *GHClient) getOneStatus(ctx context.Context, owner, repoName, ref, check string) (CIStatus, error) {
func (c GHClient) getOneStatus(ctx context.Context, owner, repoName, ref, check string) (CIStatus, error) {
listOptions := github.ListOptions{
PerPage: 100,
}
Expand Down Expand Up @@ -213,7 +231,7 @@ func (c *GHClient) getOneStatus(ctx context.Context, owner, repoName, ref, check

// GetCIStatusForCheck returns the CI status for a specific commit. It looks at
// both 'checks' and 'statuses'.
func (c *GHClient) GetCIStatusForChecks(ctx context.Context, owner, repoName string, ref string, checkNames []string) (CIStatus, []string, error) {
func (c GHClient) GetCIStatusForChecks(ctx context.Context, owner, repoName string, ref string, checkNames []string) (CIStatus, []string, error) {
allFinished := true
awaitedChecks := make(map[string]bool, len(checkNames))
var status CIStatus
Expand Down

0 comments on commit 04e405d

Please sign in to comment.