Get compile working

This commit is contained in:
Ed
2018-12-16 21:38:30 -05:00
parent bc89091d9f
commit aa5c784d45
8 changed files with 187 additions and 234 deletions

View File

@@ -4,19 +4,19 @@ import (
"encoding/json" "encoding/json"
"os" "os"
"github.com/concourse/github-release-resource" "github.com/edtan/gitlab-release-resource"
) )
func main() { func main() {
request := resource.NewCheckRequest() request := resource.NewCheckRequest()
inputRequest(&request) inputRequest(&request)
github, err := resource.NewGitHubClient(request.Source) gitlab, err := resource.NewGitLabClient(request.Source)
if err != nil { if err != nil {
resource.Fatal("constructing github client", err) resource.Fatal("constructing gitlab client", err)
} }
command := resource.NewCheckCommand(github) command := resource.NewCheckCommand(gitlab)
response, err := command.Run(request) response, err := command.Run(request)
if err != nil { if err != nil {
resource.Fatal("running command", err) resource.Fatal("running command", err)

View File

@@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"os" "os"
"github.com/concourse/github-release-resource" "github.com/edtan/gitlab-release-resource"
) )
func main() { func main() {
@@ -18,12 +18,12 @@ func main() {
destDir := os.Args[1] destDir := os.Args[1]
github, err := resource.NewGitHubClient(request.Source) gitlab, err := resource.NewGitLabClient(request.Source)
if err != nil { if err != nil {
resource.Fatal("constructing github client", err) resource.Fatal("constructing gitlab client", err)
} }
command := resource.NewInCommand(github, os.Stderr) command := resource.NewInCommand(gitlab, os.Stderr)
response, err := command.Run(destDir, request) response, err := command.Run(destDir, request)
if err != nil { if err != nil {
resource.Fatal("running command", err) resource.Fatal("running command", err)

View File

@@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"os" "os"
"github.com/concourse/github-release-resource" "github.com/edtan/gitlab-release-resource"
) )
func main() { func main() {
@@ -18,12 +18,12 @@ func main() {
sourceDir := os.Args[1] sourceDir := os.Args[1]
github, err := resource.NewGitHubClient(request.Source) gitlab, err := resource.NewGitLabClient(request.Source)
if err != nil { if err != nil {
resource.Fatal("constructing github client", err) resource.Fatal("constructing gitlab client", err)
} }
command := resource.NewOutCommand(github, os.Stderr) command := resource.NewOutCommand(gitlab, os.Stderr)
response, err := command.Run(sourceDir, request) response, err := command.Run(sourceDir, request)
if err != nil { if err != nil {
resource.Fatal("running command", err) resource.Fatal("running command", err)

View File

@@ -3,8 +3,12 @@ package resource
import ( import (
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt"
"io"
"net/http" "net/http"
"net/url" "net/url"
"os"
"path/filepath"
"golang.org/x/oauth2" "golang.org/x/oauth2"
@@ -21,17 +25,19 @@ type GitLab interface {
GetTag(tag_name string) (*gitlab.Tag, error) GetTag(tag_name string) (*gitlab.Tag, error)
CreateTag(tag_name string, ref string) (*gitlab.Tag, error) CreateTag(tag_name string, ref string) (*gitlab.Tag, error)
CreateRelease(tag_name string, description string) (*gitlab.Release, error) CreateRelease(tag_name string, description string) (*gitlab.Release, error)
UpdateRelease(description string) (*gitlab.Release, error) UpdateRelease(tag_name string, description string) (*gitlab.Release, error)
UploadProjectFile(file string) (*gitlab.ProjectFile, error) UploadProjectFile(file string) (*gitlab.ProjectFile, error)
DownloadProjectFile(url, file string) error
} }
type gitlabClient struct { type gitlabClient struct {
client *gitlab.Client client *gitlab.Client
repository string accessToken string
repository string
} }
func NewGitlabClient(source Source) (*gitlabClient, error) { func NewGitLabClient(source Source) (*gitlabClient, error) {
var httpClient = &http.Client{} var httpClient = &http.Client{}
var ctx = context.TODO() var ctx = context.TODO()
@@ -214,3 +220,41 @@ func (g *gitlabClient) UploadProjectFile(file string) (*gitlab.ProjectFile, erro
return projectFile, nil return projectFile, nil
} }
func (g *gitlabClient) DownloadProjectFile(filePath, destPath string) error {
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
filePathRef, err := url.Parse(g.repository + filePath)
if err != nil {
return err
}
projectFileUrl := g.client.BaseURL().ResolveReference(filePathRef)
client := &http.Client{}
req, err := http.NewRequest("GET", projectFileUrl.String(), nil)
if err != nil {
return err
}
req.Header.Add("Private-Token", g.accessToken)
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to download file `%s`: HTTP status %d", filepath.Base(destPath), resp.StatusCode)
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}

21
go.sum Normal file
View File

@@ -0,0 +1,21 @@
github.com/concourse/github-release-resource v1.0.0 h1:jpN453IQGRXNZcyKdmIznnBNXU1p1ALKFDRYq6KblY4=
github.com/concourse/github-release-resource v1.0.0/go.mod h1:fTyLw17ZewAEU8MSqLNKj5cM4MSNhhi2uVHUALGZ1Zo=
github.com/cppforlife/go-semi-semantic v0.0.0-20160921010311-576b6af77ae4 h1:J+ghqo7ZubTzelkjo9hntpTtP/9lUCWH9icEmAW+B+Q=
github.com/cppforlife/go-semi-semantic v0.0.0-20160921010311-576b6af77ae4/go.mod h1:socxpf5+mELPbosI149vWpNlHK6mbfWFxSWOoSndXR8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286 h1:KHyL+3mQOF9sPfs26lsefckcFNDcIZtiACQiECzIUkw=
github.com/mitchellh/colorstring v0.0.0-20150917214807-8631ce90f286/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/xanzy/go-gitlab v0.12.0 h1:rs40DfrKvJoIluarQJcFmOADVMlgFGDMXvnEeQpjqGg=
github.com/xanzy/go-gitlab v0.12.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849 h1:FSqE2GGG7wzsYUsWiQ8MZrvEd1EOyU3NCF0AW3Wtltg=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

View File

@@ -5,22 +5,26 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strings"
"github.com/google/go-github/github" "github.com/xanzy/go-gitlab"
) )
type InCommand struct { type InCommand struct {
github GitHub gitlab GitLab
writer io.Writer writer io.Writer
} }
func NewInCommand(github GitHub, writer io.Writer) *InCommand { type attachment struct {
Name string
URL string
}
func NewInCommand(gitlab GitLab, writer io.Writer) *InCommand {
return &InCommand{ return &InCommand{
github: github, gitlab: gitlab,
writer: writer, writer: writer,
} }
} }
@@ -31,81 +35,65 @@ func (c *InCommand) Run(destDir string, request InRequest) (InResponse, error) {
return InResponse{}, err return InResponse{}, err
} }
var foundRelease *github.RepositoryRelease var foundTag *gitlab.Tag
var commitSHA string
if request.Version.Tag != "" { foundTag, err = c.gitlab.GetTag(request.Version.Tag)
foundRelease, err = c.github.GetReleaseByTag(request.Version.Tag) if err != nil {
return InResponse{}, err
}
if foundTag == nil {
return InResponse{}, errors.New("could not find tag")
}
tagPath := filepath.Join(destDir, "tag")
err = ioutil.WriteFile(tagPath, []byte(foundTag.Name), 0644)
if err != nil {
return InResponse{}, err
}
versionParser, err := newVersionParser(request.Source.TagFilter)
if err != nil {
return InResponse{}, err
}
version := versionParser.parse(foundTag.Name)
versionPath := filepath.Join(destDir, "version")
err = ioutil.WriteFile(versionPath, []byte(version), 0644)
if err != nil {
return InResponse{}, err
}
commitPath := filepath.Join(destDir, "commit_sha")
err = ioutil.WriteFile(commitPath, []byte(foundTag.Commit.ID), 0644)
if err != nil {
return InResponse{}, err
}
if foundTag.Release != nil && foundTag.Release != nil && foundTag.Release.Description != "" {
body := foundTag.Release.Description
bodyPath := filepath.Join(destDir, "body")
err = ioutil.WriteFile(bodyPath, []byte(body), 0644)
if err != nil {
return InResponse{}, err
}
} else { } else {
id, _ := strconv.Atoi(request.Version.ID) return InResponse{}, errors.New("release notes for the tag was empty")
foundRelease, err = c.github.GetRelease(id)
} }
attachments, err := c.getAttachments(foundTag.Release.Description)
if err != nil { if err != nil {
return InResponse{}, err return InResponse{}, err
} }
if foundRelease == nil { for _, attachment := range attachments {
return InResponse{}, errors.New("no releases") path := filepath.Join(destDir, attachment.Name)
}
if foundRelease.TagName != nil && *foundRelease.TagName != "" {
tagPath := filepath.Join(destDir, "tag")
err = ioutil.WriteFile(tagPath, []byte(*foundRelease.TagName), 0644)
if err != nil {
return InResponse{}, err
}
versionParser, err := newVersionParser(request.Source.TagFilter)
if err != nil {
return InResponse{}, err
}
version := versionParser.parse(*foundRelease.TagName)
versionPath := filepath.Join(destDir, "version")
err = ioutil.WriteFile(versionPath, []byte(version), 0644)
if err != nil {
return InResponse{}, err
}
if foundRelease.Draft != nil && !*foundRelease.Draft {
commitPath := filepath.Join(destDir, "commit_sha")
commitSHA, err = c.resolveTagToCommitSHA(*foundRelease.TagName)
if err != nil {
return InResponse{}, err
}
if commitSHA != "" {
err = ioutil.WriteFile(commitPath, []byte(commitSHA), 0644)
if err != nil {
return InResponse{}, err
}
}
}
if foundRelease.Body != nil && *foundRelease.Body != "" {
body := *foundRelease.Body
bodyPath := filepath.Join(destDir, "body")
err = ioutil.WriteFile(bodyPath, []byte(body), 0644)
if err != nil {
return InResponse{}, err
}
}
}
assets, err := c.github.ListReleaseAssets(*foundRelease)
if err != nil {
return InResponse{}, err
}
for _, asset := range assets {
path := filepath.Join(destDir, *asset.Name)
var matchFound bool var matchFound bool
if len(request.Params.Globs) == 0 { if len(request.Params.Globs) == 0 {
matchFound = true matchFound = true
} else { } else {
for _, glob := range request.Params.Globs { for _, glob := range request.Params.Globs {
matches, err := filepath.Match(glob, *asset.Name) matches, err := filepath.Match(glob, attachment.Name)
if err != nil { if err != nil {
return InResponse{}, err return InResponse{}, err
} }
@@ -121,98 +109,36 @@ func (c *InCommand) Run(destDir string, request InRequest) (InResponse, error) {
continue continue
} }
fmt.Fprintf(c.writer, "downloading asset: %s\n", *asset.Name) fmt.Fprintf(c.writer, "downloading file: %s\n", attachment.Name)
err := c.gitlab.DownloadProjectFile(attachment.URL, path)
err := c.downloadAsset(asset, path)
if err != nil { if err != nil {
return InResponse{}, err return InResponse{}, err
} }
} }
if request.Params.IncludeSourceTarball {
u, err := c.github.GetTarballLink(request.Version.Tag)
if err != nil {
return InResponse{}, err
}
fmt.Fprintln(c.writer, "downloading source tarball to source.tar.gz")
if err := c.downloadFile(u.String(), filepath.Join(destDir, "source.tar.gz")); err != nil {
return InResponse{}, err
}
}
if request.Params.IncludeSourceZip {
u, err := c.github.GetZipballLink(request.Version.Tag)
if err != nil {
return InResponse{}, err
}
fmt.Fprintln(c.writer, "downloading source zip to source.zip")
if err := c.downloadFile(u.String(), filepath.Join(destDir, "source.zip")); err != nil {
return InResponse{}, err
}
}
return InResponse{ return InResponse{
Version: versionFromRelease(foundRelease), Version: Version{Tag: foundTag.Name},
Metadata: metadataFromRelease(foundRelease, commitSHA), Metadata: metadataFromTag(foundTag),
}, nil }, nil
} }
func (c *InCommand) downloadAsset(asset *github.ReleaseAsset, destPath string) error { // This resource stores the attachments as line-separated markdown links.
out, err := os.Create(destPath) func (c *InCommand) getAttachments(releaseBody string) ([]attachment, error) {
if err != nil { var attachments []attachment
return err
}
defer out.Close()
content, err := c.github.DownloadReleaseAsset(*asset) lines := strings.Split(releaseBody, "\n")
if err != nil { for _, line := range lines {
return err nameStart := strings.Index(line, "[") + 1
} nameEnd := strings.Index(line, "]") - 1
defer content.Close() urlStart := strings.Index(line, "(") + 1
urlEnd := strings.Index(line, ")") - 1
attachments = append(attachments, attachment{
Name: line[nameStart:nameEnd],
URL: line[urlStart:urlEnd],
})
_, err = io.Copy(out, content)
if err != nil {
return err
} }
return nil return attachments, nil
}
func (c *InCommand) downloadFile(url, destPath string) error {
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to download file `%s`: HTTP status %d", filepath.Base(destPath), resp.StatusCode)
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
func (c *InCommand) resolveTagToCommitSHA(tag string) (string, error) {
reference, err := c.github.GetRef(tag)
if err != nil {
return "", err
}
if *reference.Object.Type != "commit" {
fmt.Fprintf(c.writer, "could not resolve tag '%s' to commit: returned type is not 'commit' - only lightweight tags are supported\n", tag)
return "", err
}
return *reference.Object.SHA, err
} }

View File

@@ -1,63 +1,31 @@
package resource package resource
import "github.com/google/go-github/github" import "github.com/xanzy/go-gitlab"
func metadataFromRelease(release *github.RepositoryRelease, commitSHA string) []MetadataPair { func metadataFromTag(tag *gitlab.Tag) []MetadataPair {
metadata := []MetadataPair{} metadata := []MetadataPair{}
if release.Name != nil { if tag.Name != "" {
nameMeta := MetadataPair{ nameMeta := MetadataPair{
Name: "name", Name: "name",
Value: *release.Name, Value: tag.Name,
}
if release.HTMLURL != nil {
nameMeta.URL = *release.HTMLURL
} }
metadata = append(metadata, nameMeta) metadata = append(metadata, nameMeta)
} }
if release.HTMLURL != nil { if tag.Release.Description != "" {
metadata = append(metadata, MetadataPair{
Name: "url",
Value: *release.HTMLURL,
})
}
if release.Body != nil {
metadata = append(metadata, MetadataPair{ metadata = append(metadata, MetadataPair{
Name: "body", Name: "body",
Value: *release.Body, Value: tag.Release.Description,
Markdown: true, Markdown: true,
}) })
} }
if release.TagName != nil { if tag.Commit.ID != "" {
metadata = append(metadata, MetadataPair{
Name: "tag",
Value: *release.TagName,
})
}
if commitSHA != "" {
metadata = append(metadata, MetadataPair{ metadata = append(metadata, MetadataPair{
Name: "commit_sha", Name: "commit_sha",
Value: commitSHA, Value: tag.Commit.ID,
})
}
if *release.Draft {
metadata = append(metadata, MetadataPair{
Name: "draft",
Value: "true",
})
}
if *release.Prerelease {
metadata = append(metadata, MetadataPair{
Name: "pre-release",
Value: "true",
}) })
} }
return metadata return metadata

View File

@@ -1,13 +1,12 @@
package resource package resource
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/xanzy/go-gitlab"
) )
type OutCommand struct { type OutCommand struct {
@@ -25,10 +24,10 @@ func NewOutCommand(gitlab GitLab, writer io.Writer) *OutCommand {
func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, error) { func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, error) {
params := request.Params params := request.Params
name, err := c.fileContents(filepath.Join(sourceDir, request.Params.NamePath)) // name, err := c.fileContents(filepath.Join(sourceDir, request.Params.NamePath))
if err != nil { // if err != nil {
return OutResponse{}, err // return OutResponse{}, err
} // }
tag, err := c.fileContents(filepath.Join(sourceDir, request.Params.TagPath)) tag, err := c.fileContents(filepath.Join(sourceDir, request.Params.TagPath))
if err != nil { if err != nil {
@@ -37,31 +36,20 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
tag = request.Params.TagPrefix + tag tag = request.Params.TagPrefix + tag
targetCommitish, err = c.fileContents(filepath.Join(sourceDir, request.Params.CommitishPath)) targetCommitish, err := c.fileContents(filepath.Join(sourceDir, request.Params.CommitishPath))
if err != nil { if err != nil {
return OutResponse{}, err return OutResponse{}, err
} }
var body string // if request.Params.BodyPath != "" {
bodySpecified := false // _, err := c.fileContents(filepath.Join(sourceDir, request.Params.BodyPath))
if request.Params.BodyPath != "" { // if err != nil {
bodySpecified = true // return OutResponse{}, err
// }
body, err = c.fileContents(filepath.Join(sourceDir, request.Params.BodyPath)) // }
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),
}
tagExists := false tagExists := false
existingTag, err := c.gitlab.GetTag(tag) _, err = c.gitlab.GetTag(tag)
if err != nil { if err != nil {
//TODO: improve the check to be based on the specific error //TODO: improve the check to be based on the specific error
tagExists = true tagExists = true
@@ -69,7 +57,7 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
// create the tag first, as next sections assume the tag exists // create the tag first, as next sections assume the tag exists
if !tagExists { if !tagExists {
tag, err := c.gitlab.CreateTag(targetCommitish, tag) _, err := c.gitlab.CreateTag(targetCommitish, tag)
if err != nil { if err != nil {
return OutResponse{}, err return OutResponse{}, err
} }
@@ -97,7 +85,7 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
} }
for _, filePath := range matches { for _, filePath := range matches {
projectFile, err := c.UploadProjectFile(filePath) projectFile, err := c.gitlab.UploadProjectFile(filePath)
if err != nil { if err != nil {
return OutResponse{}, err return OutResponse{}, err
} }
@@ -106,11 +94,17 @@ func (c *OutCommand) Run(sourceDir string, request OutRequest) (OutResponse, err
} }
// update the release // update the release
release, err = c.gitlab.UpdateRelease(tag, fileLinks.Join("\n")) _, err = c.gitlab.UpdateRelease(tag, strings.Join(fileLinks, "\n"))
// get tag
savedTag, err := c.gitlab.GetTag(tag)
if err != nil {
return OutResponse{}, errors.New("could not get saved tag")
}
return OutResponse{ return OutResponse{
Version: versionFromRelease(release), Version: Version{Tag: tag},
Metadata: metadataFromRelease(release, ""), Metadata: metadataFromTag(savedTag),
}, nil }, nil
} }