func createSquashStatus(state, description string) *github.RepoStatus { return &github.RepoStatus{ State: github.String(state), Description: github.String(description), Context: github.String(githubStatusSquashContext), } }
// CreateKey is a heper function that creates a deploy key // for the specified repository. func CreateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) { var k = new(github.Key) k.Title = github.String(title) k.Key = github.String(key) created, _, err := client.Repositories.CreateKey(owner, name, k) return created, err }
func createIssue( task string, config Config, owner string, repo string, issueTitle string, issueBody string, milestone *github.Milestone, ) (issue *github.Issue, err error) { log.Run(task) client := ghutil.NewClient(config.Token()) labels := []string{config.ReviewLabel()} issue, _, err = client.Issues.Create(owner, repo, &github.IssueRequest{ Title: github.String(issueTitle), Body: github.String(issueBody), Labels: &labels, Milestone: milestone.Number, }) if err != nil { return nil, errs.NewError(task, err) } log.Log(fmt.Sprintf("GitHub issue #%v created", *issue.Number)) return issue, nil }
func (g *Github) SetStatus(u *model.User, r *model.Repo, num, granted, required int) error { client := setupClient(g.API, u.Token) pr, _, err := client.PullRequests.Get(r.Owner, r.Name, num) if err != nil { return err } status := "success" desc := "this commit looks good" if granted < required { status = "pending" desc = fmt.Sprintf("%d of %d required approvals granted", granted, required) } data := github.RepoStatus{ Context: github.String(context), State: github.String(status), Description: github.String(desc), } _, _, err = client.Repositories.CreateStatus(r.Owner, r.Name, *pr.Head.SHA, &data) return err }
func (g *Github) Tag(u *model.User, r *model.Repo, version *string, sha *string) error { client := setupClient(g.API, u.Token) t := time.Now() tag, _, err := client.Git.CreateTag(r.Owner, r.Name, &github.Tag{ Tag: version, SHA: sha, Message: github.String("Tagged by LGTM"), Tagger: &github.CommitAuthor{ Date: &t, Name: github.String("LGTM"), Email: github.String("*****@*****.**"), }, Object: &github.GitObject{ SHA: sha, Type: github.String("commit"), }, }) if err != nil { return err } _, _, err = client.Git.CreateRef(r.Owner, r.Name, &github.Reference{ Ref: github.String("refs/tags/" + *version), Object: &github.GitObject{ SHA: tag.SHA, }, }) return err }
//RegisterResult registers the supplied result func (githubClient *GitHubClient) RegisterResult(result Result) error { ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: githubClient.Token}, ) tc := oauth2.NewClient(oauth2.NoContext, ts) client := github.NewClient(tc) if githubClient.BaseUrl != nil { client.BaseURL = githubClient.BaseUrl } log.Info("Submitting result") repositories := client.Repositories status, _, err := repositories.CreateStatus( githubClient.From, githubClient.Repo, result.SHA, &github.RepoStatus{ State: github.String(result.State), TargetURL: github.String(result.Url), Description: github.String(result.Message), Context: github.String("continuous-integraion/walter"), }) log.Infof("Submit status: %s", status) if err != nil { log.Errorf("Failed to register result: %s", err) } return err }
func (tool *codeReviewTool) FinaliseRelease(v *version.Version) (action.Action, error) { // Get a GitHub client. config, err := LoadConfig() if err != nil { return nil, err } client := ghutil.NewClient(config.Token()) owner, repo, err := git.ParseUpstreamURL() if err != nil { return nil, err } // Get the relevant review milestone. releaseString := v.BaseString() task := fmt.Sprintf("Get GitHub review milestone for release %v", releaseString) log.Run(task) milestone, err := milestoneForVersion(config, owner, repo, v) if err != nil { return nil, errs.NewError(task, err) } if milestone == nil { log.Warn(fmt.Sprintf( "Weird, GitHub review milestone for release %v not found", releaseString)) return nil, nil } // Close the milestone unless there are some issues open. task = fmt.Sprintf( "Make sure the review milestone for release %v can be closed", releaseString) if num := *milestone.OpenIssues; num != 0 { return nil, errs.NewError( task, fmt.Errorf( "review milestone for release %v cannot be closed: %v issue(s) open", releaseString, num)) } milestoneTask := fmt.Sprintf("Close GitHub review milestone for release %v", releaseString) log.Run(milestoneTask) milestone, _, err = client.Issues.EditMilestone(owner, repo, *milestone.Number, &github.Milestone{ State: github.String("closed"), }) if err != nil { return nil, errs.NewError(milestoneTask, err) } // Return a rollback function. return action.ActionFunc(func() error { log.Rollback(milestoneTask) task := fmt.Sprintf("Reopen GitHub review milestone for release %v", releaseString) _, _, err := client.Issues.EditMilestone(owner, repo, *milestone.Number, &github.Milestone{ State: github.String("open"), }) if err != nil { return errs.NewError(task, err) } return nil }), nil }
// Test handler with correct input. func TestMain(t *testing.T) { pullrequest := github.PullRequestEvent{ Action: github.String("opened"), Number: github.Int(0), Repo: &github.Repository{ FullName: github.String("test"), }, } reqbody, _ := json.Marshal(pullrequest) handler := New(Configuration{}) runner := func(handler *Handler, event github.PullRequestEvent) {} ts := httptest.NewServer(mainHandler(handler, runner)) defer ts.Close() req, _ := http.NewRequest("GET", ts.URL, bytes.NewBuffer(reqbody)) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("HTTP Request failed: %s", err) } if resp.StatusCode != http.StatusAccepted { t.Errorf("Expected HTTP %d, got HTTP %d", http.StatusAccepted, resp.StatusCode) } }
func create(desc string, pub bool, files map[string]string) (*github.Gist, error) { ghat := getAccessToken() ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: ghat}, ) tc := oauth2.NewClient(oauth2.NoContext, ts) client := github.NewClient(tc) f := make(map[github.GistFilename]github.GistFile) for k := range files { _k := github.GistFilename(k) f[_k] = github.GistFile{Content: github.String(files[k])} } gist := &github.Gist{ Description: github.String(desc), Public: github.Bool(pub), Files: f, } gist, _, err := client.Gists.Create(gist) return gist, err }
// CreateTeam will create a new team in the organization on github. func (o *Organization) CreateTeam(opt TeamOptions) (teamID int, err error) { err = o.connectAdminToGithub() if err != nil { return } team := &github.Team{} team.Name = github.String(opt.Name) if opt.Permission != "" { team.Permission = github.String(opt.Permission) } team, _, err = o.githubadmin.Organizations.CreateTeam(o.Name, team) if err != nil { return } if opt.RepoNames != nil { for _, repo := range opt.RepoNames { _, err = o.githubadmin.Organizations.AddTeamRepo(*team.ID, o.Name, repo, nil) if err != nil { log.Println(err) } } } return *team.ID, nil }
func Success(url string, desc string, c string) *github.RepoStatus { return &github.RepoStatus{ State: github.String("success"), TargetURL: github.String(url), Description: github.String(desc), Context: github.String("pull/" + c), } }
func Failure(url string, desc string, c string) *github.RepoStatus { return &github.RepoStatus{ State: github.String("failure"), TargetURL: github.String(url), Description: github.String(desc), Context: github.String("pull/" + c), } }
func main() { owner := os.Getenv("GITHUB_OWNER") repo := os.Getenv("GITHUB_REPO") token := os.Getenv("GITHUB_AUTH_TOKEN") filename := os.Getenv("GITHUB_RELEASE_ASSET") releasename := os.Getenv("GITHUB_RELEASE_NAME") // Open the release asset file file, err := os.Open(filename) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Configure authentication ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) tc := oauth2.NewClient(oauth2.NoContext, ts) client := github.NewClient(tc) // Make a commit to Releases.md message := releasename content := []byte(releasename) repositoryContentsOptions := &github.RepositoryContentFileOptions{ Message: &message, Content: content, Committer: &github.CommitAuthor{Name: github.String("bonnyrigg"), Email: github.String("*****@*****.**")}, } path := "releases/" path += releasename _, _, err = client.Repositories.CreateFile(owner, repo, path, repositoryContentsOptions) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Create the release name := github.String(releasename) request := &github.RepositoryRelease{ Name: name, TagName: name, } release, _, err := client.Repositories.CreateRelease(owner, repo, request) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // Upload the release asset file to the release opt := &github.UploadOptions{Name: filename} releaseasset, _, err := client.Repositories.UploadReleaseAsset(owner, repo, *release.ID, opt, file) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } fmt.Printf("%s: Asset %s. Version: %s\n", *releaseasset.Name, *releaseasset.State, *name) }
// extendReviewRequest is a general function that can be used to extend // the given review issue with the given list of commits. func extendReviewRequest( config Config, owner string, repo string, issue *github.Issue, commits []*git.Commit, opts map[string]interface{}, ) error { var ( issueNum = *issue.Number issueBody = *issue.Body bodyBuffer = bytes.NewBufferString(issueBody) addedCommits = make([]*git.Commit, 0, len(commits)) ) for _, commit := range commits { // Make sure the commit is not added yet. commitString := fmt.Sprintf("] %v: %v", commit.SHA, commit.MessageTitle) if strings.Contains(issueBody, commitString) { log.Log(fmt.Sprintf("Commit %v already listed in issue #%v", commit.SHA, issueNum)) continue } // Extend the issue body. addedCommits = append(addedCommits, commit) fmt.Fprintf(bodyBuffer, "\n- [ ] %v: %v", commit.SHA, commit.MessageTitle) } if len(addedCommits) == 0 { log.Log(fmt.Sprintf("All commits already listed in issue #%v", issueNum)) return nil } // Edit the issue. task := fmt.Sprintf("Update GitHub issue #%v", issueNum) log.Run(task) client := ghutil.NewClient(config.Token()) newIssue, _, err := client.Issues.Edit(owner, repo, issueNum, &github.IssueRequest{ Body: github.String(bodyBuffer.String()), State: github.String("open"), }) if err != nil { return errs.NewError(task, err) } // Add the review comment. if err := addReviewComment(config, owner, repo, issueNum, addedCommits); err != nil { return err } // Open the issue if requested. if _, open := opts["open"]; open { return openIssue(newIssue) } return nil }
func (g *Github) ScheduleDeployment(u *model.User, r *model.Repo, d model.DeploymentInfo) error { client := setupClient(g.API, u.Token) _, _, err := client.Repositories.CreateDeployment(r.Owner, r.Name, &github.DeploymentRequest{ Ref: github.String(d.Ref), Task: github.String(d.Task), Environment: github.String(d.Environment), }) return err }
func repoStatus(client *github.Client, r *model.Repo, b *model.Build, link string) error { data := github.RepoStatus{ Context: github.String("continuous-integration/drone"), State: github.String(convertStatus(b.Status)), Description: github.String(convertDesc(b.Status)), TargetURL: github.String(link), } _, _, err := client.Repositories.CreateStatus(r.Owner, r.Name, b.Commit, &data) return err }
// CreateUpdateKey is a heper function that creates a deployment key // for the specified repository if it does not already exist, otherwise // it updates the existing key func CreateUpdateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) { var k, _ = GetKey(client, owner, name, title) if k != nil { k.Title = github.String(title) k.Key = github.String(key) client.Repositories.DeleteKey(owner, name, *k.ID) } return CreateKey(client, owner, name, title, key) }
// generatePersonalAuthTokenRequest is a helper function that generates an // AuthorizationRequest for a Personal Access Token (no client id). func generatePersonalAuthTokenRequest() *github.AuthorizationRequest { rand := randString() auth := github.AuthorizationRequest{ Note: github.String("Personal token: Note generated by test: " + rand), Scopes: []github.Scope{github.ScopePublicRepo}, Fingerprint: github.String("Personal token: Fingerprint generated by test: " + rand), } return &auth }
// CreateUpdateKey is a heper function that creates a deployment key // for the specified repository if it does not already exist, otherwise // it updates the existing key func CreateUpdateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) { var k, _ = GetKey(client, owner, name, title) if k != nil { k.Title = github.String(title) k.Key = github.String(key) var updated, _, err = client.Repositories.EditKey(owner, name, *k.ID, k) return updated, err } return CreateKey(client, owner, name, title, key) }
func TestRepositories_CRUD(t *testing.T) { if !checkAuth("TestRepositories_CRUD") { return } // get authenticated user me, _, err := client.Users.Get("") if err != nil { t.Fatalf("Users.Get('') returned error: %v", err) } // create random repo name that does not currently exist var repoName string for { repoName = fmt.Sprintf("test-%d", rand.Int()) _, resp, err := client.Repositories.Get(*me.Login, repoName) if err != nil { if resp.StatusCode == http.StatusNotFound { // found a non-existant repo, perfect break } t.Fatalf("Repositories.Get() returned error: %v", err) } } // create the repository repo, _, err := client.Repositories.Create("", &github.Repository{Name: github.String(repoName)}) if err != nil { t.Fatalf("Repositories.Create() returned error: %v", err) } // update the repository description repo.Description = github.String("description") repo.DefaultBranch = nil // FIXME: this shouldn't be necessary _, _, err = client.Repositories.Edit(*repo.Owner.Login, *repo.Name, repo) if err != nil { t.Fatalf("Repositories.Edit() returned error: %v", err) } // delete the repository _, err = client.Repositories.Delete(*repo.Owner.Login, *repo.Name) if err != nil { t.Fatalf("Repositories.Delete() returned error: %v", err) } // verify that the repository was deleted _, resp, err := client.Repositories.Get(*repo.Owner.Login, *repo.Name) if err == nil { t.Fatalf("Test repository still exists after deleting it.") } if err != nil && resp.StatusCode != http.StatusNotFound { t.Fatalf("Repositories.Get() returned error: %v", err) } }
func pending(client *github.Client, event *github.PullRequest) { user, repo, number := Data(event) commits, _, _ := client.PullRequests.ListCommits(user, repo, number, nil) for _, c := range commits { status := &github.RepoStatus{ State: github.String("pending"), Description: github.String("Running tests."), } client.Repositories.CreateStatus(user, repo, *c.SHA, status) } }
// generatePersonalAuthTokenRequest is a helper function that generates an // AuthorizationRequest for an OAuth application Token (uses client id). func generateAppAuthTokenRequest(clientID string, clientSecret string) *github.AuthorizationRequest { rand := randString() auth := github.AuthorizationRequest{ Note: github.String("App token: Note generated by test: " + rand), Scopes: []github.Scope{github.ScopePublicRepo}, Fingerprint: github.String("App token: Fingerprint generated by test: " + rand), ClientID: github.String(clientID), ClientSecret: github.String(clientSecret), } return &auth }
func (u *githubUpdater) UpdateStatus(d *Deployment) error { sp := strings.Split(d.Repo, "/") owner := sp[0] repo := sp[1] _, _, err := u.github.CreateDeploymentStatus(owner, repo, int(d.GitHubID), &github.DeploymentStatusRequest{ State: github.String(githubStatus[d.Status]), TargetURL: github.String(d.URL()), Description: github.String(d.Provider), }) return err }
func TestStatusUpdaterBuilder_Error(t *testing.T) { b := func(ctx context.Context, w io.Writer, opts BuildOptions) (string, error) { return "", errors.New("i/o timeout") } g := &MockGitHubClient{} w := &mockLogger{} builder := &statusUpdaterBuilder{ Builder: BuilderFunc(b), github: g, urlTmpl: template.Must(template.New("url").Parse("https://google.com")), } g.On("CreateStatus", "remind101", "acme-inc", "abcd", &github.RepoStatus{ State: github.String("pending"), Description: github.String("Image building."), TargetURL: github.String("https://google.com"), Context: github.String("container/docker"), }).Return(nil) g.On("CreateStatus", "remind101", "acme-inc", "abcd", &github.RepoStatus{ State: github.String("failure"), Description: github.String("i/o timeout"), TargetURL: github.String("https://google.com"), Context: github.String("container/docker"), }).Return(nil) builder.Build(context.Background(), w, BuildOptions{ Repository: "remind101/acme-inc", Branch: "master", Sha: "abcd", }) g.AssertExpectations(t) }
func (c githubClientMock) ListTeams(owner string, repo string, opt *github.ListOptions) ([]github.Team, *github.Response, error) { a := github.Team{ID: github.Int(1), Name: github.String("team_1"), Permission: github.String("pull")} b := github.Team{ID: github.Int(2), Name: github.String("team_2"), Permission: github.String("push")} if repo == "repo_1" { return []github.Team{a}, nil, nil } if repo == "repo_2" { return []github.Team{b}, nil, nil } if repo == "repo_3" { return []github.Team{a, b}, nil, nil } return []github.Team{}, nil, nil }
// updateStatus updates GitHub Pull Request status. func updateStatus(state, desc, url string) { s := &github.RepoStatus{ Context: github.String("builder"), State: github.String(state), Description: github.String(desc), } if url != "" { s.TargetURL = github.String(url) } _, _, err := client.ghub.Repositories.CreateStatus(repo.Owner, repo.Name, build.Commit, s) if err != nil { printf("ERROR: unable to update status: %v", err) } }
func TestRepoStatus(t *testing.T) { expected := &github.RepoStatus{ State: github.String("failure"), TargetURL: github.String("example.com"), Description: github.String("test"), Context: github.String("pull/failure"), } actual := Failure("example.com", "test", "failure") if !reflect.DeepEqual(actual, expected) { t.Errorf("Expected %+v, got %+v", expected, actual) } expected = &github.RepoStatus{ State: github.String("success"), TargetURL: github.String("example.com"), Description: github.String("test"), Context: github.String("pull/failure"), } actual = Success("example.com", "test", "failure") if !reflect.DeepEqual(actual, expected) { t.Errorf("Expected %+v, got %+v", expected, actual) } }
// Status sends the commit status to the remote system. // An example would be the GitHub pull request status. func (g *Github) Status(u *model.User, r *model.Repo, b *model.Build, link string) error { client := NewClient(g.API, u.Token, g.SkipVerify) status := getStatus(b.Status) desc := getDesc(b.Status) data := github.RepoStatus{ Context: github.String("continuous-integration/drone"), State: github.String(status), Description: github.String(desc), TargetURL: github.String(link), } _, _, err := client.Repositories.CreateStatus(r.Owner, r.Name, b.Commit, &data) return err }
func GetGitHubCommitRepoForTest(login string) GitHubCommitRepo { d := time.Now() return GitHubCommitRepo{ RepoName: "someuser/somerepo", RepositoryCommit: github.RepositoryCommit{ SHA: github.String("ffffffffffffffffffffffffffffffffffffffff"), Author: &github.User{ Login: github.String(login), }, Commit: &github.Commit{ SHA: github.String("ffffffffffffffffffffffffffffffffffffffff"), Author: &github.CommitAuthor{Date: &d}, Message: github.String("Some commit message."), }, Stats: &github.CommitStats{ Additions: github.Int(5), Deletions: github.Int(5), Total: github.Int(10), }, Files: []github.CommitFile{{ SHA: github.String("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"), Filename: github.String("some file name"), Additions: github.Int(5), Deletions: github.Int(5), Changes: github.Int(10), Status: github.String("modified"), Patch: github.String("Some patch"), }}, }, } }
func TestPending(t *testing.T) { user := "******" repo := "repo" number := 1 mux := http.NewServeMux() server := httptest.NewServer(mux) client := github.NewClient(nil) url, _ := url.Parse(server.URL) client.BaseURL = url client.UploadURL = url status := &github.RepoStatus{ State: github.String("pending"), Description: github.String("Running tests."), } statusendpoint := fmt.Sprintf("/repos/%s/%s/statuses/", user, repo) mux.HandleFunc(statusendpoint, func(w http.ResponseWriter, r *http.Request) { body := new(github.RepoStatus) json.NewDecoder(r.Body).Decode(body) if !reflect.DeepEqual(body, status) { t.Errorf("Expected %+v, got %+v", status, body) } fmt.Fprint(w, `{"id":1}`) }) commitendpoint := fmt.Sprintf("/repos/%s/%s/pulls/%d/commits", user, repo, number) mux.HandleFunc(commitendpoint, func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `[{"sha": "3", "parents": [{"sha": "2"}]}, {"sha": "2","parents": [{"sha": "1"}]}]`) }) req := &github.PullRequest{ Number: &number, Base: &github.PullRequestBranch{ User: &github.User{ Login: &user, }, Repo: &github.Repository{ Name: &repo, }, }, } pending(client, req) }