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 }
func newDraftRepositoryRelease(id int, version string) github.RepositoryRelease { return github.RepositoryRelease{ TagName: github.String(version), Draft: github.Bool(true), ID: github.Int(id), } }
func TestGitHubClient_Upload(t *testing.T) { client := testGithubClient(t) testTag := "github-client-upload-asset" req := &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(true), } release, err := client.CreateRelease(context.TODO(), req) if err != nil { t.Fatal("CreateRelease failed:", err) } defer func() { if err := client.DeleteRelease(context.TODO(), *release.ID); err != nil { t.Fatalf("DeleteRelease failed: %s", err) } }() filename := filepath.Join("./testdata", "darwin_386") asset, err := client.UploadAsset(context.TODO(), *release.ID, filename) if err != nil { t.Fatal("UploadAsset failed:", err) } githubClient, ok := client.(*GitHubClient) if !ok { t.Fatal("Faield to asset to GithubClient") } rc, url, err := githubClient.Repositories.DownloadReleaseAsset( githubClient.Owner, githubClient.Repo, *asset.ID) if err != nil { t.Fatal("DownloadReleaseAsset failed:", err) } var buf bytes.Buffer if len(url) != 0 { res, err := http.Get(url) if err != nil { t.Fatal("http.Get failed:", err) } if _, err := io.Copy(&buf, res.Body); err != nil { t.Fatal("Copy failed:", err) } res.Body.Close() } else { if _, err := io.Copy(&buf, rc); err != nil { t.Fatal("Copy failed:", err) } rc.Close() } if got, want := buf.String(), "darwin_386\n"; got != want { t.Fatalf("file body is %q, want %q", got, want) } }
func TestGHR_UploadAssets(t *testing.T) { githubClient := testGithubClient(t) GHR := &GHR{ GitHub: githubClient, outStream: ioutil.Discard, } testTag := "ghr-upload-assets" req := &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(true), } // Create an existing release before release, err := githubClient.CreateRelease(context.TODO(), req) if err != nil { t.Fatalf("CreateRelease failed: %s", err) } defer func() { if err := githubClient.DeleteRelease(context.TODO(), *release.ID); err != nil { t.Fatal("DeleteRelease failed:", err) } }() localTestAssets, err := LocalAssets(TestDir) if err != nil { t.Fatal("LocalAssets failed:", err) } if err := GHR.UploadAssets(context.TODO(), *release.ID, localTestAssets, 4); err != nil { t.Fatal("GHR.UploadAssets failed:", err) } assets, err := githubClient.ListAssets(context.TODO(), *release.ID) if err != nil { t.Fatal("ListAssets failed:", err) } if got, want := len(assets), 4; got != want { t.Fatalf("upload assets number = %d, want %d", got, want) } // Delete all assets parallel := 4 if err := GHR.DeleteAssets(context.TODO(), *release.ID, localTestAssets, parallel); err != nil { t.Fatal("GHR.DeleteAssets failed:", err) } assets, err = githubClient.ListAssets(context.TODO(), *release.ID) if err != nil { t.Fatal("ListAssets failed:", err) } if got, want := len(assets), 0; got != want { t.Fatalf("upload assets number = %d, want %d", got, want) } }
func TestActivity_Watching(t *testing.T) { watchers, _, err := client.Activity.ListWatchers("google", "go-github", nil) if err != nil { t.Fatalf("Activity.ListWatchers returned error: %v", err) } if len(watchers) == 0 { t.Errorf("Activity.ListWatchers('google', 'go-github') returned no watchers") } // the rest of the tests requires auth if !checkAuth("TestActivity_Watching") { return } // first, check if already watching google/go-github sub, _, err := client.Activity.GetRepositorySubscription("google", "go-github") if err != nil { t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) } if sub != nil { t.Fatalf("Already watching google/go-github. Please manually stop watching it first.") } // watch google/go-github sub = &github.Subscription{Subscribed: github.Bool(true)} _, _, err = client.Activity.SetRepositorySubscription("google", "go-github", sub) if err != nil { t.Fatalf("Activity.SetRepositorySubscription returned error: %v", err) } // check again and verify watching sub, _, err = client.Activity.GetRepositorySubscription("google", "go-github") if err != nil { t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) } if sub == nil || !*sub.Subscribed { t.Fatalf("Not watching google/go-github after setting subscription.") } // delete subscription _, err = client.Activity.DeleteRepositorySubscription("google", "go-github") if err != nil { t.Fatalf("Activity.DeleteRepositorySubscription returned error: %v", err) } // check again and verify not watching sub, _, err = client.Activity.GetRepositorySubscription("google", "go-github") if err != nil { t.Fatalf("Activity.GetRepositorySubscription returned error: %v", err) } if sub != nil { t.Fatalf("Still watching google/go-github after deleting subscription.") } }
// CreateRepo will create a new repository in the organization on github. // // TODO: When the hook option is activated, it can only create a push hook. // Extend this to include a optional event hook. func (o *Organization) CreateRepo(opt RepositoryOptions) (err error) { err = o.connectAdminToGithub() if err != nil { return } if opt.Name == "" { return errors.New("Missing required name field. ") } repo := &github.Repository{} repo.Name = github.String(opt.Name) repo.Private = github.Bool(opt.Private) repo.AutoInit = github.Bool(opt.AutoInit) repo.HasIssues = github.Bool(opt.Issues) if opt.TeamID != 0 { repo.TeamID = github.Int(opt.TeamID) } _, _, err = o.githubadmin.Repositories.Create(o.Name, repo) if err != nil { return } if opt.Hook != "" { config := make(map[string]interface{}) config["url"] = global.Hostname + "/event/hook" config["content_type"] = "json" hook := github.Hook{ Name: github.String("web"), Config: config, Events: []string{ opt.Hook, }, } _, _, err = o.githubadmin.Repositories.CreateHook(o.Name, opt.Name, &hook) } return }
// NewHook returns a new github.Hook instance that represents the appropriate // configuration for the Conveyor webhook. func NewHook(url, secret string) *github.Hook { return &github.Hook{ Events: []string{"push"}, Active: github.Bool(true), Name: github.String("web"), Config: map[string]interface{}{ "url": url, "content_type": "json", "secret": secret, }, } }
func TestRepositories_EditBranches(t *testing.T) { if !checkAuth("TestRepositories_EditBranches") { return } // get authenticated user me, _, err := client.Users.Get("") if err != nil { t.Fatalf("Users.Get('') returned error: %v", err) } repo, err := createRandomTestRepository(*me.Login, true) if err != nil { t.Fatalf("createRandomTestRepository returned error: %v", err) } branch, _, err := client.Repositories.GetBranch(*repo.Owner.Login, *repo.Name, "master") if err != nil { t.Fatalf("Repositories.GetBranch() returned error: %v", err) } if *branch.Protection.Enabled { t.Fatalf("Branch %v of repo %v is already protected", "master", *repo.Name) } branch.Protection.Enabled = github.Bool(true) branch.Protection.RequiredStatusChecks = &github.RequiredStatusChecks{ EnforcementLevel: github.String("everyone"), Contexts: &[]string{"continous-integration"}, } branch, _, err = client.Repositories.EditBranch(*repo.Owner.Login, *repo.Name, "master", branch) if err != nil { t.Fatalf("Repositories.EditBranch() returned error: %v", err) } if !*branch.Protection.Enabled { t.Fatalf("Branch %v of repo %v should be protected, but is not!", "master", *repo.Name) } if *branch.Protection.RequiredStatusChecks.EnforcementLevel != "everyone" { t.Fatalf("RequiredStatusChecks should be enabled for everyone, set for: %v", *branch.Protection.RequiredStatusChecks.EnforcementLevel) } wantedContexts := []string{"continous-integration"} if !reflect.DeepEqual(*branch.Protection.RequiredStatusChecks.Contexts, wantedContexts) { t.Fatalf("RequiredStatusChecks.Contexts should be: %v but is: %v", wantedContexts, *branch.Protection.RequiredStatusChecks.Contexts) } _, err = client.Repositories.Delete(*repo.Owner.Login, *repo.Name) if err != nil { t.Fatalf("Repositories.Delete() returned error: %v", err) } }
func TestGitHubClient_ListAssets(t *testing.T) { client := testGithubClient(t) testTag := "github-list-assets" req := &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(true), } release, err := client.CreateRelease(context.TODO(), req) if err != nil { t.Fatal("CreateRelease failed:", err) } defer func() { if err := client.DeleteRelease(context.TODO(), *release.ID); err != nil { t.Fatalf("DeleteRelease failed: %s", err) } }() for _, filename := range []string{"darwin_386", "darwin_amd64"} { filename := filepath.Join("./testdata", filename) if _, err := client.UploadAsset(context.TODO(), *release.ID, filename); err != nil { t.Fatal("UploadAsset failed:", err) } } assets, err := client.ListAssets(context.TODO(), *release.ID) if err != nil { t.Fatal("ListAssets failed:", err) } if got, want := len(assets), 2; got != want { t.Fatalf("ListAssets number = %d, want %d", got, want) } if err := client.DeleteAsset(context.TODO(), *assets[0].ID); err != nil { t.Fatal("DeleteAsset failed:", err) } assets, err = client.ListAssets(context.TODO(), *release.ID) if err != nil { t.Fatal("ListAssets failed:", err) } if got, want := len(assets), 1; got != want { t.Fatalf("ListAssets number = %d, want %d", got, want) } }
// create a new private repository named name for the given team func createRepo(name string, team int) { repo := &github.Repository{ Name: github.String(name), Private: github.Bool(false), // TODO Update once github has given me private repos } r, _, err := client.Repositories.Create(courseOrg, repo) if err != nil { fmt.Printf("Failed to create repo: %s: %v\n", name, err) return } fmt.Printf("Created repository: %s for team %d;\n URL: %s\n", name, team, *r.URL) _, err = client.Organizations.AddTeamRepo(team, courseOrg, name) if err != nil { fmt.Printf("Failed to add team %d to repo: %s: %v\n", team, name, err) } fmt.Println("Added team to repository:", name) }
// Create will create a Gist(https://gist.github.com/) // // If gist was created http.Response.StatusCode will be // http.StatusCreated.(201) func Create(githubToken string, gistParam CreateParams) (string, *http.Response, error) { client := connectGithub(githubToken) gf := &github.GistFile{ Filename: github.String(gistParam.FileName), Content: github.String(gistParam.Content), } gist := &github.Gist{ Description: github.String(gistParam.Description), Public: github.Bool(gistParam.Public), Files: map[github.GistFilename]github.GistFile{"": *gf}, } gst, resp, err := client.Gists.Create(gist) return *gst.HTMLURL, resp.Response, err }
func (b *GithubBackend) CreateDeployment(ref string, env string) error { client := b.getClient() user, repo := b.parseGithubInfo() status_req := github.DeploymentRequest{ Ref: &ref, Task: github.String("deploy"), AutoMerge: github.Bool(false), Environment: &env, } _, _, err := client.Repositories.CreateDeployment(user, repo, &status_req) if err != nil { return err } return nil }
func TestGHR_CreateRelease(t *testing.T) { t.Parallel() githubClient := testGithubClient(t) GHR := &GHR{ GitHub: githubClient, outStream: ioutil.Discard, } testTag := "create-release" req := &github.RepositoryRelease{ TagName: &testTag, Draft: github.Bool(false), } recreate := false release, err := GHR.CreateRelease(context.TODO(), req, recreate) if err != nil { t.Fatal("CreateRelease failed:", err) } defer GHR.DeleteRelease(context.TODO(), *release.ID, testTag) }
// CreateRepo creates a repository in the github user account func (repo GithubRepository) CreateRepo(username, reponame, org string, private bool) (*domain.Repository, error) { rp := &github.Repository{ Name: github.String(reponame), Private: github.Bool(private), } rp, _, err := repo.client.Repositories.Create(org, rp) if err != nil { return nil, err } r := &domain.Repository{ Name: rp.Name, FullName: rp.FullName, Description: rp.Description, Private: rp.Private, HTMLURL: rp.HTMLURL, CloneURL: rp.CloneURL, SSHURL: rp.SSHURL, } return r, nil }
On("Get", repositoryOwner, repositoryName, issueNumber). Return(nil, nil, errors.New("an error")) }) It("fails with a gateway error", func() { handle() Expect(responseRecorder.Code).To(Equal(http.StatusBadGateway)) }) }) Context("with the PR being already merged", func() { BeforeEach(func() { pullRequests. On("Get", repositoryOwner, repositoryName, issueNumber). Return(&github.PullRequest{ Merged: github.Bool(true), }, nil, nil) }) It("removes the 'merging' label from the PR", func() { issues. On("RemoveLabelForIssue", repositoryOwner, repositoryName, issueNumber, grh.MergingLabel). Return(nil, nil, nil) handle() Expect(responseRecorder.Code).To(Equal(http.StatusOK)) }) }) Context("with the PR not being mergeable", func() { BeforeEach(func() {
// PostProject ... func PostProject(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { user, err := session.GetUser(r) if err != nil { log.Fatal(err) } projectName := r.PostFormValue("name") if projectName == "" { log.Println("Missing projectName") http.Redirect(w, r, "/", http.StatusSeeOther) return } repoDescription := "Repository for " + projectName + " created by Hugoku" ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: user.Token.AccessToken}, ) tc := oauth2.NewClient(oauth2.NoContext, ts) client := github.NewClient(tc) log.Printf("Creating %s...", projectName) buildInfo, err := ci.Deploy(user.Username, projectName) log.Printf("Build duration: %s\n", buildInfo.BuildDuration) if err != nil { log.Fatalf("Error while trying to create project: %s", err) } if !repo.Exists(client, user.Username, projectName) { gitHubStartTime := time.Now() repo := &github.Repository{ Name: github.String(projectName), Private: github.Bool(false), Description: github.String(repoDescription), } repo, _, err = client.Repositories.Create("", repo) if err != nil { log.Fatalf("Error while trying to create repo: %s", err) } // Push the repo wd, _ := os.Getwd() err := os.Chdir(wd + "/repos/" + user.Username + "/" + projectName + "/") if err != nil { log.Fatal(err) } cmd.Run("git", []string{"init", "--quiet"}) cmd.Run("git", []string{"add", "."}) cmd.Run("git", []string{"commit", "-m", "'initial source code'"}) cmd.Run("git", []string{"remote", "add", "origin", "[email protected]:" + user.Username + "/" + projectName + ".git"}) cmd.Run("git", []string{"push", "--quiet", "-u", "origin", "master"}) err = os.Chdir(wd) if err != nil { log.Fatal(err) } githubTime := time.Since(gitHubStartTime) log.Printf("Git repo creation duration: %s\n", githubTime) } project := store.Project{Name: projectName, Description: repoDescription, BuildsInfo: []store.BuildInfo{buildInfo}, LastBuildInfo: buildInfo} user.Projects = append(user.Projects, project) err = store.SaveUser(user) http.Redirect(w, r, "/", http.StatusSeeOther) }
existingAssets := []github.ReleaseAsset{ { ID: github.Int(456789), Name: github.String("unicorns.txt"), }, { ID: github.Int(3450798), Name: github.String("rainbows.txt"), State: github.String("new"), }, } existingReleases := []github.RepositoryRelease{ { ID: github.Int(1), Draft: github.Bool(true), }, { ID: github.Int(112), TagName: github.String("some-tag-name"), Assets: []github.ReleaseAsset{existingAssets[0]}, Draft: github.Bool(false), }, } BeforeEach(func() { githubClient.ListReleasesReturns(existingReleases, nil) githubClient.ListReleaseAssetsReturns(existingAssets, nil) namePath := filepath.Join(sourcesDir, "name")
func createRandomTestRepository(owner string, autoinit bool) (*github.Repository, error) { // 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(owner, repoName) if err != nil { if resp.StatusCode == http.StatusNotFound { // found a non-existent repo, perfect break } return nil, err } } // create the repository repo, _, err := client.Repositories.Create("", &github.Repository{Name: github.String(repoName), AutoInit: github.Bool(autoinit)}) if err != nil { return nil, err } return repo, nil }
inRequest = resource.InRequest{} }) AfterEach(func() { Ω(os.RemoveAll(tmpDir)).Should(Succeed()) }) buildRelease := func(id int, tag string, draft bool) *github.RepositoryRelease { return &github.RepositoryRelease{ ID: github.Int(id), TagName: github.String(tag), HTMLURL: github.String("http://google.com"), Name: github.String("release-name"), Body: github.String("*markdown*"), Draft: github.Bool(draft), } } buildNilTagRelease := func(id int) *github.RepositoryRelease { return &github.RepositoryRelease{ ID: github.Int(id), HTMLURL: github.String("http://google.com"), Name: github.String("release-name"), Body: github.String("*markdown*"), Draft: github.Bool(true), } } buildAsset := func(id int, name string) github.ReleaseAsset { return github.ReleaseAsset{
func TestGHR_CreateReleaseWithExistingRelease(t *testing.T) { t.Parallel() githubClient := testGithubClient(t) GHR := &GHR{ GitHub: githubClient, outStream: ioutil.Discard, } testTag := "create-with-existing" existingReq := &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(false), } cases := []struct { request *github.RepositoryRelease recreate bool newRelease bool }{ // 0: When same tag as existing release is used { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(false), }, false, false, }, // 1: When draft release is requested { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(true), }, false, true, }, // 2: When recreate is requtested { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(false), }, true, true, }, // 3: When different tag is requtested { &github.RepositoryRelease{ TagName: github.String("v2.0.0"), Draft: github.Bool(false), }, false, true, }, } for i, tc := range cases { // Prevent a lot of requests at same time to GitHub API time.Sleep(1 * time.Second) // Create an existing release before existing, err := githubClient.CreateRelease(context.TODO(), existingReq) if err != nil { t.Fatalf("#%d CreateRelease failed: %s", i, err) } // Create a release for THIS TEST created, err := GHR.CreateRelease(context.TODO(), tc.request, tc.recreate) if err != nil { t.Fatalf("#%d GHR.CreateRelease failed: %s", i, err) } // Clean up existing release if !tc.recreate { err = GHR.DeleteRelease(context.TODO(), *existing.ID, *existingReq.TagName) if err != nil { t.Fatalf("#%d GHR.DeleteRelease (existing) failed: %s", i, err) } } if !tc.newRelease { if *created.ID != *existing.ID { t.Fatalf("#%d created ID %d, want %d (same as existing release ID)", i, *created.ID, *existing.ID) } continue } // Clean up newly created release before. When draft request, // tag is not created. So it need to be deleted separately by Github client. if *tc.request.Draft { // Clean up newly created release before checking if err := githubClient.DeleteRelease(context.TODO(), *created.ID); err != nil { t.Fatalf("#%d GitHub.DeleteRelease (created) failed: %s", i, err) } } else { err := GHR.DeleteRelease(context.TODO(), *created.ID, *tc.request.TagName) if err != nil { t.Fatalf("#%d GHR.DeleteRelease (created) failed: %s", i, err) } } if *created.ID == *existing.ID { t.Fatalf("#%d expect created ID %d to be different from existing ID %d", i, *created.ID, *existing.ID) } } }
func TestGitHubClient(t *testing.T) { t.Parallel() c := testGithubClient(t) testTag := "github-client" cases := []struct { Request *github.RepositoryRelease }{ { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(false), Prerelease: github.Bool(false), }, }, { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(false), Prerelease: github.Bool(true), }, }, { &github.RepositoryRelease{ TagName: github.String(testTag), Draft: github.Bool(true), Prerelease: github.Bool(false), }, }, } for i, tc := range cases { // Prevent a lot of requests at same time to GitHub API time.Sleep(1 * time.Second) created, err := c.CreateRelease(context.TODO(), tc.Request) if err != nil { t.Fatalf("#%d CreateRelease failed: %s", i, err) } // Draft release doesn't create tag. So it's not found. if !*created.Draft { got, err := c.GetRelease(context.TODO(), *created.TagName) if err != nil { t.Fatalf("#%d GetRelease failed: %s", i, err) } if *got.ID != *created.ID { t.Fatalf("got ID = %d, want %d", *got.ID, *created.ID) } } if err := c.DeleteRelease(context.TODO(), *created.ID); err != nil { t.Fatalf("#%d DeleteRelease failed: %s", i, err) } if *created.Draft { continue } if err := c.DeleteTag(context.TODO(), *tc.Request.TagName); err != nil { t.Fatalf("#%d DeleteTag failed: %s", i, err) } } }
func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, error) { params := request.Params name, err := c.fileContents(filepath.Join(sourceDir, request.Params.NamePath)) if err != nil { return OutResponse{}, err } tag, err := c.fileContents(filepath.Join(sourceDir, request.Params.TagPath)) if err != nil { return OutResponse{}, err } tag = request.Params.TagPrefix + tag var body string bodySpecified := false if request.Params.BodyPath != "" { bodySpecified = true body, err = c.fileContents(filepath.Join(sourceDir, request.Params.BodyPath)) if err != nil { return OutResponse{}, err } } targetCommitish := "" if request.Params.CommitishPath != "" { targetCommitish, err = c.fileContents(filepath.Join(sourceDir, request.Params.CommitishPath)) if err != nil { return OutResponse{}, err } } draft := request.Source.Drafts release := &github.RepositoryRelease{ Name: github.String(name), TagName: github.String(tag), Body: github.String(body), Draft: github.Bool(draft), TargetCommitish: github.String(targetCommitish), } existingReleases, err := c.github.ListReleases() if err != nil { return OutResponse{}, err } var existingRelease *github.RepositoryRelease for _, e := range existingReleases { if e.TagName != nil && *e.TagName == tag { existingRelease = &e break } } if existingRelease != nil { releaseAssets, err := c.github.ListReleaseAssets(*existingRelease) if err != nil { return OutResponse{}, err } existingRelease.Name = github.String(name) existingRelease.TargetCommitish = github.String(targetCommitish) existingRelease.Draft = github.Bool(draft) if bodySpecified { existingRelease.Body = github.String(body) } for _, asset := range releaseAssets { fmt.Fprintf(c.writer, "clearing existing asset: %s\n", *asset.Name) err := c.github.DeleteReleaseAsset(asset) if err != nil { return OutResponse{}, err } } fmt.Fprintf(c.writer, "updating release %s\n", name) release, err = c.github.UpdateRelease(*existingRelease) } else { fmt.Fprintf(c.writer, "creating release %s\n", name) release, err = c.github.CreateRelease(*release) } if err != nil { return OutResponse{}, err } for _, fileGlob := range params.Globs { matches, err := filepath.Glob(filepath.Join(sourceDir, fileGlob)) if err != nil { return OutResponse{}, err } if len(matches) == 0 { return OutResponse{}, fmt.Errorf("could not find file that matches glob '%s'", fileGlob) } for _, filePath := range matches { file, err := os.Open(filePath) if err != nil { return OutResponse{}, err } fmt.Fprintf(c.writer, "uploading %s\n", filePath) name := filepath.Base(filePath) err = c.github.UploadReleaseAsset(*release, name, file) for i := 0; i < 9 && err != nil; i++ { assets, err := c.github.ListReleaseAssets(*release) if err != nil { return OutResponse{}, err } for _, asset := range assets { if asset.Name != nil && *asset.Name == name { err = c.github.DeleteReleaseAsset(asset) if err != nil { return OutResponse{}, err } break } } err = c.github.UploadReleaseAsset(*release, name, file) } if err != nil { return OutResponse{}, err } file.Close() } } return OutResponse{ Version: versionFromRelease(release), Metadata: metadataFromRelease(release), }, nil }
// Run invokes the CLI with the given arguments. func (cli *CLI) Run(args []string) int { var ( owner string repo string token string commitish string draft bool prerelease bool parallel int recreate bool replace bool stat bool version bool debug bool ) flags := flag.NewFlagSet(Name, flag.ContinueOnError) flags.SetOutput(cli.errStream) flags.Usage = func() { fmt.Fprint(cli.errStream, helpText) } flags.StringVar(&owner, "username", "", "") flags.StringVar(&owner, "owner", "", "") flags.StringVar(&owner, "u", "", "") flags.StringVar(&repo, "repository", "", "") flags.StringVar(&repo, "r", "", "") flags.StringVar(&token, "token", os.Getenv(EnvGitHubToken), "") flags.StringVar(&token, "t", os.Getenv(EnvGitHubToken), "") flags.StringVar(&commitish, "commitish", "", "") flags.StringVar(&commitish, "c", "", "") flags.BoolVar(&draft, "draft", false, "") flags.BoolVar(&prerelease, "prerelease", false, "") flags.IntVar(¶llel, "parallel", DefaultParallel, "") flags.IntVar(¶llel, "p", DefaultParallel, "") flags.BoolVar(&recreate, "delete", false, "") flags.BoolVar(&recreate, "recreate", false, "") flags.BoolVar(&replace, "replace", false, "") flags.BoolVar(&version, "version", false, "") flags.BoolVar(&version, "v", false, "") flags.BoolVar(&debug, "debug", false, "") // Deprecated flags.BoolVar(&stat, "stat", false, "") // Parse flag if err := flags.Parse(args[1:]); err != nil { return ExitCodeParseFlagsError } if debug { os.Setenv(EnvDebug, "1") Debugf("Run as DEBUG mode") } // Show version and check latest version release if version { fmt.Fprintf(cli.outStream, OutputVersion()) return ExitCodeOK } parsedArgs := flags.Args() if len(parsedArgs) != 2 { PrintRedf(cli.errStream, "Invalid argument: you must set TAG and PATH name.") return ExitCodeBadArgs } tag, path := parsedArgs[0], parsedArgs[1] // Extract github repository owner name. // If it's not provided via command line flag, read it from .gitconfig // (github user or git user). if len(owner) == 0 { var err error owner, err = gitconfig.GithubUser() if err != nil { owner, err = gitconfig.Username() } if err != nil { PrintRedf(cli.errStream, "Failed to set up ghr: repository owner name not found\n") fmt.Fprintf(cli.errStream, "Please set it via `-u` option.\n\n"+ "You can set default owner name in `github.username` or `user.name`\n"+ "in `~/.gitconfig` file") return ExitCodeOwnerNotFound } } Debugf("Owner: %s", owner) // Extract repository name from files. // If not provided, read it from .git/config file. if len(repo) == 0 { var err error repo, err = gitconfig.Repository() if err != nil { PrintRedf(cli.errStream, "Failed to set up ghr: repository name not found\n") fmt.Fprintf(cli.errStream, "ghr reads it from `.git/config` file. Change directory to \n"+ "repository root directory or setup git repository.\n"+ "Or set it via `-r` option.\n") return ExitCodeOwnerNotFound } } Debugf("Repository: %s", repo) // If GitHub api token is not provided via command line flag // or env var then read it from .gitconfig file. if len(token) == 0 { var err error token, err = gitconfig.GithubToken() if err != nil { PrintRedf(cli.errStream, "Failed to set up ghr: token not found\n") fmt.Fprintf(cli.errStream, "To use ghr, you need a GitHub API token.\n"+ "Please set it via `%s` env var or `-t` option.\n\n"+ "If you don't have one, visit official doc (goo.gl/jSnoI)\n"+ "and get it first.\n", EnvGitHubToken) return ExitCodeTokenNotFound } } Debugf("Github API Token: %s", maskString(token)) // Set Base GitHub API. Base URL can be provided via env var. This is for GHE. baseURLStr := defaultBaseURL if urlStr := os.Getenv(EnvGitHubAPI); len(urlStr) != 0 { baseURLStr = urlStr } Debugf("Base GitHub API URL: %s", baseURLStr) if parallel <= 0 { parallel = runtime.NumCPU() } Debugf("Parallel factor: %d", parallel) localAssets, err := LocalAssets(path) if err != nil { PrintRedf(cli.errStream, "Failed to find assets from %s: %s\n", path, err) return ExitCodeError } Debugf("Number of file to upload: %d", len(localAssets)) // Create a GitHub client gitHubClient, err := NewGitHubClient(owner, repo, token, baseURLStr) if err != nil { PrintRedf(cli.errStream, "Failed to construct GitHub client: %s", err) return ExitCodeError } ghr := GHR{ GitHub: gitHubClient, outStream: cli.outStream, } // Prepare create release request req := &github.RepositoryRelease{ TagName: github.String(tag), Prerelease: github.Bool(prerelease), Draft: github.Bool(draft), TargetCommitish: github.String(commitish), } ctx := context.TODO() release, err := ghr.CreateRelease(ctx, req, recreate) if err != nil { PrintRedf(cli.errStream, "Failed to create GitHub release page: %s", err) return ExitCodeError } if replace { err := ghr.DeleteAssets(ctx, *release.ID, localAssets, parallel) if err != nil { PrintRedf(cli.errStream, "Failed to delete existing assets: %s", err) return ExitCodeError } } // FIXME(tcnksm): More ideal way to change this // This is for Github enterprise if err := ghr.GitHub.SetUploadURL(*release.UploadURL); err != nil { fmt.Fprintf(cli.errStream, "Failed to set upload URL %s: %s", *release.UploadURL, err) return ExitCodeError } err = ghr.UploadAssets(ctx, *release.ID, localAssets, parallel) if err != nil { PrintRedf(cli.errStream, "Failed to upload one of assets: %s", err) return ExitCodeError } return ExitCodeOK }
func Test_helper(t *testing.T) { g := goblin.Goblin(t) g.Describe("GitHub converter", func() { g.It("should convert passing status", func() { g.Assert(convertStatus(model.StatusSuccess)).Equal(statusSuccess) }) g.It("should convert pending status", func() { g.Assert(convertStatus(model.StatusPending)).Equal(statusPending) g.Assert(convertStatus(model.StatusRunning)).Equal(statusPending) }) g.It("should convert failing status", func() { g.Assert(convertStatus(model.StatusFailure)).Equal(statusFailure) }) g.It("should convert error status", func() { g.Assert(convertStatus(model.StatusKilled)).Equal(statusError) g.Assert(convertStatus(model.StatusError)).Equal(statusError) }) g.It("should convert passing desc", func() { g.Assert(convertDesc(model.StatusSuccess)).Equal(descSuccess) }) g.It("should convert pending desc", func() { g.Assert(convertDesc(model.StatusPending)).Equal(descPending) g.Assert(convertDesc(model.StatusRunning)).Equal(descPending) }) g.It("should convert failing desc", func() { g.Assert(convertDesc(model.StatusFailure)).Equal(descFailure) }) g.It("should convert error desc", func() { g.Assert(convertDesc(model.StatusKilled)).Equal(descError) g.Assert(convertDesc(model.StatusError)).Equal(descError) }) g.It("should convert repository lite", func() { from := github.Repository{ FullName: github.String("octocat/hello-world"), Name: github.String("hello-world"), Owner: &github.User{ AvatarURL: github.String("http://..."), Login: github.String("octocat"), }, } to := convertRepoLite(from) g.Assert(to.Avatar).Equal("http://...") g.Assert(to.FullName).Equal("octocat/hello-world") g.Assert(to.Owner).Equal("octocat") g.Assert(to.Name).Equal("hello-world") }) g.It("should convert repository list", func() { from := []github.Repository{ { FullName: github.String("octocat/hello-world"), Name: github.String("hello-world"), Owner: &github.User{ AvatarURL: github.String("http://..."), Login: github.String("octocat"), }, }, } to := convertRepoList(from) g.Assert(to[0].Avatar).Equal("http://...") g.Assert(to[0].FullName).Equal("octocat/hello-world") g.Assert(to[0].Owner).Equal("octocat") g.Assert(to[0].Name).Equal("hello-world") }) g.It("should convert repository", func() { from := github.Repository{ FullName: github.String("octocat/hello-world"), Name: github.String("hello-world"), HTMLURL: github.String("https://github.com/octocat/hello-world"), CloneURL: github.String("https://github.com/octocat/hello-world.git"), DefaultBranch: github.String("develop"), Private: github.Bool(true), Owner: &github.User{ AvatarURL: github.String("http://..."), Login: github.String("octocat"), }, } to := convertRepo(&from, false) g.Assert(to.Avatar).Equal("http://...") g.Assert(to.FullName).Equal("octocat/hello-world") g.Assert(to.Owner).Equal("octocat") g.Assert(to.Name).Equal("hello-world") g.Assert(to.Branch).Equal("develop") g.Assert(to.Kind).Equal("git") g.Assert(to.IsPrivate).IsTrue() g.Assert(to.Clone).Equal("https://github.com/octocat/hello-world.git") g.Assert(to.Link).Equal("https://github.com/octocat/hello-world") }) g.It("should convert repository permissions", func() { from := &github.Repository{ Permissions: &map[string]bool{ "admin": true, "push": true, "pull": true, }, } to := convertPerm(from) g.Assert(to.Push).IsTrue() g.Assert(to.Pull).IsTrue() g.Assert(to.Admin).IsTrue() }) g.It("should convert team", func() { from := github.Organization{ Login: github.String("octocat"), AvatarURL: github.String("http://..."), } to := convertTeam(from) g.Assert(to.Login).Equal("octocat") g.Assert(to.Avatar).Equal("http://...") }) g.It("should convert team list", func() { from := []github.Organization{ { Login: github.String("octocat"), AvatarURL: github.String("http://..."), }, } to := convertTeamList(from) g.Assert(to[0].Login).Equal("octocat") g.Assert(to[0].Avatar).Equal("http://...") }) g.It("should convert a repository from webhook", func() { from := &webhook{} from.Repo.Owner.Login = "******" from.Repo.Owner.Name = "octocat" from.Repo.Name = "hello-world" from.Repo.FullName = "octocat/hello-world" from.Repo.Private = true from.Repo.HTMLURL = "https://github.com/octocat/hello-world" from.Repo.CloneURL = "https://github.com/octocat/hello-world.git" from.Repo.DefaultBranch = "develop" repo := convertRepoHook(from) g.Assert(repo.Owner).Equal(from.Repo.Owner.Login) g.Assert(repo.Name).Equal(from.Repo.Name) g.Assert(repo.FullName).Equal(from.Repo.FullName) g.Assert(repo.IsPrivate).Equal(from.Repo.Private) g.Assert(repo.Link).Equal(from.Repo.HTMLURL) g.Assert(repo.Clone).Equal(from.Repo.CloneURL) g.Assert(repo.Branch).Equal(from.Repo.DefaultBranch) }) g.It("should convert a pull request from webhook", func() { from := &webhook{} from.PullRequest.Head.Ref = "master" from.PullRequest.Head.SHA = "f72fc19" from.PullRequest.HTMLURL = "https://github.com/octocat/hello-world/pulls/42" from.PullRequest.Number = 42 from.PullRequest.Title = "Updated README.md" from.PullRequest.User.Login = "******" from.PullRequest.User.Avatar = "https://avatars1.githubusercontent.com/u/583231" build := convertPullHook(from, true) g.Assert(build.Event).Equal(model.EventPull) g.Assert(build.Branch).Equal(from.PullRequest.Head.Ref) g.Assert(build.Ref).Equal("refs/pull/42/merge") g.Assert(build.Commit).Equal(from.PullRequest.Head.SHA) g.Assert(build.Message).Equal(from.PullRequest.Title) g.Assert(build.Title).Equal(from.PullRequest.Title) g.Assert(build.Author).Equal(from.PullRequest.User.Login) g.Assert(build.Avatar).Equal(from.PullRequest.User.Avatar) }) g.It("should convert a deployment from webhook", func() { from := &webhook{} from.Deployment.Desc = ":shipit:" from.Deployment.Env = "production" from.Deployment.ID = 42 from.Deployment.Ref = "master" from.Deployment.Sha = "f72fc19" from.Deployment.URL = "https://github.com/octocat/hello-world" from.Sender.Login = "******" from.Sender.Avatar = "https://avatars1.githubusercontent.com/u/583231" build := convertDeployHook(from) g.Assert(build.Event).Equal(model.EventDeploy) g.Assert(build.Branch).Equal("master") g.Assert(build.Ref).Equal("refs/heads/master") g.Assert(build.Commit).Equal(from.Deployment.Sha) g.Assert(build.Message).Equal(from.Deployment.Desc) g.Assert(build.Link).Equal(from.Deployment.URL) g.Assert(build.Author).Equal(from.Sender.Login) g.Assert(build.Avatar).Equal(from.Sender.Avatar) }) g.It("should convert a push from webhook", func() { from := &webhook{} from.Sender.Login = "******" from.Sender.Avatar = "https://avatars1.githubusercontent.com/u/583231" from.Repo.CloneURL = "https://github.com/octocat/hello-world.git" from.Head.Author.Email = "*****@*****.**" from.Head.Message = "updated README.md" from.Head.URL = "https://github.com/octocat/hello-world" from.Head.ID = "f72fc19" from.Ref = "refs/heads/master" build := convertPushHook(from) g.Assert(build.Event).Equal(model.EventPush) g.Assert(build.Branch).Equal("master") g.Assert(build.Ref).Equal("refs/heads/master") g.Assert(build.Commit).Equal(from.Head.ID) g.Assert(build.Message).Equal(from.Head.Message) g.Assert(build.Link).Equal(from.Head.URL) g.Assert(build.Author).Equal(from.Sender.Login) g.Assert(build.Avatar).Equal(from.Sender.Avatar) g.Assert(build.Email).Equal(from.Head.Author.Email) g.Assert(build.Remote).Equal(from.Repo.CloneURL) }) g.It("should convert a tag from webhook", func() { from := &webhook{} from.Ref = "refs/tags/v1.0.0" build := convertPushHook(from) g.Assert(build.Event).Equal(model.EventTag) g.Assert(build.Ref).Equal("refs/tags/v1.0.0") }) }) }
func (manager *releaseNotesManager) PostReleaseNotes( releaseNotes *common.ReleaseNotes, ) (action.Action, error) { // Get the GitHub owner and repository from the upstream URL. owner, repo, err := github.ParseUpstreamURL() if err != nil { return nil, err } // Instantiate the API client. client := github.NewClient(manager.config.Token) // Format the release notes. task := "Format the release notes" body := bytes.NewBufferString(` ## Summary ## **PLEASE FILL IN THE RELEASE SUMMARY** `) encoder, err := notes.NewEncoder(notes.EncodingMarkdown, body) if err != nil { return nil, errs.NewError(task, err) } if err := encoder.Encode(releaseNotes, nil); err != nil { return nil, errs.NewError(task, err) } bodyString := body.String() // Create GitHub release for the given version. tag := releaseNotes.Version.ReleaseTagString() releaseTask := fmt.Sprintf("Create GitHub release for tag '%v'", tag) log.Run(releaseTask) release, _, err := client.Repositories.CreateRelease(owner, repo, &gh.RepositoryRelease{ TagName: gh.String(tag), Name: gh.String("Release " + releaseNotes.Version.BaseString()), Body: &bodyString, Draft: gh.Bool(true), }) if err != nil { return nil, err } // Delete the GitHub release on rollback. rollback := func() error { log.Rollback(releaseTask) task := fmt.Sprintf("Delete GitHub release for tag '%v'", tag) _, err := client.Repositories.DeleteRelease(owner, repo, *release.ID) if err != nil { return errs.NewError(task, err) } return nil } // Open the release in the browser so that the user can fill in the details. task = "Open the release notes in the browser" if err := webbrowser.Open(*release.HTMLURL); err != nil { if ex := rollback(); ex != nil { errs.Log(ex) } return nil, errs.NewError(task, err) } // Return the rollback function. return action.ActionFunc(rollback), nil }
func newDraftWithNilTagRepositoryRelease(id int) github.RepositoryRelease { return github.RepositoryRelease{ Draft: github.Bool(true), ID: github.Int(id), } }