diff --git a/install/github/github.go b/install/github/github.go index 2f1a2c78..073df361 100644 --- a/install/github/github.go +++ b/install/github/github.go @@ -44,9 +44,33 @@ type GitHub struct { // Client is an interface modeling supported GitHub operations type Client interface { // TODO(install): Populate interface + CreateFile( + context.Context, string, string, string, *github.RepositoryContentFileOptions, + ) (*github.RepositoryContentResponse, *github.Response, error) + + CreatePullRequest( + context.Context, string, string, string, string, string, string, + ) (*github.PullRequest, error) + + CreateGitRef( + context.Context, string, string, *github.Reference, + ) (*github.Reference, *github.Response, error) + + GetBranch( + context.Context, string, string, string, bool, + ) (*github.Branch, *github.Response, error) + + GetContents( + context.Context, string, string, string, *github.RepositoryContentGetOptions, + ) (*github.RepositoryContent, []*github.RepositoryContent, *github.Response, error) + GetRepositoriesByOrg( context.Context, string, ) ([]*github.Repository, *github.Response, error) + + GetRepository( + context.Context, string, string, + ) (*github.Repository, *github.Response, error) } // Options is a set of options to configure the behavior of the GitHub package @@ -181,3 +205,75 @@ func (g *githubClient) GetRepositoriesByOrg( return repos, resp, nil } + +func (g *githubClient) GetRepository( + ctx context.Context, owner, repo string, +) (*github.Repository, *github.Response, error) { + pr, resp, err := g.Repositories.Get(ctx, owner, repo) + if err != nil { + return pr, resp, fmt.Errorf("getting repository: %w", err) + } + + return pr, resp, nil +} + +func (g *githubClient) GetBranch( + ctx context.Context, owner, repo, branch string, followRedirect bool) (*github.Branch, *github.Response, error) { + // TODO: Populate + return nil, nil, nil +} + +func (g *githubClient) GetContents( + ctx context.Context, owner, repo, path string, opts *github.RepositoryContentGetOptions) (*github.RepositoryContent, []*github.RepositoryContent, *github.Response, error) { + // TODO: Populate + return g.Repositories.GetContents( + ctx, + owner, + repo, + path, + opts, + ) +} + +func (g *githubClient) CreateGitRef( + ctx context.Context, owner, repo string, ref *github.Reference) (*github.Reference, *github.Response, error) { + // TODO: Populate + return g.Git.CreateRef( + ctx, + owner, + repo, + ref, + ) +} + +func (g *githubClient) CreateFile( + ctx context.Context, owner, repo, path string, opts *github.RepositoryContentFileOptions) (*github.RepositoryContentResponse, *github.Response, error) { + // TODO: Populate + return g.Repositories.CreateFile( + ctx, + owner, + repo, + path, + opts, + ) +} + +func (g *githubClient) CreatePullRequest( + ctx context.Context, owner, repo, baseBranchName, headBranchName, title, body string, +) (*github.PullRequest, error) { + newPullRequest := &github.NewPullRequest{ + Title: &title, + Head: &headBranchName, + Base: &baseBranchName, + Body: &body, + MaintainerCanModify: github.Bool(true), + } + + pr, _, err := g.PullRequests.Create(ctx, owner, repo, newPullRequest) + if err != nil { + return pr, fmt.Errorf("creating pull request: %w", err) + } + + logrus.Infof("Successfully created PR #%d", pr.GetNumber()) + return pr, nil +} diff --git a/install/install.go b/install/install.go index 256d4679..38182fec 100644 --- a/install/install.go +++ b/install/install.go @@ -22,7 +22,8 @@ import ( "io/ioutil" "github.com/google/go-github/v42/github" - "golang.org/x/oauth2" + + scagh "github.com/ossf/scorecard-action/install/github" ) const ( @@ -37,20 +38,16 @@ var RepoList = []string{} // Run adds the OpenSSF Scorecard workflow to all repositories under the given // organization. // TODO(install): Improve description. +// TODO(install): Accept a context instead of setting one. func Run() { // Get github user client. ctx := context.Background() - tokenService := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: pat}, - ) - - tokenClient := oauth2.NewClient(ctx, tokenService) - client := github.NewClient(tokenClient) + gh := scagh.New() + client := gh.Client() // If not provided, get all repositories under organization. if len(RepoList) == 0 { - lops := &github.RepositoryListByOrgOptions{Type: "all"} - repos, _, err := client.Repositories.ListByOrg(ctx, orgName, lops) + repos, _, err := client.GetRepositoriesByOrg(ctx, orgName) errCheck(err, "Error listing organization's repos.") // Convert to list of repository names. @@ -66,7 +63,7 @@ func Run() { // Process each repository. for _, repoName := range RepoList { // Get repo metadata. - repo, _, err := client.Repositories.Get(ctx, orgName, repoName) + repo, _, err := client.GetRepository(ctx, orgName, repoName) if err != nil { fmt.Println( "Skipped repo", @@ -78,7 +75,7 @@ func Run() { } // Get head commit SHA of default branch. - defaultBranch, _, err := client.Repositories.GetBranch( + defaultBranch, _, err := client.GetBranch( ctx, orgName, repoName, @@ -98,7 +95,7 @@ func Run() { defaultBranchSHA := defaultBranch.Commit.SHA // Skip if scorecard file already exists in workflows folder. - scoreFileContent, _, _, err := client.Repositories.GetContents( + scoreFileContent, _, _, err := client.GetContents( ctx, orgName, repoName, @@ -116,7 +113,7 @@ func Run() { } // Skip if branch scorecard already exists. - scorecardBranch, _, err := client.Repositories.GetBranch( + scorecardBranch, _, err := client.GetBranch( ctx, orgName, repoName, @@ -138,7 +135,7 @@ func Run() { Ref: github.String("refs/heads/scorecard"), Object: &github.GitObject{SHA: defaultBranchSHA}, } - _, _, err = client.Git.CreateRef(ctx, orgName, repoName, ref) + _, _, err = client.CreateGitRef(ctx, orgName, repoName, ref) if err != nil { fmt.Println( "Skipped repo", @@ -155,7 +152,7 @@ func Run() { Content: workflowContent, Branch: github.String("scorecard"), } - _, _, err = client.Repositories.CreateFile( + _, _, err = client.CreateFile( ctx, orgName, repoName, @@ -173,17 +170,15 @@ func Run() { } // Create Pull request. - pr := &github.NewPullRequest{ - Title: github.String("Added Scorecard Workflow"), - Head: github.String("scorecard"), - Base: github.String(*defaultBranch.Name), - Body: github.String( - "Added the workflow for OpenSSF's Security Scorecard", - ), - Draft: github.Bool(false), - } - - _, _, err = client.PullRequests.Create(ctx, orgName, repoName, pr) + _, err = client.CreatePullRequest( + ctx, + orgName, + repoName, + *defaultBranch.Name, + "scorecard", + "Added Scorecard Workflow", + "Added the workflow for OpenSSF's Security Scorecard", + ) if err != nil { fmt.Println( "Skipped repo",