2017-05-13 18:09:42 -03:00
|
|
|
// Package client contains the client implementations for several providers.
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
2020-11-10 11:15:03 -03:00
|
|
|
"errors"
|
2020-07-06 14:48:17 +01:00
|
|
|
"fmt"
|
2017-05-13 18:09:42 -03:00
|
|
|
"os"
|
|
|
|
|
2020-03-22 17:03:31 -03:00
|
|
|
"github.com/apex/log"
|
2019-08-13 20:28:03 +02:00
|
|
|
"github.com/goreleaser/goreleaser/internal/artifact"
|
2021-09-18 10:21:29 -03:00
|
|
|
"github.com/goreleaser/goreleaser/internal/tmpl"
|
2018-08-14 23:50:20 -03:00
|
|
|
"github.com/goreleaser/goreleaser/pkg/config"
|
|
|
|
"github.com/goreleaser/goreleaser/pkg/context"
|
2017-05-13 18:09:42 -03:00
|
|
|
)
|
|
|
|
|
2020-05-26 00:48:10 -03:00
|
|
|
// Info of the repository.
|
2017-05-13 18:09:42 -03:00
|
|
|
type Info struct {
|
|
|
|
Description string
|
|
|
|
Homepage string
|
|
|
|
URL string
|
|
|
|
}
|
|
|
|
|
2020-07-06 21:12:41 +01:00
|
|
|
type Repo struct {
|
|
|
|
Owner string
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r Repo) String() string {
|
|
|
|
if r.Owner == "" && r.Name == "" {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return r.Owner + "/" + r.Name
|
|
|
|
}
|
|
|
|
|
2020-05-26 00:48:10 -03:00
|
|
|
// Client interface.
|
2017-05-13 18:09:42 -03:00
|
|
|
type Client interface {
|
2020-07-09 16:40:37 -04:00
|
|
|
CloseMilestone(ctx *context.Context, repo Repo, title string) (err error)
|
2019-06-29 16:02:40 +02:00
|
|
|
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
|
2020-07-06 14:48:17 +01:00
|
|
|
ReleaseURLTemplate(ctx *context.Context) (string, error)
|
2020-07-06 21:12:41 +01:00
|
|
|
CreateFile(ctx *context.Context, commitAuthor config.CommitAuthor, repo Repo, content []byte, path, message string) (err error)
|
2019-08-13 20:28:03 +02:00
|
|
|
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
|
2019-06-29 16:02:40 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 00:48:10 -03:00
|
|
|
// New creates a new client depending on the token type.
|
2019-06-29 16:02:40 +02:00
|
|
|
func New(ctx *context.Context) (Client, error) {
|
2021-09-27 08:13:56 -03:00
|
|
|
return newWithToken(ctx, ctx.Token)
|
2020-07-06 21:12:41 +01:00
|
|
|
}
|
|
|
|
|
2021-09-18 10:21:29 -03:00
|
|
|
func newWithToken(ctx *context.Context, token string) (Client, error) {
|
2021-09-27 08:13:56 -03:00
|
|
|
log.WithField("type", ctx.TokenType).Debug("token type")
|
2020-07-06 21:12:41 +01:00
|
|
|
if ctx.TokenType == context.TokenTypeGitHub {
|
|
|
|
return NewGitHub(ctx, token)
|
2019-06-29 16:02:40 +02:00
|
|
|
}
|
|
|
|
if ctx.TokenType == context.TokenTypeGitLab {
|
2020-07-06 21:12:41 +01:00
|
|
|
return NewGitLab(ctx, token)
|
2019-06-29 16:02:40 +02:00
|
|
|
}
|
2019-08-26 10:31:38 +03:00
|
|
|
if ctx.TokenType == context.TokenTypeGitea {
|
2020-07-06 21:12:41 +01:00
|
|
|
return NewGitea(ctx, token)
|
2019-08-26 10:31:38 +03:00
|
|
|
}
|
2021-09-27 08:13:56 -03:00
|
|
|
return nil, fmt.Errorf("invalid client token type: %q", ctx.TokenType)
|
2017-05-13 18:09:42 -03:00
|
|
|
}
|
2020-03-22 17:03:31 -03:00
|
|
|
|
2021-09-18 10:21:29 -03:00
|
|
|
func NewIfToken(ctx *context.Context, cli Client, token string) (Client, error) {
|
|
|
|
if token == "" {
|
|
|
|
return cli, nil
|
|
|
|
}
|
|
|
|
token, err := tmpl.New(ctx).ApplySingleEnvOnly(token)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
log.Debug("using custom token")
|
|
|
|
return newWithToken(ctx, token)
|
|
|
|
}
|
|
|
|
|
2020-07-09 16:40:37 -04:00
|
|
|
// ErrNoMilestoneFound is an error when no milestone is found.
|
|
|
|
type ErrNoMilestoneFound struct {
|
|
|
|
Title string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e ErrNoMilestoneFound) Error() string {
|
|
|
|
return fmt.Sprintf("no milestone found: %s", e.Title)
|
|
|
|
}
|
|
|
|
|
2020-03-22 17:03:31 -03:00
|
|
|
// RetriableError is an error that will cause the action to be retried.
|
|
|
|
type RetriableError struct {
|
|
|
|
Err error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e RetriableError) Error() string {
|
|
|
|
return e.Err.Error()
|
|
|
|
}
|
2020-07-06 14:48:17 +01:00
|
|
|
|
2020-11-10 11:15:03 -03:00
|
|
|
// NotImplementedError happens when trying to use something a client does not
|
|
|
|
// implement.
|
2020-07-06 14:48:17 +01:00
|
|
|
type NotImplementedError struct {
|
|
|
|
TokenType context.TokenType
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e NotImplementedError) Error() string {
|
|
|
|
return fmt.Sprintf("not implemented for %s", e.TokenType)
|
|
|
|
}
|
|
|
|
|
2020-11-10 11:15:03 -03:00
|
|
|
// IsNotImplementedErr returns true if given error is a NotImplementedError.
|
2020-07-06 14:48:17 +01:00
|
|
|
func IsNotImplementedErr(err error) bool {
|
2020-11-10 11:15:03 -03:00
|
|
|
return errors.As(err, &NotImplementedError{})
|
2020-07-06 14:48:17 +01:00
|
|
|
}
|