From 17f715becad91edf6f58a10dfc8bad44d9b6173a Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 28 May 2019 22:12:45 +0200 Subject: [PATCH] tmp(releaser): add helper methods for releasers --- internal/releaser/github.go | 82 +++++++++++++++++++++++++ internal/releaser/releaser.go | 86 +++++++++++++++++++++++++-- internal/releaser/releasers/github.go | 36 ----------- 3 files changed, 164 insertions(+), 40 deletions(-) create mode 100644 internal/releaser/github.go delete mode 100644 internal/releaser/releasers/github.go diff --git a/internal/releaser/github.go b/internal/releaser/github.go new file mode 100644 index 0000000..e46cd47 --- /dev/null +++ b/internal/releaser/github.go @@ -0,0 +1,82 @@ +package releaser + +import ( + "encoding/json" + "fmt" + "github.com/Nightapes/go-semantic-release/pkg/config" + "io/ioutil" + "strings" +) + +// GITHUB identifer for github interface +const GITHUB = "github" +const githubCreateRleasURL = "https://api.github.com/repos" +const githubUploadAssetURL = "https://uploads.github.com" + +// GitHubReleaser type struct +type GitHubReleaser struct { + repositoryURL string + authToken string + assets []config.Asset + Version string `json:"tag_name"` + Branch string `json:"target_commitish"` + ReleaseName string `json:"name"` + ReleaseMessage string `json:"body"` + Draft bool `json:"draft,omitempty"` + Prerelease bool `json:"prerelease,omitempty"` +} + +type gitHubCreateReleaseResponse struct { + ReleaseURL string `json:url` + AssetUploadURL string `json:upload_url` +} + +// NewGitHubReleaser initialize a new GitHubRelease +func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { + return &GitHubReleaser{ + repositoryURL: c.Github["url"], + authToken: c.Github["authToken"], + assets: c.Assets, + } +} + +// CreateRelease creates release on remote +func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage, branch, version string) error { + g.ReleaseName = releaseName + g.ReleaseMessage = releaseMessage + g.Branch = branch + g.Version = version + + repositoryURI := strings.TrimLeft(g.repositoryURL, "/") + jsonRelease, err := json.Marshal(g) + + if err != nil { + return fmt.Errorf("releaser: github: could not marshal GitHubReleaser struct. Error: %s", err.Error()) + } + + tempDir, err := ioutil.TempDir(".", "tempZipAssets") + if err != nil { + return fmt.Errorf("releaser: github: Could not create a temp directory. Error: %s", err.Error()) + } + assetList, err := prepareAssets(tempDir, g.assets) + if err != nil { + return err + } + + response, err := makeReleaseRequest(githubCreateRleasURL+repositoryURI, g.authToken, jsonRelease) + if err != nil { + return err + } + + releaseInfo := gitHubCreateReleaseResponse{} + if err := json.Unmarshal(response, &releaseInfo); err != nil { + return err + } + + // tbd build new upload url + if err := uploadReleaseAssets(releaseInfo.AssetUploadURL, g.authToken, assetList); err != nil { + return err + } + + return nil +} diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 6402c6e..adec996 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -1,10 +1,12 @@ package releaser import ( + "archive/zip" + "bytes" "fmt" - "github.com/Nightapes/go-semantic-release/internal/cache" - "github.com/Nightapes/go-semantic-release/internal/releaser/releasers" "github.com/Nightapes/go-semantic-release/pkg/config" + "io/ioutil" + "net/http" ) // Releasers struct type @@ -27,10 +29,86 @@ func New(c *config.ReleaseConfig) *Releasers { //GetReleaser returns an initialized releaser func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) { switch releaserType { - case releasers.GITHUB: - return releasers.NewGitHubReleaser(r.config), nil + case GITHUB: + return NewGitHubReleaser(r.config), nil } return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", releaserType) } // tbd. http helper function + +func makeReleaseRequest(url, authToken string, jsonRelease []byte) ([]byte, error) { + request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(jsonRelease)) + request.Header.Set("Authorization", authToken) + request.Header.Set("content-type", "application/json") + + client := http.Client{} + defer client.CloseIdleConnections() + + response, err := client.Do(request) + + if err != nil { + return []byte{}, err + + } + bodyContent, _ := ioutil.ReadAll(response.Body) + + if response.StatusCode >= http.StatusMultipleChoices { + return []byte{}, fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) + } + + return bodyContent, nil +} + +func uploadReleaseAssets(url, authToken string, assets []string) error { + body := []byte{} + request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) + + request.Header.Set("Authorization", authToken) + client := http.Client{} + defer client.CloseIdleConnections() + + response, err := client.Do(request) + + if err != nil { + return err + + } + bodyContent, _ := ioutil.ReadAll(response.Body) + + if response.StatusCode >= http.StatusMultipleChoices { + return fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) + } + + return nil +} + +func prepareAssets(tempDir string, asset []config.Asset) ([]string, error) { + buf := new(bytes.Buffer) + tempAssets := []string{} + for _, asset := range asset { + if asset.Compress { + fileContent, err := ioutil.ReadFile(asset.Name) + if err != nil { + return []string{}, err + } + + w := zip.NewWriter(buf) + zip, err := w.Create(tempDir + asset.Name) + + if err != nil { + return []string{}, err + } + + _, err = zip.Write(fileContent) + if err != nil { + return []string{}, err + } + tempAssets = append(tempAssets, tempDir+asset.Name) + + } else { + tempAssets = append(tempAssets, asset.Name) + } + } + return tempAssets, nil +} diff --git a/internal/releaser/releasers/github.go b/internal/releaser/releasers/github.go deleted file mode 100644 index 3b65c53..0000000 --- a/internal/releaser/releasers/github.go +++ /dev/null @@ -1,36 +0,0 @@ -package releasers - -import ( - "github.com/Nightapes/go-semantic-release/pkg/config" -) - -// GITHUB identifer for github interface -const GITHUB = "github" - -// GitHubReleaser type struct -type GitHubReleaser struct { - RepositoryURL string - TagName string `json:"tag_name"` - TargetCommitish string `json:"target_commitish"` - ReleaseName string `json:"name"` - ReleaseMessage string `json:"body"` - Draft bool `json:"draft,omitempty"` - Prerelease bool `json:"prerelease,omitempty"` - // Assets -} - -// CreateRelease creates release on remote -func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage string) error { - g.ReleaseName = releaseName - g.ReleaseMessage = releaseMessage - return nil -} - -// NewGitHubReleaser initialize a new GitHubRelease -func NewGitHubReleaser(c *config.ReleaseConfig, branch, latestVersion string) *GitHubReleaser { - return &GitHubReleaser{ - RepositoryURL: c.Github["url"], - TargetCommitish: branch, - TagName: latestVersion, - } -}