2019-06-15 23:03:27 +02:00
|
|
|
package util
|
|
|
|
|
|
|
|
|
|
import (
|
2019-07-07 23:42:52 +02:00
|
|
|
"archive/zip"
|
2019-06-15 23:03:27 +02:00
|
|
|
"context"
|
2019-08-07 23:24:13 +02:00
|
|
|
"encoding/json"
|
2019-06-17 22:30:17 +02:00
|
|
|
"fmt"
|
2019-07-07 23:42:52 +02:00
|
|
|
"io"
|
2019-06-15 23:03:27 +02:00
|
|
|
"net/http"
|
2019-08-07 23:24:13 +02:00
|
|
|
"net/url"
|
2019-06-17 22:30:17 +02:00
|
|
|
"os"
|
|
|
|
|
"strings"
|
2019-06-15 23:03:27 +02:00
|
|
|
|
2019-07-09 01:45:16 +02:00
|
|
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
2019-06-17 22:45:49 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
2019-06-15 23:03:27 +02:00
|
|
|
"golang.org/x/oauth2"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
//CreateBearerHTTPClient with given token
|
|
|
|
|
func CreateBearerHTTPClient(ctx context.Context, token string) *http.Client {
|
|
|
|
|
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{
|
|
|
|
|
AccessToken: token},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
client := oauth2.NewClient(ctx, tokenSource)
|
|
|
|
|
|
|
|
|
|
return client
|
|
|
|
|
}
|
2019-06-17 22:30:17 +02:00
|
|
|
|
2019-08-07 23:24:13 +02:00
|
|
|
// AddHeaderTransport struct
|
|
|
|
|
type AddHeaderTransport struct {
|
|
|
|
|
T http.RoundTripper
|
|
|
|
|
key string
|
|
|
|
|
value string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RoundTrip add header
|
|
|
|
|
func (adt *AddHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
|
|
|
req.Header.Add(adt.key, adt.value)
|
|
|
|
|
return adt.T.RoundTrip(req)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//NewAddHeaderTransport to add default header
|
|
|
|
|
func NewAddHeaderTransport(T http.RoundTripper, key, value string) *AddHeaderTransport {
|
|
|
|
|
if T == nil {
|
|
|
|
|
T = http.DefaultTransport
|
|
|
|
|
}
|
|
|
|
|
return &AddHeaderTransport{T, key, value}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 22:30:17 +02:00
|
|
|
// GetAccessToken lookup for the providers accesstoken
|
|
|
|
|
func GetAccessToken(providerName string) (string, error) {
|
|
|
|
|
var token string
|
|
|
|
|
var exists bool
|
|
|
|
|
envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(providerName))
|
|
|
|
|
|
2019-06-17 22:45:49 +02:00
|
|
|
log.Debugf("check if %s environment variable is set", envName)
|
|
|
|
|
|
2019-06-17 22:30:17 +02:00
|
|
|
if token, exists = os.LookupEnv(envName); !exists {
|
2019-06-18 21:35:51 +02:00
|
|
|
return "", fmt.Errorf("could not find %s in the enviroment variables. Please check if it is set", envName)
|
2019-07-22 00:48:13 +02:00
|
|
|
} else if token == "" {
|
|
|
|
|
return "", fmt.Errorf("token %s is set in environment variables but is empty", envName)
|
2019-06-17 22:30:17 +02:00
|
|
|
}
|
|
|
|
|
return token, nil
|
|
|
|
|
}
|
2019-07-07 23:42:52 +02:00
|
|
|
|
2019-07-09 01:45:16 +02:00
|
|
|
// PrepareAssets prepare all files before uploading
|
|
|
|
|
func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) {
|
|
|
|
|
filesToUpload := []*string{}
|
|
|
|
|
for _, asset := range assets {
|
2019-07-22 18:11:48 +02:00
|
|
|
if asset.Name == "" {
|
2019-07-22 20:46:48 +02:00
|
|
|
return nil, fmt.Errorf("asset name declaration is empty, please check your configuration file")
|
2019-07-22 18:11:48 +02:00
|
|
|
} else if asset.Compress {
|
2019-07-09 01:45:16 +02:00
|
|
|
log.Debugf("Asset %s will now be compressed", asset.Name)
|
|
|
|
|
log.Debugf("Repo url %s", repository)
|
|
|
|
|
zipNameWithPath, err := zipFile(repository, asset.Name)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return filesToUpload, err
|
|
|
|
|
}
|
|
|
|
|
filesToUpload = append(filesToUpload, &zipNameWithPath)
|
|
|
|
|
} else {
|
|
|
|
|
tmpFileName := fmt.Sprintf("%s/%s", repository, asset.Name)
|
|
|
|
|
filesToUpload = append(filesToUpload, &tmpFileName)
|
|
|
|
|
}
|
|
|
|
|
log.Debugf("Add asset %s to files to upload", asset.Name)
|
|
|
|
|
}
|
|
|
|
|
return filesToUpload, nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 23:42:52 +02:00
|
|
|
// ZipFile compress given file in zip format
|
2019-07-09 01:45:16 +02:00
|
|
|
func zipFile(repository string, file string) (string, error) {
|
2019-07-07 23:42:52 +02:00
|
|
|
|
2019-07-22 18:11:48 +02:00
|
|
|
fileToZip, err := os.Open(repository + "/" + file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
defer fileToZip.Close()
|
|
|
|
|
|
2019-07-09 01:45:16 +02:00
|
|
|
zipFileName := fmt.Sprintf("%s/%s.zip", strings.TrimSuffix(repository, "/"), file)
|
2019-07-07 23:42:52 +02:00
|
|
|
zipFile, err := os.Create(zipFileName)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
2019-07-09 01:45:16 +02:00
|
|
|
log.Debugf("Created zipfile %s", zipFile.Name())
|
2019-07-07 23:42:52 +02:00
|
|
|
|
|
|
|
|
defer zipFile.Close()
|
|
|
|
|
|
|
|
|
|
fileToZipInfo, err := fileToZip.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipWriter := zip.NewWriter(zipFile)
|
2019-07-09 01:45:16 +02:00
|
|
|
defer zipWriter.Close()
|
2019-07-07 23:42:52 +02:00
|
|
|
|
|
|
|
|
fileToZipHeader, err := zip.FileInfoHeader(fileToZipInfo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileToZipHeader.Name = fileToZipInfo.Name()
|
|
|
|
|
|
|
|
|
|
fileToZipWriter, err := zipWriter.CreateHeader(fileToZipHeader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err = io.Copy(fileToZipWriter, fileToZip); err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return zipFileName, nil
|
|
|
|
|
}
|
2019-08-07 23:24:13 +02:00
|
|
|
|
|
|
|
|
// CheckURL if is valid
|
|
|
|
|
func CheckURL(urlStr string) (string, error) {
|
|
|
|
|
|
|
|
|
|
if !strings.HasSuffix(urlStr, "/") {
|
|
|
|
|
urlStr += "/"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err := url.Parse(urlStr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return urlStr, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//PathEscape to be url save
|
|
|
|
|
func PathEscape(s string) string {
|
|
|
|
|
return strings.Replace(url.PathEscape(s), ".", "%2E", -1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do request for client
|
|
|
|
|
func Do(client *http.Client, req *http.Request, v interface{}) (*http.Response, error) {
|
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
switch resp.StatusCode {
|
|
|
|
|
case 200, 201, 202, 204, 304:
|
|
|
|
|
if v != nil {
|
|
|
|
|
if w, ok := v.(io.Writer); ok {
|
|
|
|
|
_, err = io.Copy(w, resp.Body)
|
|
|
|
|
} else {
|
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func IsValidResult(resp *http.Response) error {
|
|
|
|
|
switch resp.StatusCode {
|
|
|
|
|
case 200, 201, 202, 204, 304:
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("%s %s: %d", resp.Request.Method, resp.Request.URL, resp.StatusCode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ShouldRetry(resp *http.Response) bool {
|
2019-08-08 21:30:29 +02:00
|
|
|
return resp.StatusCode == http.StatusTooManyRequests
|
2019-08-07 23:24:13 +02:00
|
|
|
}
|