示例#1
0
文件: main.go 项目: chanux/gogist
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),
	}
}
示例#3
0
文件: github_test.go 项目: tchssk/ghr
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)
	}
}
示例#4
0
文件: ghr_test.go 项目: tchssk/ghr
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)
	}
}
示例#5
0
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.")
	}
}
示例#6
0
// 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
}
示例#7
0
// 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,
		},
	}
}
示例#8
0
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)
	}
}
示例#9
0
文件: github_test.go 项目: tchssk/ghr
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)
	}
}
示例#10
0
// 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)
}
示例#11
0
文件: gist.go 项目: 0x7cc/x16
// 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
}
示例#12
0
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
}
示例#13
0
文件: ghr_test.go 项目: tchssk/ghr
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)
}
示例#14
0
// 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() {
示例#16
0
// 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")
示例#18
0
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{
示例#20
0
文件: ghr_test.go 项目: tchssk/ghr
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)
		}
	}
}
示例#21
0
文件: github_test.go 项目: tchssk/ghr
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
}
示例#23
0
文件: cli.go 项目: tchssk/ghr
// 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(&parallel, "parallel", DefaultParallel, "")
	flags.IntVar(&parallel, "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
}
示例#24
0
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),
	}
}