/
client.go
133 lines (113 loc) · 3.59 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Package client contains the client implementations for several providers.
package client
import (
"fmt"
"os"
"github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
const (
// maxReleaseBodyLength defines the max characters size of the body
maxReleaseBodyLength = 125000
// ellipsis to be used when release notes body is too long
ellipsis = "..."
)
// ErrNotImplemented is returned when a client does not implement certain feature.
var ErrNotImplemented = fmt.Errorf("not implemented")
// Info of the repository.
type Info struct {
Description string
Homepage string
URL string
}
type Repo struct {
Owner string
Name string
Branch string
GitURL string
GitSSHCommand string
PrivateKey string
}
func (r Repo) String() string {
if r.Owner == "" && r.Name == "" {
return ""
}
return r.Owner + "/" + r.Name
}
// Client interface.
type Client interface {
CloseMilestone(ctx *context.Context, repo Repo, title string) (err error)
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error)
ReleaserURLTemplater
FileCreator
}
// ReleaserURLTemplater provides the release URL as a template, containing the
// artifact name as well.
type ReleaserURLTemplater interface {
ReleaseURLTemplate(ctx *context.Context) (string, error)
}
// 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)
}
// ReleaseNotesGenerator can generate release notes.
type ReleaseNotesGenerator interface {
GenerateReleaseNotes(ctx *context.Context, repo Repo, prev, current string) (string, error)
}
// PullRequestOpener can open pull requests.
type PullRequestOpener interface {
OpenPullRequest(ctx *context.Context, repo Repo, head, title string) error
}
// New creates a new client depending on the token type.
func New(ctx *context.Context) (Client, error) {
return newWithToken(ctx, ctx.Token)
}
func newWithToken(ctx *context.Context, token string) (Client, error) {
log.WithField("type", ctx.TokenType).Debug("token type")
switch ctx.TokenType {
case context.TokenTypeGitHub:
return newGitHub(ctx, token)
case context.TokenTypeGitLab:
return newGitLab(ctx, token)
case context.TokenTypeGitea:
return newGitea(ctx, token)
default:
return nil, fmt.Errorf("invalid client token type: %q", ctx.TokenType)
}
}
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)
}
func truncateReleaseBody(body string) string {
if len(body) > maxReleaseBodyLength {
body = body[1:(maxReleaseBodyLength-len(ellipsis))] + ellipsis
}
return body
}
// 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)
}
// 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()
}