ref(releaser/github): uses now the google github libary

This commit is contained in:
Felix Wiedmann
2019-06-05 22:20:42 +02:00
parent 17f715beca
commit 2dd59be362
3 changed files with 67 additions and 113 deletions

3
go.mod
View File

@@ -6,8 +6,9 @@ require (
github.com/Masterminds/semver v1.4.2 github.com/Masterminds/semver v1.4.2
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/google/go-github/v25 v25.1.1
github.com/sirupsen/logrus v1.4.1 github.com/sirupsen/logrus v1.4.1
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/src-d/go-git.v4 v4.11.0 gopkg.in/src-d/go-git.v4 v4.11.0
gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 v2.2.2

View File

@@ -1,29 +1,23 @@
package releaser package releaser
import ( import (
"encoding/json" "context"
"fmt" "fmt"
"github.com/Nightapes/go-semantic-release/pkg/config" "github.com/Nightapes/go-semantic-release/pkg/config"
"io/ioutil" "github.com/google/go-github/v25/github"
"strings" "net/http"
"os"
) )
// GITHUB identifer for github interface // GITHUB identifer for github interface
const GITHUB = "github" const GITHUB = "github"
const githubCreateRleasURL = "https://api.github.com/repos"
const githubUploadAssetURL = "https://uploads.github.com"
// GitHubReleaser type struct // GitHubReleaser type struct
type GitHubReleaser struct { type GitHubReleaser struct {
repositoryURL string config *config.ReleaseConfig
authToken string client *github.Client
assets []config.Asset context context.Context
Version string `json:"tag_name"` release *github.RepositoryRelease
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 { type gitHubCreateReleaseResponse struct {
@@ -33,50 +27,57 @@ type gitHubCreateReleaseResponse struct {
// NewGitHubReleaser initialize a new GitHubRelease // NewGitHubReleaser initialize a new GitHubRelease
func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser {
ctx := context.Background()
httpClient := createHTTPClient(ctx, c.Github.AccessToken)
return &GitHubReleaser{ return &GitHubReleaser{
repositoryURL: c.Github["url"], config: c,
authToken: c.Github["authToken"], client: github.NewClient(httpClient),
assets: c.Assets, context: ctx,
} }
} }
// CreateRelease creates release on remote // CreateRelease creates release on remote
func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage, branch, version string) error { func (g GitHubReleaser) CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error {
g.ReleaseName = releaseName
g.ReleaseMessage = releaseMessage
g.Branch = branch
g.Version = version
repositoryURI := strings.TrimLeft(g.repositoryURL, "/") release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.Github.User, g.config.Github.URL, &github.RepositoryRelease{
jsonRelease, err := json.Marshal(g) TagName: &tag,
TargetCommitish: &targetBranch,
Name: &releaseName,
Body: &releaseMessage,
Draft: &g.config.IsDraft,
Prerelease: &g.config.IsPreRelease,
})
if err != nil { if err != nil {
return fmt.Errorf("releaser: github: could not marshal GitHubReleaser struct. Error: %s", err.Error()) return fmt.Errorf("releaser: github: Could not create release: %v", err)
} }
tempDir, err := ioutil.TempDir(".", "tempZipAssets") if resp.StatusCode >= http.StatusBadRequest {
if err != nil { return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status)
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) g.release = release
if err != nil { return nil
return err
}
releaseInfo := gitHubCreateReleaseResponse{} }
if err := json.Unmarshal(response, &releaseInfo); err != nil {
return err
}
// tbd build new upload url // UploadAssets uploads specified assets
if err := uploadReleaseAssets(releaseInfo.AssetUploadURL, g.authToken, assetList); err != nil { func (g GitHubReleaser) UploadAssets(assets []config.Asset) error {
return err for _, asset := range assets {
} file, err := os.Open(asset.Name)
if err != nil {
return err
}
_, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.Github.User, g.config.Github.URL, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file)
if err != nil {
return err
}
if resp.StatusCode >= http.StatusBadRequest {
return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status)
}
}
return nil return nil
} }

View File

@@ -1,12 +1,12 @@
package releaser package releaser
import ( import (
"archive/zip" "context"
"bytes"
"fmt" "fmt"
"github.com/Nightapes/go-semantic-release/pkg/config" "github.com/Nightapes/go-semantic-release/pkg/config"
"io/ioutil" "golang.org/x/oauth2"
"net/http" "net/http"
"os"
) )
// Releasers struct type // Releasers struct type
@@ -16,7 +16,8 @@ type Releasers struct {
// Releaser interface for providers // Releaser interface for providers
type Releaser interface { type Releaser interface {
CreateRelease(releaseName, releaseMessage string) error CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error
UploadAssets(assets []config.Asset) error
} }
// New initialize a Relerser // New initialize a Relerser
@@ -37,78 +38,29 @@ func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) {
// tbd. http helper function // tbd. http helper function
func makeReleaseRequest(url, authToken string, jsonRelease []byte) ([]byte, error) { func createHTTPClient(ctx context.Context, token string) *http.Client {
request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(jsonRelease)) tokenSource := oauth2.StaticTokenSource(&oauth2.Token{
request.Header.Set("Authorization", authToken) AccessToken: token},
request.Header.Set("content-type", "application/json") )
client := http.Client{} client := oauth2.NewClient(ctx, tokenSource)
defer client.CloseIdleConnections()
response, err := client.Do(request) return client
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 { func checkIfAssetsExists(assets []config.Asset) error {
body := []byte{} var missingAssets []string
request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) for _, asset := range assets {
request.Header.Set("Authorization", authToken)
client := http.Client{}
defer client.CloseIdleConnections()
response, err := client.Do(request)
if err != nil {
return err
if _, err := os.Stat(asset.Name); err != nil {
missingAssets = append(missingAssets, asset.Name)
}
} }
bodyContent, _ := ioutil.ReadAll(response.Body)
if response.StatusCode >= http.StatusMultipleChoices { if len(missingAssets) != 0 {
return fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) return fmt.Errorf("Could not find specified Asset: %+v ", assets)
} }
return nil 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
} }