2017-04-14 20:39:32 +02:00
// Package env implements the Pipe interface providing validation of
// missing environment variables needed by the release process.
2017-01-14 18:06:57 +02:00
package env
import (
2018-02-03 20:51:19 +02:00
"bufio"
2020-09-21 19:47:51 +02:00
"errors"
"fmt"
2017-01-14 18:06:57 +02:00
"os"
2021-12-06 03:25:29 +02:00
"strings"
2017-01-14 18:06:57 +02:00
2020-04-09 15:28:58 +02:00
"github.com/apex/log"
2021-05-25 04:23:59 +02:00
"github.com/goreleaser/goreleaser/internal/tmpl"
2018-08-15 04:50:20 +02:00
"github.com/goreleaser/goreleaser/pkg/context"
2018-02-03 04:06:48 +02:00
homedir "github.com/mitchellh/go-homedir"
2017-01-14 18:06:57 +02:00
)
2020-05-26 05:48:10 +02:00
// ErrMissingToken indicates an error when GITHUB_TOKEN, GITLAB_TOKEN and GITEA_TOKEN are all missing in the environment.
2019-08-26 09:31:38 +02:00
var ErrMissingToken = errors . New ( "missing GITHUB_TOKEN, GITLAB_TOKEN and GITEA_TOKEN" )
2019-06-29 16:02:40 +02:00
2020-05-26 05:48:10 +02:00
// ErrMultipleTokens indicates that multiple tokens are defined. ATM only one of them if allowed.
2019-06-29 16:02:40 +02:00
// See https://github.com/goreleaser/goreleaser/pull/809
2021-12-06 03:25:29 +02:00
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 , ", " ) )
}
2017-01-14 18:06:57 +02:00
2020-05-26 05:48:10 +02:00
// Pipe for env.
2017-01-14 18:06:57 +02:00
type Pipe struct { }
2017-12-02 23:53:19 +02:00
func ( Pipe ) String ( ) string {
return "loading environment variables"
2017-01-14 18:06:57 +02:00
}
2020-03-16 17:10:56 +02:00
func setDefaultTokenFiles ( ctx * context . Context ) {
2021-04-25 19:20:49 +02:00
env := & ctx . Config . EnvFiles
2018-02-03 04:06:48 +02:00
if env . GitHubToken == "" {
env . GitHubToken = "~/.config/goreleaser/github_token"
}
2019-06-29 16:02:40 +02:00
if env . GitLabToken == "" {
env . GitLabToken = "~/.config/goreleaser/gitlab_token"
}
2019-08-26 09:31:38 +02:00
if env . GiteaToken == "" {
env . GiteaToken = "~/.config/goreleaser/gitea_token"
}
2018-02-03 04:06:48 +02:00
}
2020-05-26 05:48:10 +02:00
// Run the pipe.
2018-02-03 04:06:48 +02:00
func ( Pipe ) Run ( ctx * context . Context ) error {
2021-05-25 04:23:59 +02:00
templ := tmpl . New ( ctx ) . WithEnvS ( os . Environ ( ) )
2021-11-12 03:56:03 +02:00
tEnv := [ ] string { }
2021-05-25 04:23:59 +02:00
for i := range ctx . Config . Env {
env , err := templ . Apply ( ctx . Config . Env [ i ] )
if err != nil {
return err
}
2021-11-12 03:56:03 +02:00
tEnv = append ( tEnv , env )
}
for k , v := range context . ToEnv ( tEnv ) {
ctx . Env [ k ] = v
2021-05-25 04:23:59 +02:00
}
2020-03-16 17:10:56 +02:00
setDefaultTokenFiles ( ctx )
2019-06-29 16:02:40 +02:00
githubToken , githubTokenErr := loadEnv ( "GITHUB_TOKEN" , ctx . Config . EnvFiles . GitHubToken )
gitlabToken , gitlabTokenErr := loadEnv ( "GITLAB_TOKEN" , ctx . Config . EnvFiles . GitLabToken )
2019-08-26 09:31:38 +02:00
giteaToken , giteaTokenErr := loadEnv ( "GITEA_TOKEN" , ctx . Config . EnvFiles . GiteaToken )
2019-06-29 16:02:40 +02:00
2021-12-06 03:25:29 +02:00
var tokens [ ] string
2019-08-26 09:31:38 +02:00
if githubToken != "" {
2021-12-06 03:25:29 +02:00
tokens = append ( tokens , "GITHUB_TOKEN" )
2019-08-26 09:31:38 +02:00
}
if gitlabToken != "" {
2021-12-06 03:25:29 +02:00
tokens = append ( tokens , "GITLAB_TOKEN" )
2019-08-26 09:31:38 +02:00
}
if giteaToken != "" {
2021-12-06 03:25:29 +02:00
tokens = append ( tokens , "GITEA_TOKEN" )
2019-08-26 09:31:38 +02:00
}
2021-12-06 03:25:29 +02:00
if len ( tokens ) > 1 {
return ErrMultipleTokens { tokens }
2019-06-29 16:02:40 +02:00
}
2019-08-26 09:31:38 +02:00
noTokens := githubToken == "" && gitlabToken == "" && giteaToken == ""
noTokenErrs := githubTokenErr == nil && gitlabTokenErr == nil && giteaTokenErr == nil
2020-04-09 15:28:58 +02:00
if err := checkErrors ( ctx , noTokens , noTokenErrs , gitlabTokenErr , githubTokenErr , giteaTokenErr ) ; err != nil {
return err
2019-08-26 09:31:38 +02:00
}
2019-06-29 16:02:40 +02:00
if gitlabToken != "" {
2020-04-09 15:28:58 +02:00
log . Debug ( "token type: gitlab" )
2019-06-29 16:02:40 +02:00
ctx . TokenType = context . TokenTypeGitLab
ctx . Token = gitlabToken
}
2019-08-26 09:31:38 +02:00
if giteaToken != "" {
2020-04-09 15:28:58 +02:00
log . Debug ( "token type: gitea" )
2019-08-26 09:31:38 +02:00
ctx . TokenType = context . TokenTypeGitea
ctx . Token = giteaToken
}
2021-09-27 13:13:56 +02:00
if githubToken != "" {
log . Debug ( "token type: github" )
ctx . Token = githubToken
}
if ctx . TokenType == "" {
ctx . TokenType = context . TokenTypeGitHub
}
2019-06-29 16:02:40 +02:00
return nil
2018-02-03 04:06:48 +02:00
}
2020-04-09 15:28:58 +02:00
func checkErrors ( ctx * context . Context , noTokens , noTokenErrs bool , gitlabTokenErr , githubTokenErr , giteaTokenErr error ) error {
2020-05-15 16:19:20 +02:00
if ctx . SkipTokenCheck || ctx . SkipPublish || ctx . Config . Release . Disable {
2020-04-09 15:28:58 +02:00
return nil
}
if noTokens && noTokenErrs {
return ErrMissingToken
}
if gitlabTokenErr != nil {
2020-09-21 19:47:51 +02:00
return fmt . Errorf ( "failed to load gitlab token: %w" , gitlabTokenErr )
2020-04-09 15:28:58 +02:00
}
if githubTokenErr != nil {
2020-09-21 19:47:51 +02:00
return fmt . Errorf ( "failed to load github token: %w" , githubTokenErr )
2020-04-09 15:28:58 +02:00
}
if giteaTokenErr != nil {
2020-09-21 19:47:51 +02:00
return fmt . Errorf ( "failed to load gitea token: %w" , giteaTokenErr )
2020-04-09 15:28:58 +02:00
}
return nil
}
2018-02-03 04:06:48 +02:00
func loadEnv ( env , path string ) ( string , error ) {
val := os . Getenv ( env )
2018-02-03 04:16:30 +02:00
if val != "" {
return val , nil
2018-02-03 04:06:48 +02:00
}
2018-02-03 04:16:30 +02:00
path , err := homedir . Expand ( path )
if err != nil {
return "" , err
}
2018-09-04 14:26:45 +02:00
f , err := os . Open ( path ) // #nosec
2018-02-03 20:47:03 +02:00
if os . IsNotExist ( err ) {
2018-02-03 04:16:30 +02:00
return "" , nil
}
if err != nil {
return "" , err
}
2021-04-25 16:41:36 +02:00
defer f . Close ( )
2018-02-03 20:51:19 +02:00
bts , _ , err := bufio . NewReader ( f ) . ReadLine ( )
return string ( bts ) , err
2017-01-14 18:06:57 +02:00
}