First draft of check and out
This commit is contained in:
@@ -2,69 +2,65 @@ package resource
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
|
||||
"github.com/cppforlife/go-semi-semantic/version"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type CheckCommand struct {
|
||||
github GitHub
|
||||
gitlab GitLab
|
||||
}
|
||||
|
||||
func NewCheckCommand(github GitHub) *CheckCommand {
|
||||
func NewCheckCommand(gitlab GitLab) *CheckCommand {
|
||||
return &CheckCommand{
|
||||
github: github,
|
||||
gitlab: gitlab,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CheckCommand) Run(request CheckRequest) ([]Version, error) {
|
||||
releases, err := c.github.ListReleases()
|
||||
var tags []*gitlab.Tag
|
||||
var err error
|
||||
if (request.Version == Version{}) {
|
||||
tags, err = c.gitlab.ListTags()
|
||||
} else {
|
||||
tags, err = c.gitlab.ListTagsUntil(request.Version.Tag)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return []Version{}, err
|
||||
}
|
||||
|
||||
if len(releases) == 0 {
|
||||
if len(tags) == 0 {
|
||||
return []Version{}, nil
|
||||
}
|
||||
|
||||
var filteredReleases []*github.RepositoryRelease
|
||||
var filteredTags []*gitlab.Tag
|
||||
|
||||
// TODO: make ListTagsUntil work better with this
|
||||
versionParser, err := newVersionParser(request.Source.TagFilter)
|
||||
if err != nil {
|
||||
return []Version{}, err
|
||||
}
|
||||
|
||||
for _, release := range releases {
|
||||
if request.Source.Drafts != *release.Draft {
|
||||
for _, tag := range tags {
|
||||
if _, err := version.NewVersionFromString(versionParser.parse(tag.Name)); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Should we skip this release
|
||||
// a- prerelease condition dont match our source config
|
||||
// b- release condition match prerealse in github since github has true/false to describe release/prerelase
|
||||
if request.Source.PreRelease != *release.Prerelease && request.Source.Release == *release.Prerelease {
|
||||
if tag.Release == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if release.TagName == nil {
|
||||
continue
|
||||
}
|
||||
if _, err := version.NewVersionFromString(versionParser.parse(*release.TagName)); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
filteredReleases = append(filteredReleases, release)
|
||||
filteredTags = append(filteredTags, tag)
|
||||
}
|
||||
|
||||
sort.Slice(filteredReleases, func(i, j int) bool {
|
||||
first, err := version.NewVersionFromString(versionParser.parse(*filteredReleases[i].TagName))
|
||||
sort.Slice(filteredTags, func(i, j int) bool {
|
||||
first, err := version.NewVersionFromString(versionParser.parse(filteredTags[i].Name))
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
second, err := version.NewVersionFromString(versionParser.parse(*filteredReleases[j].TagName))
|
||||
second, err := version.NewVersionFromString(versionParser.parse(filteredTags[j].Name))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -72,37 +68,32 @@ func (c *CheckCommand) Run(request CheckRequest) ([]Version, error) {
|
||||
return first.IsLt(second)
|
||||
})
|
||||
|
||||
if len(filteredReleases) == 0 {
|
||||
if len(filteredTags) == 0 {
|
||||
return []Version{}, nil
|
||||
}
|
||||
latestRelease := filteredReleases[len(filteredReleases)-1]
|
||||
latestTag := filteredTags[len(filteredTags)-1]
|
||||
|
||||
if (request.Version == Version{}) {
|
||||
return []Version{
|
||||
versionFromRelease(latestRelease),
|
||||
Version{Tag: latestTag.Name},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if *latestRelease.TagName == request.Version.Tag {
|
||||
if latestTag.Name == request.Version.Tag {
|
||||
return []Version{}, nil
|
||||
}
|
||||
|
||||
upToLatest := false
|
||||
reversedVersions := []Version{}
|
||||
|
||||
for _, release := range filteredReleases {
|
||||
for _, release := range filteredTags {
|
||||
if !upToLatest {
|
||||
if *release.Draft || *release.Prerelease {
|
||||
id := *release.ID
|
||||
upToLatest = request.Version.ID == strconv.Itoa(id)
|
||||
} else {
|
||||
version := *release.TagName
|
||||
upToLatest = request.Version.Tag == version
|
||||
}
|
||||
version := release.Name
|
||||
upToLatest = request.Version.Tag == version
|
||||
}
|
||||
|
||||
if upToLatest {
|
||||
reversedVersions = append(reversedVersions, versionFromRelease(release))
|
||||
reversedVersions = append(reversedVersions, Version{Tag: release.Name})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +101,7 @@ func (c *CheckCommand) Run(request CheckRequest) ([]Version, error) {
|
||||
// current version was removed; start over from latest
|
||||
reversedVersions = append(
|
||||
reversedVersions,
|
||||
versionFromRelease(filteredReleases[len(filteredReleases)-1]),
|
||||
Version{Tag: filteredTags[len(filteredTags)-1].Name},
|
||||
)
|
||||
}
|
||||
|
||||
|
336
gitlab.go
336
gitlab.go
@@ -3,10 +3,8 @@ package resource
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -15,29 +13,21 @@ import (
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter . GitHub
|
||||
//go:generate counterfeiter . GitLab
|
||||
|
||||
type gitlab interface {
|
||||
ListReleases() ([]*gitlab.RepositoryRelease, error)
|
||||
GetReleaseByTag(tag string) (*gitlab.RepositoryRelease, error)
|
||||
GetRelease(id int) (*gitlab.RepositoryRelease, error)
|
||||
CreateRelease(release gitlab.RepositoryRelease) (*gitlab.RepositoryRelease, error)
|
||||
UpdateRelease(release gitlab.RepositoryRelease) (*gitlab.RepositoryRelease, error)
|
||||
|
||||
ListReleaseAssets(release gitlab.RepositoryRelease) ([]*gitlab.ReleaseAsset, error)
|
||||
UploadReleaseAsset(release gitlab.RepositoryRelease, name string, file *os.File) error
|
||||
DeleteReleaseAsset(asset gitlab.ReleaseAsset) error
|
||||
DownloadReleaseAsset(asset gitlab.ReleaseAsset) (io.ReadCloser, error)
|
||||
|
||||
GetTarballLink(tag string) (*url.URL, error)
|
||||
GetZipballLink(tag string) (*url.URL, error)
|
||||
GetRef(tag string) (*gitlab.Reference, error)
|
||||
type GitLab interface {
|
||||
ListTags() ([]*gitlab.Tag, error)
|
||||
ListTagsUntil(tag_name string) ([]*gitlab.Tag, error)
|
||||
GetTag(tag_name string) (*gitlab.Tag, error)
|
||||
CreateTag(tag_name string, ref string) (*gitlab.Tag, error)
|
||||
CreateRelease(tag_name string, description string) (*gitlab.Release, error)
|
||||
UpdateRelease(description string) (*gitlab.Release, error)
|
||||
UploadProjectFile(file string) (*gitlab.ProjectFile, error)
|
||||
}
|
||||
|
||||
type gitlabClient struct {
|
||||
client *gitlab.Client
|
||||
|
||||
owner string
|
||||
repository string
|
||||
}
|
||||
|
||||
@@ -52,221 +42,175 @@ func NewGitlabClient(source Source) (*gitlabClient, error) {
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
}
|
||||
|
||||
if source.AccessToken != "" {
|
||||
client := gitlab.NewClient(httpClient, source.AccessToken)
|
||||
|
||||
if source.GitlabAPIURL != "" {
|
||||
var err error
|
||||
httpClient, err = oauthClient(ctx, source)
|
||||
baseUrl, err := url.Parse(source.GitlabAPIURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
client := gitlab.NewClient(httpClient)
|
||||
|
||||
if source.gitlabAPIURL != "" {
|
||||
var err error
|
||||
client.BaseURL, err = url.Parse(source.gitlabAPIURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.UploadURL, err = url.Parse(source.gitlabAPIURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if source.gitlabUploadsURL != "" {
|
||||
var err error
|
||||
client.UploadURL, err = url.Parse(source.gitlabUploadsURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
owner := source.Owner
|
||||
if source.User != "" {
|
||||
owner = source.User
|
||||
client.SetBaseURL(baseUrl.String())
|
||||
}
|
||||
|
||||
return &gitlabClient{
|
||||
client: client,
|
||||
owner: owner,
|
||||
repository: source.Repository,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) ListReleases() ([]*gitlab.RepositoryRelease, error) {
|
||||
releases, res, err := g.client.Repositories.ListReleases(context.TODO(), g.owner, g.repository, nil)
|
||||
if err != nil {
|
||||
return []*gitlab.RepositoryRelease{}, err
|
||||
}
|
||||
func (g *gitlabClient) ListTags() ([]*gitlab.Tag, error) {
|
||||
var allTags []*gitlab.Tag
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetReleaseByTag(tag string) (*gitlab.RepositoryRelease, error) {
|
||||
release, res, err := g.client.Repositories.GetReleaseByTag(context.TODO(), g.owner, g.repository, tag)
|
||||
if err != nil {
|
||||
return &gitlab.RepositoryRelease{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetRelease(id int) (*gitlab.RepositoryRelease, error) {
|
||||
release, res, err := g.client.Repositories.GetRelease(context.TODO(), g.owner, g.repository, id)
|
||||
if err != nil {
|
||||
return &gitlab.RepositoryRelease{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) CreateRelease(release gitlab.RepositoryRelease) (*gitlab.RepositoryRelease, error) {
|
||||
createdRelease, res, err := g.client.Repositories.CreateRelease(context.TODO(), g.owner, g.repository, &release)
|
||||
if err != nil {
|
||||
return &gitlab.RepositoryRelease{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createdRelease, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) UpdateRelease(release gitlab.RepositoryRelease) (*gitlab.RepositoryRelease, error) {
|
||||
if release.ID == nil {
|
||||
return nil, errors.New("release did not have an ID: has it been saved yet?")
|
||||
}
|
||||
|
||||
updatedRelease, res, err := g.client.Repositories.EditRelease(context.TODO(), g.owner, g.repository, *release.ID, &release)
|
||||
if err != nil {
|
||||
return &gitlab.RepositoryRelease{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updatedRelease, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) ListReleaseAssets(release gitlab.RepositoryRelease) ([]*gitlab.ReleaseAsset, error) {
|
||||
assets, res, err := g.client.Repositories.ListReleaseAssets(context.TODO(), g.owner, g.repository, *release.ID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return assets, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) UploadReleaseAsset(release gitlab.RepositoryRelease, name string, file *os.File) error {
|
||||
_, res, err := g.client.Repositories.UploadReleaseAsset(
|
||||
context.TODO(),
|
||||
g.owner,
|
||||
g.repository,
|
||||
*release.ID,
|
||||
&gitlab.UploadOptions{
|
||||
Name: name,
|
||||
opt := &gitlab.ListTagsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
PerPage: 100,
|
||||
Page: 1,
|
||||
},
|
||||
file,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
OrderBy: gitlab.String("updated"),
|
||||
Sort: gitlab.String("desc"),
|
||||
}
|
||||
|
||||
return res.Body.Close()
|
||||
}
|
||||
|
||||
func (g *gitlabClient) DeleteReleaseAsset(asset gitlab.ReleaseAsset) error {
|
||||
res, err := g.client.Repositories.DeleteReleaseAsset(context.TODO(), g.owner, g.repository, *asset.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return res.Body.Close()
|
||||
}
|
||||
|
||||
func (g *gitlabClient) DownloadReleaseAsset(asset gitlab.ReleaseAsset) (io.ReadCloser, error) {
|
||||
res, redir, err := g.client.Repositories.DownloadReleaseAsset(context.TODO(), g.owner, g.repository, *asset.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if redir != "" {
|
||||
resp, err := http.Get(redir)
|
||||
for {
|
||||
tags, res, err := g.client.Tags.ListTags(g.repository, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return []*gitlab.Tag{}, err
|
||||
}
|
||||
|
||||
return resp.Body, nil
|
||||
if opt.Page >= res.TotalPages {
|
||||
break
|
||||
}
|
||||
|
||||
opt.Page = res.NextPage
|
||||
|
||||
allTags = append(allTags, tags...)
|
||||
}
|
||||
|
||||
return res, err
|
||||
return allTags, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetTarballLink(tag string) (*url.URL, error) {
|
||||
opt := &gitlab.RepositoryContentGetOptions{Ref: tag}
|
||||
u, res, err := g.client.Repositories.GetArchiveLink(context.TODO(), g.owner, g.repository, gitlab.Tarball, opt)
|
||||
func (g *gitlabClient) ListTagsUntil(tag_name string) ([]*gitlab.Tag, error) {
|
||||
var allTags []*gitlab.Tag
|
||||
|
||||
opt := &gitlab.ListTagsOptions{
|
||||
ListOptions: gitlab.ListOptions{
|
||||
PerPage: 100,
|
||||
Page: 1,
|
||||
},
|
||||
OrderBy: gitlab.String("updated"),
|
||||
Sort: gitlab.String("desc"),
|
||||
}
|
||||
|
||||
for {
|
||||
tags, res, err := g.client.Tags.ListTags(g.repository, opt)
|
||||
if err != nil {
|
||||
return []*gitlab.Tag{}, err
|
||||
}
|
||||
|
||||
if opt.Page >= res.TotalPages {
|
||||
break
|
||||
}
|
||||
|
||||
for i, tag := range tags {
|
||||
if tag.Name == tag_name {
|
||||
allTags = append(allTags, tags[:i]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
opt.Page = res.NextPage
|
||||
allTags = append(allTags, tags...)
|
||||
}
|
||||
|
||||
return allTags, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetTag(tag_name string) (*gitlab.Tag, error) {
|
||||
tag, res, err := g.client.Tags.GetTag(g.repository, tag_name)
|
||||
if err != nil {
|
||||
return &gitlab.Tag{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Body.Close()
|
||||
return u, nil
|
||||
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetZipballLink(tag string) (*url.URL, error) {
|
||||
opt := &gitlab.RepositoryContentGetOptions{Ref: tag}
|
||||
u, res, err := g.client.Repositories.GetArchiveLink(context.TODO(), g.owner, g.repository, gitlab.Zipball, opt)
|
||||
func (g *gitlabClient) CreateTag(ref string, tag_name string) (*gitlab.Tag, error) {
|
||||
opt := &gitlab.CreateTagOptions{
|
||||
TagName: gitlab.String(tag_name),
|
||||
Ref: gitlab.String(ref),
|
||||
Message: gitlab.String(tag_name),
|
||||
}
|
||||
|
||||
tag, res, err := g.client.Tags.CreateTag(g.repository, opt)
|
||||
if err != nil {
|
||||
return &gitlab.Tag{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Body.Close()
|
||||
return u, nil
|
||||
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) GetRef(tag string) (*gitlab.Reference, error) {
|
||||
ref, res, err := g.client.Git.GetRef(context.TODO(), g.owner, g.repository, "tags/"+tag)
|
||||
func (g *gitlabClient) CreateRelease(tag_name string, description string) (*gitlab.Release, error) {
|
||||
opt := &gitlab.CreateReleaseOptions{
|
||||
Description: gitlab.String(description),
|
||||
}
|
||||
|
||||
release, res, err := g.client.Tags.CreateRelease(g.repository, tag_name, opt)
|
||||
if err != nil {
|
||||
return &gitlab.Release{}, err
|
||||
}
|
||||
|
||||
// https://docs.gitlab.com/ce/api/tags.html#create-a-new-release
|
||||
// returns 409 if release already exists
|
||||
if res.StatusCode == http.StatusConflict {
|
||||
return nil, errors.New("release already exists")
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Body.Close()
|
||||
return ref, nil
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func oauthClient(ctx context.Context, source Source) (*http.Client, error) {
|
||||
ts := oauth2.StaticTokenSource(&oauth2.Token{
|
||||
AccessToken: source.AccessToken,
|
||||
})
|
||||
|
||||
oauthClient := oauth2.NewClient(ctx, ts)
|
||||
|
||||
gitlabHTTPClient := &http.Client{
|
||||
Transport: oauthClient.Transport,
|
||||
func (g *gitlabClient) UpdateRelease(tag_name string, description string) (*gitlab.Release, error) {
|
||||
opt := &gitlab.UpdateReleaseOptions{
|
||||
Description: gitlab.String(description),
|
||||
}
|
||||
|
||||
return gitlabHTTPClient, nil
|
||||
release, res, err := g.client.Tags.UpdateRelease(g.repository, tag_name, opt)
|
||||
if err != nil {
|
||||
return &gitlab.Release{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func (g *gitlabClient) UploadProjectFile(file string) (*gitlab.ProjectFile, error) {
|
||||
projectFile, res, err := g.client.Projects.UploadFile(g.repository, file)
|
||||
if err != nil {
|
||||
return &gitlab.ProjectFile{}, err
|
||||
}
|
||||
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projectFile, nil
|
||||
}
|
||||
|
9
go.mod
9
go.mod
@@ -1 +1,10 @@
|
||||
module github.com/edtan/gitlab-release-resource
|
||||
|
||||
require (
|
||||
github.com/concourse/github-release-resource v1.0.0
|
||||
github.com/cppforlife/go-semi-semantic v0.0.0-20160921010311-576b6af77ae4
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286
|
||||
github.com/xanzy/go-gitlab v0.12.0
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
|
||||
)
|
||||
|
151
out_command.go
151
out_command.go
@@ -4,21 +4,20 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type OutCommand struct {
|
||||
github GitHub
|
||||
gitlab GitLab
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func NewOutCommand(github GitHub, writer io.Writer) *OutCommand {
|
||||
func NewOutCommand(gitlab GitLab, writer io.Writer) *OutCommand {
|
||||
return &OutCommand{
|
||||
github: github,
|
||||
gitlab: gitlab,
|
||||
writer: writer,
|
||||
}
|
||||
}
|
||||
@@ -38,6 +37,11 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
|
||||
|
||||
tag = request.Params.TagPrefix + tag
|
||||
|
||||
targetCommitish, err = c.fileContents(filepath.Join(sourceDir, request.Params.CommitishPath))
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
|
||||
var body string
|
||||
bodySpecified := false
|
||||
if request.Params.BodyPath != "" {
|
||||
@@ -49,82 +53,39 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
|
||||
}
|
||||
}
|
||||
|
||||
targetCommitish := ""
|
||||
if request.Params.CommitishPath != "" {
|
||||
targetCommitish, err = c.fileContents(filepath.Join(sourceDir, request.Params.CommitishPath))
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
release := &gitlab.RepositoryRelease{
|
||||
Name: gitlab.String(name),
|
||||
TagName: gitlab.String(tag),
|
||||
Body: gitlab.String(body),
|
||||
TargetCommitish: gitlab.String(targetCommitish),
|
||||
}
|
||||
|
||||
draft := request.Source.Drafts
|
||||
prerelease := false
|
||||
if request.Source.PreRelease == true && request.Source.Release == false {
|
||||
prerelease = request.Source.PreRelease
|
||||
}
|
||||
|
||||
release := &github.RepositoryRelease{
|
||||
Name: github.String(name),
|
||||
TagName: github.String(tag),
|
||||
Body: github.String(body),
|
||||
Draft: github.Bool(draft),
|
||||
Prerelease: github.Bool(prerelease),
|
||||
TargetCommitish: github.String(targetCommitish),
|
||||
}
|
||||
|
||||
existingReleases, err := c.github.ListReleases()
|
||||
tagExists := false
|
||||
existingTag, err := c.gitlab.GetTag(tag)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
//TODO: improve the check to be based on the specific error
|
||||
tagExists = true
|
||||
}
|
||||
|
||||
var existingRelease *github.RepositoryRelease
|
||||
for _, e := range existingReleases {
|
||||
if e.TagName != nil && *e.TagName == tag {
|
||||
existingRelease = e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if existingRelease != nil {
|
||||
releaseAssets, err := c.github.ListReleaseAssets(*existingRelease)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
|
||||
existingRelease.Name = github.String(name)
|
||||
existingRelease.TargetCommitish = github.String(targetCommitish)
|
||||
existingRelease.Draft = github.Bool(draft)
|
||||
existingRelease.Prerelease = github.Bool(prerelease)
|
||||
|
||||
if bodySpecified {
|
||||
existingRelease.Body = github.String(body)
|
||||
} else {
|
||||
existingRelease.Body = nil
|
||||
}
|
||||
|
||||
for _, asset := range releaseAssets {
|
||||
fmt.Fprintf(c.writer, "clearing existing asset: %s\n", *asset.Name)
|
||||
|
||||
err := c.github.DeleteReleaseAsset(*asset)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(c.writer, "updating release %s\n", name)
|
||||
|
||||
release, err = c.github.UpdateRelease(*existingRelease)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(c.writer, "creating release %s\n", name)
|
||||
release, err = c.github.CreateRelease(*release)
|
||||
// create the tag first, as next sections assume the tag exists
|
||||
if !tagExists {
|
||||
tag, err := c.gitlab.CreateTag(targetCommitish, tag)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// create a new release
|
||||
_, err = c.gitlab.CreateRelease(tag, "Auto-generated from Concourse GitLab Release Resource")
|
||||
if err != nil {
|
||||
// if 409 error occurs, this means the release already existed, so just skip to the next section (update the release)
|
||||
if err.Error() != "release already exists" {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// upload files
|
||||
var fileLinks []string
|
||||
for _, fileGlob := range params.Globs {
|
||||
matches, err := filepath.Glob(filepath.Join(sourceDir, fileGlob))
|
||||
if err != nil {
|
||||
@@ -136,13 +97,17 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
|
||||
}
|
||||
|
||||
for _, filePath := range matches {
|
||||
err := c.upload(release, filePath)
|
||||
projectFile, err := c.UploadProjectFile(filePath)
|
||||
if err != nil {
|
||||
return OutResponse{}, err
|
||||
}
|
||||
fileLinks = append(fileLinks, projectFile.Markdown)
|
||||
}
|
||||
}
|
||||
|
||||
// update the release
|
||||
release, err = c.gitlab.UpdateRelease(tag, fileLinks.Join("\n"))
|
||||
|
||||
return OutResponse{
|
||||
Version: versionFromRelease(release),
|
||||
Metadata: metadataFromRelease(release, ""),
|
||||
@@ -157,45 +122,3 @@ func (c *OutCommand) fileContents(path string) (string, error) {
|
||||
|
||||
return strings.TrimSpace(string(contents)), nil
|
||||
}
|
||||
|
||||
func (c *OutCommand) upload(release *github.RepositoryRelease, filePath string) error {
|
||||
fmt.Fprintf(c.writer, "uploading %s\n", filePath)
|
||||
|
||||
name := filepath.Base(filePath)
|
||||
|
||||
var retryErr error
|
||||
for i := 0; i < 10; i++ {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
retryErr = c.github.UploadReleaseAsset(*release, name, file)
|
||||
if retryErr == nil {
|
||||
break
|
||||
}
|
||||
|
||||
assets, err := c.github.ListReleaseAssets(*release)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, asset := range assets {
|
||||
if asset.Name != nil && *asset.Name == name {
|
||||
err = c.github.DeleteReleaseAsset(*asset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if retryErr != nil {
|
||||
return retryErr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -7,8 +7,8 @@ type Source struct {
|
||||
// Deprecated; use Owner instead
|
||||
User string `json:"user"`
|
||||
|
||||
GitHubAPIURL string `json:"github_api_url"`
|
||||
GitHubUploadsURL string `json:"github_uploads_url"`
|
||||
GitlabAPIURL string `json:"gitlab_api_url"`
|
||||
GitlabUploadsURL string `json:"gitlab_uploads_url"`
|
||||
AccessToken string `json:"access_token"`
|
||||
Drafts bool `json:"drafts"`
|
||||
PreRelease bool `json:"pre_release"`
|
||||
|
11
versions.go
11
versions.go
@@ -2,9 +2,6 @@ package resource
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
var defaultTagFilter = "^v?([^v].*)"
|
||||
@@ -31,11 +28,3 @@ func (vp *versionParser) parse(tag string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func versionFromRelease(release *github.RepositoryRelease) Version {
|
||||
if *release.Draft {
|
||||
return Version{ID: strconv.Itoa(*release.ID)}
|
||||
} else {
|
||||
return Version{Tag: *release.TagName}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user