2017-05-13 18:09:42 -03:00
|
|
|
// Package client contains the client implementations for several providers.
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
2020-07-06 14:48:17 +01:00
|
|
|
"fmt"
|
2017-05-13 18:09:42 -03:00
|
|
|
"os"
|
|
|
|
|
2022-06-21 21:11:15 -03:00
|
|
|
"github.com/caarlos0/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
|
|
|
)
|
|
|
|
|
2021-11-11 13:31:01 +01:00
|
|
|
const (
|
|
|
|
// maxReleaseBodyLength defines the max characters size of the body
|
|
|
|
maxReleaseBodyLength = 125000
|
|
|
|
// ellipsis to be used when release notes body is too long
|
|
|
|
ellipsis = "..."
|
|
|
|
)
|
|
|
|
|
2021-10-04 09:32:30 -03:00
|
|
|
// ErrNotImplemented is returned when a client does not implement certain feature.
|
|
|
|
var ErrNotImplemented = fmt.Errorf("not implemented")
|
|
|
|
|
feat: allow goreleaser to run in gerrit, soft-serve and others (#4271)
Currently, GoReleaser will assume you're running against github, gitea
or gitlab.
You could set `release.disable: true`, but it would still set and try to
use some defaults that could break things up.
Now, if you disable the release, goreleaser will not set these defaults.
It'll also hard error in some cases in which it would happily produce
invalid resources before, namely, if `release.disable` is set, and, for
example, `brews.url_template` is empty (in which case it would try to
use the one from the release, usually github).
closes #4208
2023-09-04 11:23:38 -03:00
|
|
|
// ErrReleaseDisabled happens when a configuration tries to use the default
|
|
|
|
// url_template even though the release is disabled.
|
|
|
|
var ErrReleaseDisabled = fmt.Errorf("release is disabled, cannot use default url_template")
|
|
|
|
|
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 {
|
2023-04-30 10:18:13 -03:00
|
|
|
Owner string
|
|
|
|
Name string
|
|
|
|
Branch string
|
|
|
|
GitURL string
|
|
|
|
GitSSHCommand string
|
|
|
|
PrivateKey string
|
2020-07-06 21:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2024-02-19 13:50:47 +01:00
|
|
|
// Creates a release. It's marked as draft if possible (should call PublishRelease to finish publishing).
|
2019-06-29 16:02:40 +02:00
|
|
|
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
|
2024-02-19 13:50:47 +01:00
|
|
|
PublishRelease(ctx *context.Context, releaseID 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)
|
2021-10-04 09:32:30 -03:00
|
|
|
Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error)
|
feat: allow goreleaser to run in gerrit, soft-serve and others (#4271)
Currently, GoReleaser will assume you're running against github, gitea
or gitlab.
You could set `release.disable: true`, but it would still set and try to
use some defaults that could break things up.
Now, if you disable the release, goreleaser will not set these defaults.
It'll also hard error in some cases in which it would happily produce
invalid resources before, namely, if `release.disable` is set, and, for
example, `brews.url_template` is empty (in which case it would try to
use the one from the release, usually github).
closes #4208
2023-09-04 11:23:38 -03:00
|
|
|
ReleaseURLTemplater
|
2023-04-30 10:18:13 -03:00
|
|
|
FileCreator
|
|
|
|
}
|
|
|
|
|
feat: allow goreleaser to run in gerrit, soft-serve and others (#4271)
Currently, GoReleaser will assume you're running against github, gitea
or gitlab.
You could set `release.disable: true`, but it would still set and try to
use some defaults that could break things up.
Now, if you disable the release, goreleaser will not set these defaults.
It'll also hard error in some cases in which it would happily produce
invalid resources before, namely, if `release.disable` is set, and, for
example, `brews.url_template` is empty (in which case it would try to
use the one from the release, usually github).
closes #4208
2023-09-04 11:23:38 -03:00
|
|
|
// ReleaseURLTemplater provides the release URL as a template, containing the
|
2023-04-30 10:18:13 -03:00
|
|
|
// artifact name as well.
|
feat: allow goreleaser to run in gerrit, soft-serve and others (#4271)
Currently, GoReleaser will assume you're running against github, gitea
or gitlab.
You could set `release.disable: true`, but it would still set and try to
use some defaults that could break things up.
Now, if you disable the release, goreleaser will not set these defaults.
It'll also hard error in some cases in which it would happily produce
invalid resources before, namely, if `release.disable` is set, and, for
example, `brews.url_template` is empty (in which case it would try to
use the one from the release, usually github).
closes #4208
2023-09-04 11:23:38 -03:00
|
|
|
type ReleaseURLTemplater interface {
|
2023-04-30 10:18:13 -03:00
|
|
|
ReleaseURLTemplate(ctx *context.Context) (string, error)
|
|
|
|
}
|
|
|
|
|
2023-06-14 23:52:35 -03:00
|
|
|
// RepoFile is a file to be created.
|
|
|
|
type RepoFile struct {
|
2023-07-19 22:04:45 -03:00
|
|
|
Content []byte
|
|
|
|
Path string
|
|
|
|
Identifier string // for the use of the caller.
|
2023-06-14 23:52:35 -03:00
|
|
|
}
|
|
|
|
|
2023-04-30 10:18:13 -03:00
|
|
|
// FileCreator can create the given file to some code repository.
|
|
|
|
type FileCreator interface {
|
|
|
|
CreateFile(ctx *context.Context, commitAuthor config.CommitAuthor, repo Repo, content []byte, path, message string) (err error)
|
2019-06-29 16:02:40 +02:00
|
|
|
}
|
|
|
|
|
2023-06-14 23:52:35 -03:00
|
|
|
// FilesCreator can create the multiple files in some repository and in a single commit.
|
|
|
|
type FilesCreator interface {
|
|
|
|
FileCreator
|
|
|
|
CreateFiles(ctx *context.Context, commitAuthor config.CommitAuthor, repo Repo, message string, files []RepoFile) (err error)
|
|
|
|
}
|
|
|
|
|
2023-04-06 22:58:06 -03:00
|
|
|
// ReleaseNotesGenerator can generate release notes.
|
|
|
|
type ReleaseNotesGenerator interface {
|
2021-11-07 12:53:28 -03:00
|
|
|
GenerateReleaseNotes(ctx *context.Context, repo Repo, prev, current string) (string, error)
|
|
|
|
}
|
|
|
|
|
2023-04-06 22:58:06 -03:00
|
|
|
// PullRequestOpener can open pull requests.
|
|
|
|
type PullRequestOpener interface {
|
2023-05-29 15:07:00 -03:00
|
|
|
OpenPullRequest(ctx *context.Context, base, head Repo, title string, draft bool) error
|
2023-04-06 22:58:06 -03: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
|
|
|
}
|
|
|
|
|
feat: allow goreleaser to run in gerrit, soft-serve and others (#4271)
Currently, GoReleaser will assume you're running against github, gitea
or gitlab.
You could set `release.disable: true`, but it would still set and try to
use some defaults that could break things up.
Now, if you disable the release, goreleaser will not set these defaults.
It'll also hard error in some cases in which it would happily produce
invalid resources before, namely, if `release.disable` is set, and, for
example, `brews.url_template` is empty (in which case it would try to
use the one from the release, usually github).
closes #4208
2023-09-04 11:23:38 -03:00
|
|
|
// NewReleaseClient returns a ReleaserURLTemplater, handling the possibility of
|
|
|
|
// the release being disabled.
|
|
|
|
func NewReleaseClient(ctx *context.Context) (ReleaseURLTemplater, error) {
|
|
|
|
disable, err := tmpl.New(ctx).Bool(ctx.Config.Release.Disable)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if disable {
|
|
|
|
return errURLTemplater{}, nil
|
|
|
|
}
|
|
|
|
return New(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ ReleaseURLTemplater = errURLTemplater{}
|
|
|
|
|
|
|
|
type errURLTemplater struct{}
|
|
|
|
|
|
|
|
func (errURLTemplater) ReleaseURLTemplate(_ *context.Context) (string, error) {
|
|
|
|
return "", ErrReleaseDisabled
|
|
|
|
}
|
|
|
|
|
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")
|
2021-10-03 13:24:20 -03:00
|
|
|
switch ctx.TokenType {
|
|
|
|
case context.TokenTypeGitHub:
|
2023-04-06 22:58:06 -03:00
|
|
|
return newGitHub(ctx, token)
|
2021-10-03 13:24:20 -03:00
|
|
|
case context.TokenTypeGitLab:
|
2023-04-06 22:58:06 -03:00
|
|
|
return newGitLab(ctx, token)
|
2021-10-03 13:24:20 -03:00
|
|
|
case context.TokenTypeGitea:
|
2023-04-06 22:58:06 -03:00
|
|
|
return newGitea(ctx, token)
|
2021-10-03 13:24:20 -03:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("invalid client token type: %q", ctx.TokenType)
|
2019-08-26 10:31:38 +03:00
|
|
|
}
|
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)
|
|
|
|
}
|
|
|
|
|
2021-11-11 13:31:01 +01:00
|
|
|
func truncateReleaseBody(body string) string {
|
|
|
|
if len(body) > maxReleaseBodyLength {
|
|
|
|
body = body[1:(maxReleaseBodyLength-len(ellipsis))] + ellipsis
|
|
|
|
}
|
|
|
|
return body
|
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
}
|