/
env.go
159 lines (135 loc) · 4 KB
/
env.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Package env implements the Pipe interface providing validation of
// missing environment variables needed by the release process.
package env
import (
"bufio"
"errors"
"fmt"
"io/fs"
"os"
"strings"
"github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
homedir "github.com/mitchellh/go-homedir"
)
// ErrMissingToken indicates an error when GITHUB_TOKEN, GITLAB_TOKEN and GITEA_TOKEN are all missing in the environment.
var ErrMissingToken = errors.New("missing GITHUB_TOKEN, GITLAB_TOKEN and GITEA_TOKEN")
// ErrMultipleTokens indicates that multiple tokens are defined. ATM only one of them if allowed.
// See https://github.com/goreleaser/goreleaser/pull/809
type ErrMultipleTokens struct {
tokens []string
}
func (e ErrMultipleTokens) Error() string {
return fmt.Sprintf("multiple tokens found, but only one is allowed: %s\n\nLearn more at https://goreleaser.com/errors/multiple-tokens\n", strings.Join(e.tokens, ", "))
}
// Pipe for env.
type Pipe struct{}
func (Pipe) String() string {
return "loading environment variables"
}
func setDefaultTokenFiles(ctx *context.Context) {
env := &ctx.Config.EnvFiles
if env.GitHubToken == "" {
env.GitHubToken = "~/.config/goreleaser/github_token"
}
if env.GitLabToken == "" {
env.GitLabToken = "~/.config/goreleaser/gitlab_token"
}
if env.GiteaToken == "" {
env.GiteaToken = "~/.config/goreleaser/gitea_token"
}
}
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
templ := tmpl.New(ctx).WithEnvS(os.Environ())
tEnv := []string{}
for i := range ctx.Config.Env {
env, err := templ.Apply(ctx.Config.Env[i])
if err != nil {
return err
}
tEnv = append(tEnv, env)
}
for k, v := range context.ToEnv(tEnv) {
ctx.Env[k] = v
}
setDefaultTokenFiles(ctx)
githubToken, githubTokenErr := loadEnv("GITHUB_TOKEN", ctx.Config.EnvFiles.GitHubToken)
gitlabToken, gitlabTokenErr := loadEnv("GITLAB_TOKEN", ctx.Config.EnvFiles.GitLabToken)
giteaToken, giteaTokenErr := loadEnv("GITEA_TOKEN", ctx.Config.EnvFiles.GiteaToken)
var tokens []string
if githubToken != "" {
tokens = append(tokens, "GITHUB_TOKEN")
}
if gitlabToken != "" {
tokens = append(tokens, "GITLAB_TOKEN")
}
if giteaToken != "" {
tokens = append(tokens, "GITEA_TOKEN")
}
if len(tokens) > 1 {
return ErrMultipleTokens{tokens}
}
noTokens := githubToken == "" && gitlabToken == "" && giteaToken == ""
noTokenErrs := githubTokenErr == nil && gitlabTokenErr == nil && giteaTokenErr == nil
if err := checkErrors(ctx, noTokens, noTokenErrs, gitlabTokenErr, githubTokenErr, giteaTokenErr); err != nil {
return err
}
if gitlabToken != "" {
log.Debug("token type: gitlab")
ctx.TokenType = context.TokenTypeGitLab
ctx.Token = gitlabToken
}
if giteaToken != "" {
log.Debug("token type: gitea")
ctx.TokenType = context.TokenTypeGitea
ctx.Token = giteaToken
}
if githubToken != "" {
log.Debug("token type: github")
ctx.Token = githubToken
}
if ctx.TokenType == "" {
ctx.TokenType = context.TokenTypeGitHub
}
return nil
}
func checkErrors(ctx *context.Context, noTokens, noTokenErrs bool, gitlabTokenErr, githubTokenErr, giteaTokenErr error) error {
if ctx.SkipTokenCheck || ctx.SkipPublish || ctx.Config.Release.Disable {
return nil
}
if noTokens && noTokenErrs {
return ErrMissingToken
}
if gitlabTokenErr != nil {
return fmt.Errorf("failed to load gitlab token: %w", gitlabTokenErr)
}
if githubTokenErr != nil {
return fmt.Errorf("failed to load github token: %w", githubTokenErr)
}
if giteaTokenErr != nil {
return fmt.Errorf("failed to load gitea token: %w", giteaTokenErr)
}
return nil
}
func loadEnv(env, path string) (string, error) {
val := os.Getenv(env)
if val != "" {
return val, nil
}
path, err := homedir.Expand(path)
if err != nil {
return "", err
}
f, err := os.Open(path) // #nosec
if errors.Is(err, fs.ErrNotExist) {
return "", nil
}
if err != nil {
return "", err
}
defer f.Close()
bts, _, err := bufio.NewReader(f).ReadLine()
return string(bts), err
}