github.phpd.cn/goreleaser/goreleaser@v0.92.0/internal/client/github.go (about)

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"net/url"
     6  	"os"
     7  
     8  	"github.com/apex/log"
     9  	"github.com/google/go-github/github"
    10  	"github.com/goreleaser/goreleaser/internal/tmpl"
    11  	"github.com/goreleaser/goreleaser/pkg/config"
    12  	"github.com/goreleaser/goreleaser/pkg/context"
    13  	"golang.org/x/oauth2"
    14  )
    15  
    16  type githubClient struct {
    17  	client *github.Client
    18  }
    19  
    20  // NewGitHub returns a github client implementation
    21  func NewGitHub(ctx *context.Context) (Client, error) {
    22  	ts := oauth2.StaticTokenSource(
    23  		&oauth2.Token{AccessToken: ctx.Token},
    24  	)
    25  	client := github.NewClient(oauth2.NewClient(ctx, ts))
    26  	if ctx.Config.GitHubURLs.API != "" {
    27  		api, err := url.Parse(ctx.Config.GitHubURLs.API)
    28  		if err != nil {
    29  			return &githubClient{}, err
    30  		}
    31  		upload, err := url.Parse(ctx.Config.GitHubURLs.Upload)
    32  		if err != nil {
    33  			return &githubClient{}, err
    34  		}
    35  		client.BaseURL = api
    36  		client.UploadURL = upload
    37  	}
    38  
    39  	return &githubClient{client: client}, nil
    40  }
    41  
    42  func (c *githubClient) CreateFile(
    43  	ctx *context.Context,
    44  	commitAuthor config.CommitAuthor,
    45  	repo config.Repo,
    46  	content bytes.Buffer,
    47  	path string,
    48  	message string,
    49  ) error {
    50  	options := &github.RepositoryContentFileOptions{
    51  		Committer: &github.CommitAuthor{
    52  			Name:  github.String(commitAuthor.Name),
    53  			Email: github.String(commitAuthor.Email),
    54  		},
    55  		Content: content.Bytes(),
    56  		Message: github.String(message),
    57  	}
    58  
    59  	file, _, res, err := c.client.Repositories.GetContents(
    60  		ctx,
    61  		repo.Owner,
    62  		repo.Name,
    63  		path,
    64  		&github.RepositoryContentGetOptions{},
    65  	)
    66  	if err != nil && res.StatusCode != 404 {
    67  		return err
    68  	}
    69  
    70  	if res.StatusCode == 404 {
    71  		_, _, err = c.client.Repositories.CreateFile(
    72  			ctx,
    73  			repo.Owner,
    74  			repo.Name,
    75  			path,
    76  			options,
    77  		)
    78  		return err
    79  	}
    80  	options.SHA = file.SHA
    81  	_, _, err = c.client.Repositories.UpdateFile(
    82  		ctx,
    83  		repo.Owner,
    84  		repo.Name,
    85  		path,
    86  		options,
    87  	)
    88  	return err
    89  }
    90  
    91  func (c *githubClient) CreateRelease(ctx *context.Context, body string) (int64, error) {
    92  	var release *github.RepositoryRelease
    93  	title, err := tmpl.New(ctx).Apply(ctx.Config.Release.NameTemplate)
    94  	if err != nil {
    95  		return 0, err
    96  	}
    97  	var data = &github.RepositoryRelease{
    98  		Name:       github.String(title),
    99  		TagName:    github.String(ctx.Git.CurrentTag),
   100  		Body:       github.String(body),
   101  		Draft:      github.Bool(ctx.Config.Release.Draft),
   102  		Prerelease: github.Bool(ctx.Config.Release.Prerelease),
   103  	}
   104  	release, _, err = c.client.Repositories.GetReleaseByTag(
   105  		ctx,
   106  		ctx.Config.Release.GitHub.Owner,
   107  		ctx.Config.Release.GitHub.Name,
   108  		ctx.Git.CurrentTag,
   109  	)
   110  	if err != nil {
   111  		release, _, err = c.client.Repositories.CreateRelease(
   112  			ctx,
   113  			ctx.Config.Release.GitHub.Owner,
   114  			ctx.Config.Release.GitHub.Name,
   115  			data,
   116  		)
   117  	} else {
   118  		release, _, err = c.client.Repositories.EditRelease(
   119  			ctx,
   120  			ctx.Config.Release.GitHub.Owner,
   121  			ctx.Config.Release.GitHub.Name,
   122  			release.GetID(),
   123  			data,
   124  		)
   125  	}
   126  	log.WithField("url", release.GetHTMLURL()).Info("release updated")
   127  	return release.GetID(), err
   128  }
   129  
   130  func (c *githubClient) Upload(
   131  	ctx *context.Context,
   132  	releaseID int64,
   133  	name string,
   134  	file *os.File,
   135  ) error {
   136  	_, _, err := c.client.Repositories.UploadReleaseAsset(
   137  		ctx,
   138  		ctx.Config.Release.GitHub.Owner,
   139  		ctx.Config.Release.GitHub.Name,
   140  		releaseID,
   141  		&github.UploadOptions{
   142  			Name: name,
   143  		},
   144  		file,
   145  	)
   146  	return err
   147  }