github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/apps/distgo/cmd/publish/bintray_publish.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package publish 16 17 import ( 18 "fmt" 19 "io" 20 "io/ioutil" 21 "net/http" 22 "net/url" 23 "path" 24 "strings" 25 26 "github.com/pkg/errors" 27 28 "github.com/palantir/godel/apps/distgo/params" 29 ) 30 31 type BintrayConnectionInfo struct { 32 BasicConnectionInfo 33 Subject string 34 Repository string 35 Release bool 36 DownloadsList bool 37 } 38 39 func (b BintrayConnectionInfo) Publish(buildSpec params.ProductBuildSpec, paths ProductPaths, stdout io.Writer) (string, error) { 40 baseURL := strings.Join([]string{b.URL, "content", b.Subject, b.Repository, buildSpec.ProductName, buildSpec.ProductVersion, paths.productPath}, "/") 41 artifactURL, err := b.uploadArtifacts(baseURL, paths, nil, stdout) 42 if err != nil { 43 return artifactURL, err 44 } 45 if b.Release { 46 if err := b.release(buildSpec, stdout); err != nil { 47 fmt.Fprintln(stdout, "Uploading artifacts succeeded, but publish of uploaded artifacts failed:", err) 48 } 49 } 50 if b.DownloadsList { 51 if err := b.addToDownloadsList(buildSpec, paths, stdout); err != nil { 52 fmt.Fprintln(stdout, "Uploading artifacts succeeded, but addings artifact to downloads list failed:", err) 53 } 54 } 55 return artifactURL, err 56 } 57 58 func (b BintrayConnectionInfo) release(buildSpec params.ProductBuildSpec, stdout io.Writer) (rErr error) { 59 publishURLString := strings.Join([]string{b.URL, "content", b.Subject, b.Repository, buildSpec.ProductName, buildSpec.ProductVersion, "publish"}, "/") 60 return b.runBintrayCommand(publishURLString, http.MethodPost, `{"publish_wait_for_secs":-1}`, "running Bintray publish for uploaded artifacts", stdout) 61 } 62 63 func (b BintrayConnectionInfo) addToDownloadsList(buildSpec params.ProductBuildSpec, paths ProductPaths, stdout io.Writer) (rErr error) { 64 downloadsListURLString := strings.Join([]string{b.URL, "file_metadata", b.Subject, b.Repository, paths.productPath, path.Base(paths.artifactPath)}, "/") 65 return b.runBintrayCommand(downloadsListURLString, http.MethodPut, `{"list_in_downloads":true}`, "adding artifact to Bintray downloads list for package", stdout) 66 } 67 68 func (b BintrayConnectionInfo) runBintrayCommand(urlString, httpMethod, jsonContent, cmdMsg string, stdout io.Writer) (rErr error) { 69 url, err := url.Parse(urlString) 70 if err != nil { 71 return errors.Wrapf(err, "failed to parse %v as URL", urlString) 72 } 73 74 capitalizedMsg := cmdMsg 75 if len(cmdMsg) > 0 { 76 capitalizedMsg = strings.ToUpper(string(cmdMsg[0])) + cmdMsg[1:] 77 } 78 79 fmt.Fprintf(stdout, "%s...", capitalizedMsg) 80 defer func() { 81 fmt.Fprintln(stdout) 82 }() 83 84 reader := strings.NewReader(jsonContent) 85 86 header := http.Header{} 87 header.Set("Content-Type", "application/json") 88 req := http.Request{ 89 Method: httpMethod, 90 URL: url, 91 Header: header, 92 Body: ioutil.NopCloser(reader), 93 ContentLength: int64(len([]byte(jsonContent))), 94 } 95 req.SetBasicAuth(b.Username, b.Password) 96 97 resp, err := http.DefaultClient.Do(&req) 98 if err != nil { 99 return errors.Wrapf(err, "%s", cmdMsg) 100 } 101 defer func() { 102 if err := resp.Body.Close(); err != nil && rErr == nil { 103 rErr = errors.Wrapf(err, "failed to close response body for URL %s", urlString) 104 } 105 }() 106 107 if resp.StatusCode >= http.StatusBadRequest { 108 return errors.Errorf("%s resulted in response: %v", cmdMsg, resp.Status) 109 } 110 111 fmt.Fprint(stdout, "done") 112 113 return nil 114 }