mirror of https://gitlab.com/gitlab-org/cli.git
feat: add `release create` command
This commit is contained in:
parent
dbb7f2dd46
commit
c707d7d3f7
|
@ -12,6 +12,9 @@ workflow:
|
|||
- if: '$CI_COMMIT_BRANCH =~ /^[\d-]+-stable$/'
|
||||
#
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
||||
default:
|
||||
image: golang:1.15
|
||||
|
||||
|
@ -37,3 +40,31 @@ code_navigation:
|
|||
artifacts:
|
||||
reports:
|
||||
lsif: dump.lsif
|
||||
|
||||
.test:
|
||||
variables:
|
||||
GOPATH: "/builds/go"
|
||||
GIT_CLONE_PATH: $GOPATH/src/github.com/profclems/glab
|
||||
GITLAB_TOKEN: "qRC87Xg9Wd46RhB8J8sp"
|
||||
CODECOV_TOKEN: "1597edbc-8760-42c1-ab79-c192ad151717"
|
||||
before_script:
|
||||
# Add a non-sensitive ssh key for test to work.
|
||||
- mkdir ~/.ssh && chmod 700 ~/.ssh
|
||||
- echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- echo -e "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCc54ULcDSmuQBMaM52dqxNMETAlwn01AF79vJb6Nw3SzkNKEMY1pBttM1U8wz7dHpVteAQGCU2AH+T2UhswZWPIzcMfVwB+1RgcIkHW184V5FX1xxqo4Xx6CC6LTSq3md/EmXfQR7gAwaKQHy6txxYpEprlhw+EWICgD5znUMprRRbcsb2FoAdsodMWSl5aRIyC1rA06SKKwqN09o4mgNhv49McyzDnUCGmSTc0oQpygPadDRqW46iCkMdiJa1fuP9pSGkAuTaQayILbDenAM3cV7LqsIm7tOXLPW5fQm9FB91ftRLXxk1Mp6lMYqNc5eGoR4ATzHn7M/VHbBaqVlp profclems@ProfClems" > ~/.ssh/id_rsa.pub
|
||||
- echo -e "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAQEAnOeFC3A0prkATGjOdnasTTBEwJcJ9NQBe/byW+jcN0s5DShDGNaQ\nbbTNVPMM+3R6VbXgEBglNgB/k9lIbMGVjyM3DH1cAftUYHCJB1tfOFeRV9ccaqOF8eggui\n00qt5nfxJl30Ee4AMGikB8urccWKRKa5YcPhFiAoA+c51DKa0UW3LG9haAHbKHTFkpeWkS\nMgtawNOkiisKjdPaOJoDYb+PTHMsw51Ahpkk3NKEKcoD2nQ0aluOogpDHYiWtX7j/aUhpA\nLk2kGsiC2w3pwDN3Fey6rCJu7Tlyz1uX0JvRQfdX7US18ZNTKepTGKjXOXhqEeAE8x5+zP\n1R2wWqlZaQAAA8j2Yikl9mIpJQAAAAdzc2gtcnNhAAABAQCc54ULcDSmuQBMaM52dqxNME\nTAlwn01AF79vJb6Nw3SzkNKEMY1pBttM1U8wz7dHpVteAQGCU2AH+T2UhswZWPIzcMfVwB\n+1RgcIkHW184V5FX1xxqo4Xx6CC6LTSq3md/EmXfQR7gAwaKQHy6txxYpEprlhw+EWICgD\n5znUMprRRbcsb2FoAdsodMWSl5aRIyC1rA06SKKwqN09o4mgNhv49McyzDnUCGmSTc0oQp\nygPadDRqW46iCkMdiJa1fuP9pSGkAuTaQayILbDenAM3cV7LqsIm7tOXLPW5fQm9FB91ft\nRLXxk1Mp6lMYqNc5eGoR4ATzHn7M/VHbBaqVlpAAAAAwEAAQAAAQAJvxv1nO+4V4+cL3p7\nw11qog/zQq6cpbq935YofWuIh8Swe4rHdTSdi/ihSUPKLu8WeejENyvAkgFaxsmH7/KBZL\nebsAHSIbGZGAR7D4L3tgDSSwt52FSOtVOrHPnDj3MwYo0vdBUd5zI1zlGxK4S4QORakIWK\nmXvUGfFHL0KnyP6uH3Z/j8hQaAE8TIVrGM6PyLes3NWFTlXIakrV8jiJc5bxVnhzDcIKdf\n9JUYGO3DUCQI+pdkCfMNptbBuGwqHjruruGYMfh+mx7FrnpjbJ3y2TG01pcXBeCRIJNm2/\n4htjlAxdz2Zxa8JL437s56Jf4ZtDOYt367dhTMRBleoxAAAAgDo0de+4nNSVb/H3aGo5Y0\nLg/q/npYUNVSvZ9R0GfRY0qDbNCaKeqbyJDkReRn5R/KKT9+Gx0/zqXGNi1ubnGtxqCCmC\nYHDys0PSw6yAEDZ3JOeYWEIO7ntH0DKdErcEUj+FqatdIpoZZO48XZDSXzO1+B1n2y+AML\nfyMggdFXIBAAAAgQDMnIFss9kLpnqC5QOAiDO+jsnHwNHENBgQKE9/jM6gagaK3T4TDkJl\nPszXRDE11LSBCxahL5rxwWDog1vG67tnbfznjhGm8Fd+mEs6omuQ5pA0o6Qx40xtkfn3vi\nj4NLkpo5rYg0DTtciDgGeibtt1oT1EhKZ59ystGdFgSGWxtQAAAIEAxE+xPCLHzqEUUlxI\nSJC6+e2hUT/9s64OwmH9pCrQ8+96G9TtbR9NFD1LSArnLXvl6ooYODw0QDjLdgCUQj63r7\nqOV9QjWKL6xD1atN37WFbrIpem8pFOJWinYrQtddANSBd5tp5QsDkI58ovqhdDuYoVfL1y\nmEfWvucOVlZraWUAAAATcHJvZmNsZW1zQFByb2ZDbGVtcw==\n-----END OPENSSH PRIVATE KEY-----" > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa*
|
||||
- eval `ssh-agent -s`
|
||||
- ssh-add ~/.ssh/id_rsa
|
||||
script:
|
||||
- go version
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- go get -t -v ./...
|
||||
- make test
|
||||
after_script:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
test:
|
||||
stage: test
|
||||
extends: .test
|
||||
image: golang:1.15
|
|
@ -2,6 +2,19 @@ package api
|
|||
|
||||
import "github.com/xanzy/go-gitlab"
|
||||
|
||||
var CreateRelease = func(client *gitlab.Client, projectID interface{}, opts *gitlab.CreateReleaseOptions) (*gitlab.Release, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
}
|
||||
|
||||
release, _, err := client.Releases.CreateRelease(projectID, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
var GetRelease = func(client *gitlab.Client, projectID interface{}, tag string) (*gitlab.Release, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
|
@ -14,6 +27,7 @@ var GetRelease = func(client *gitlab.Client, projectID interface{}, tag string)
|
|||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
var ListReleases = func(client *gitlab.Client, projectID interface{}, opts *gitlab.ListReleasesOptions) ([]*gitlab.Release, error) {
|
||||
if client == nil {
|
||||
client = apiClient.Lab()
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package cmdutils
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// FlagError is the kind of error raised in flag processing
|
||||
type FlagError struct {
|
||||
|
@ -17,3 +21,16 @@ func (fe FlagError) Unwrap() error {
|
|||
|
||||
// SilentError is an error that triggers exit code 1 without any error messaging
|
||||
var SilentError = errors.New("SilentError")
|
||||
|
||||
func MinimumArgs(n int, msg string) cobra.PositionalArgs {
|
||||
if msg == "" {
|
||||
return cobra.MinimumNArgs(1)
|
||||
}
|
||||
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < n {
|
||||
return &FlagError{Err: errors.New(msg)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,324 @@
|
|||
package create
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/profclems/glab/commands/release/upload"
|
||||
"github.com/profclems/glab/internal/glinstance"
|
||||
"github.com/profclems/glab/internal/glrepo"
|
||||
"github.com/profclems/glab/pkg/iostreams"
|
||||
|
||||
"github.com/profclems/glab/commands/cmdutils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type CreateOpts struct {
|
||||
Name string
|
||||
Ref string
|
||||
TagName string
|
||||
Notes string
|
||||
NotesFile string
|
||||
Milestone []string
|
||||
AssetLinksAsJson string
|
||||
ReleasedAt string
|
||||
|
||||
AssetLinks []*upload.ReleaseAsset
|
||||
AssetFiles []*upload.ReleaseFile
|
||||
|
||||
IO *iostreams.IOStreams
|
||||
HTTPClient func() (*gitlab.Client, error)
|
||||
BaseRepo func() (glrepo.Interface, error)
|
||||
}
|
||||
|
||||
func NewCmdCreate(f *cmdutils.Factory, runE func(opts *CreateOpts) error) *cobra.Command {
|
||||
opts := &CreateOpts{
|
||||
IO: f.IO,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "create <tag> [<files>...]",
|
||||
Short: "Create a new GitLab Release for a repository",
|
||||
Long: `Create a new GitLab Release for a repository.
|
||||
|
||||
You need push access to the repository to create a Release.`,
|
||||
Args: cmdutils.MinimumArgs(1, "no tag name provided"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
opts.HTTPClient = f.HttpClient
|
||||
opts.BaseRepo = f.BaseRepo
|
||||
|
||||
opts.TagName = args[0]
|
||||
|
||||
opts.AssetFiles, err = AssetsFromArgs(args[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.AssetLinksAsJson != "" {
|
||||
err := json.Unmarshal([]byte(opts.AssetLinksAsJson), &opts.AssetLinks)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse JSON string: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.NotesFile != "" {
|
||||
if opts.NotesFile == "-" {
|
||||
b, err := ioutil.ReadAll(opts.IO.In)
|
||||
_ = opts.IO.In.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts.Notes = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
if runE != nil {
|
||||
return runE(opts)
|
||||
}
|
||||
|
||||
return createRun(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&opts.Name, "name", "n", "", "The release name or title")
|
||||
cmd.Flags().StringVarP(&opts.Ref, "ref", "r", "", "If a tag specified doesn’t exist, the release is created from ref and tagged with the specified tag name. It can be a commit SHA, another tag name, or a branch name.")
|
||||
cmd.Flags().StringVarP(&opts.Notes, "notes", "N", "", "The release notes/description. You can use Markdown")
|
||||
cmd.Flags().StringVarP(&opts.NotesFile, "notes-file", "F", "", "Read release notes `file`")
|
||||
cmd.Flags().StringVarP(&opts.ReleasedAt, "released-at", "D", "", "The `date` when the release is/was ready. Defaults to the current datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)")
|
||||
cmd.Flags().StringSliceVarP(&opts.Milestone, "milestone", "m", []string{}, "The title of each milestone the release is associated with")
|
||||
cmd.Flags().StringVarP(&opts.AssetLinksAsJson, "assets", "a", "", "`JSON` string representation of assets links (e.g. --assets='[{\"name\": \"Asset1\", \"url\":\"https://<domain>/some/location/1\", \"link_type\": \"other\", \"filepath\": \"path/to/file\" }]'")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createRun(opts *CreateOpts) error {
|
||||
client, err := opts.HTTPClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := opts.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
color := opts.IO.Color()
|
||||
|
||||
fmt.Fprintf(opts.IO.StdErr, "%s creating or updating release %s=%s %s=%s\n",
|
||||
color.ProgressIcon(),
|
||||
color.Blue("repo"), repo.FullName(),
|
||||
color.Blue("tag"), opts.TagName)
|
||||
|
||||
release, resp, err := client.Releases.GetRelease(repo.FullName(), opts.TagName)
|
||||
if err != nil && (resp == nil || resp.StatusCode != 403) {
|
||||
return err
|
||||
}
|
||||
|
||||
var releasedAt time.Time
|
||||
|
||||
if opts.ReleasedAt != "" {
|
||||
// Parse the releasedAt to the expected format of the API
|
||||
// From the API docs "Expected in ISO 8601 format (2019-03-15T08:00:00Z)".
|
||||
releasedAt, err = time.Parse(time.RFC3339[:len(opts.ReleasedAt)], opts.ReleasedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode == 403 || release == nil {
|
||||
release, _, err = client.Releases.CreateRelease(repo.FullName(), &gitlab.CreateReleaseOptions{
|
||||
Name: &opts.Name,
|
||||
Description: &opts.Notes,
|
||||
Ref: &opts.Ref,
|
||||
TagName: &opts.TagName,
|
||||
ReleasedAt: &releasedAt,
|
||||
Milestones: opts.Milestone,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(opts.IO.StdErr, "%s, release created\t%s=%s\n", color.ProgressIcon(),
|
||||
color.Blue("url"), fmt.Sprintf("%s://%s/%s/releases/tag/%s",
|
||||
glinstance.OverridableDefaultProtocol(), glinstance.OverridableDefault(),
|
||||
repo.FullName(), release.TagName))
|
||||
} else {
|
||||
apiOpts := &gitlab.UpdateReleaseOptions{}
|
||||
if opts.Notes != "" {
|
||||
apiOpts.Description = &opts.Notes
|
||||
}
|
||||
if opts.Name != "" {
|
||||
apiOpts.Name = &opts.Name
|
||||
}
|
||||
|
||||
if opts.ReleasedAt != "" {
|
||||
apiOpts.ReleasedAt = &releasedAt
|
||||
}
|
||||
|
||||
if len(opts.Milestone) > 0 {
|
||||
apiOpts.Milestones = opts.Milestone
|
||||
}
|
||||
|
||||
release, _, err = client.Releases.UpdateRelease(repo.FullName(), opts.TagName, apiOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.StdErr, "%s release updated\t%s=%s\n", color.ProgressIcon(),
|
||||
color.Blue("url"), fmt.Sprintf("%s://%s/%s/-/releases/tag/%s",
|
||||
glinstance.OverridableDefaultProtocol(), glinstance.OverridableDefault(),
|
||||
repo.FullName(), release.TagName))
|
||||
}
|
||||
|
||||
// upload files and create asset link
|
||||
if opts.AssetFiles != nil || opts.AssetLinks != nil {
|
||||
fmt.Fprintf(opts.IO.StdErr, "\n%s Uploading release assets\n", color.ProgressIcon())
|
||||
uploadCtx := upload.Context{
|
||||
IO: opts.IO,
|
||||
Client: client,
|
||||
AssetsLinks: opts.AssetLinks,
|
||||
AssetFiles: opts.AssetFiles,
|
||||
}
|
||||
if err = uploadCtx.UploadFiles(repo.FullName(), release.TagName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create asset link for assets provided as json
|
||||
if err = uploadCtx.CreateReleaseAssetLinks(repo.FullName(), release.TagName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(opts.Milestone) > 0 {
|
||||
// close all associated milestones
|
||||
for _, milestone := range opts.Milestone {
|
||||
// run loading msg
|
||||
opts.IO.StartSpinner("closing milestone %q", milestone)
|
||||
// close milestone
|
||||
err := closeMilestone(opts, milestone)
|
||||
// stop loading
|
||||
opts.IO.StopSpinner("")
|
||||
if err != nil {
|
||||
fmt.Fprintln(opts.IO.StdErr, color.FailedIcon(), err.Error())
|
||||
} else {
|
||||
fmt.Fprintf(opts.IO.StdErr, "%s closed milestone %q\n", color.GreenCheck(), milestone)
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(opts.IO.StdErr, "%s release succeeded", color.GreenCheck())
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMilestoneByTitle(c *CreateOpts, title string) (*gitlab.Milestone, error) {
|
||||
opts := &gitlab.ListMilestonesOptions{
|
||||
Title: &title,
|
||||
}
|
||||
|
||||
client, err := c.HTTPClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo, err := c.BaseRepo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for {
|
||||
milestones, resp, err := client.Milestones.ListMilestones(repo.FullName(), opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, milestone := range milestones {
|
||||
if milestone != nil && milestone.Title == title {
|
||||
return milestone, nil
|
||||
}
|
||||
}
|
||||
|
||||
if resp.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
opts.Page = resp.NextPage
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CloseMilestone closes a given milestone.
|
||||
func closeMilestone(c *CreateOpts, title string) error {
|
||||
client, err := c.HTTPClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := c.BaseRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
milestone, err := getMilestoneByTitle(c, title)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if milestone == nil {
|
||||
return fmt.Errorf("could not find milestone: %q", title)
|
||||
}
|
||||
|
||||
closeStateEvent := "close"
|
||||
|
||||
opts := &gitlab.UpdateMilestoneOptions{
|
||||
Description: &milestone.Description,
|
||||
DueDate: milestone.DueDate,
|
||||
StartDate: milestone.StartDate,
|
||||
StateEvent: &closeStateEvent,
|
||||
Title: &milestone.Title,
|
||||
}
|
||||
|
||||
_, _, err = client.Milestones.UpdateMilestone(
|
||||
repo.FullName(),
|
||||
milestone.ID,
|
||||
opts,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func AssetsFromArgs(args []string) (assets []*upload.ReleaseFile, err error) {
|
||||
for _, arg := range args {
|
||||
var label string
|
||||
fn := arg
|
||||
if idx := strings.IndexRune(arg, '#'); idx > 0 {
|
||||
fn = arg[0:idx]
|
||||
label = arg[idx+1:]
|
||||
}
|
||||
|
||||
var fi os.FileInfo
|
||||
fi, err = os.Stat(fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if label == "" {
|
||||
label = fi.Name()
|
||||
}
|
||||
|
||||
assets = append(assets, &upload.ReleaseFile{
|
||||
Open: func() (io.ReadCloser, error) {
|
||||
return os.Open(fn)
|
||||
},
|
||||
Name: fi.Name(),
|
||||
Label: label,
|
||||
Path: fn,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
|
@ -2,6 +2,7 @@ package release
|
|||
|
||||
import (
|
||||
"github.com/profclems/glab/commands/cmdutils"
|
||||
releaseCreateCmd "github.com/profclems/glab/commands/release/create"
|
||||
releaseListCmd "github.com/profclems/glab/commands/release/list"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -15,7 +16,9 @@ func NewCmdRelease(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
cmdutils.EnableRepoOverride(releaseCmd, f)
|
||||
|
||||
releaseCmd.AddCommand(releaseListCmd.NewCmdReleaseList(f))
|
||||
releaseCmd.AddCommand(releaseCreateCmd.NewCmdCreate(f, nil))
|
||||
|
||||
return releaseCmd
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package upload
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/profclems/glab/internal/glinstance"
|
||||
"github.com/profclems/glab/pkg/iostreams"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type ReleaseAsset struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
FilePath *string `json:"filepath,omitempty"`
|
||||
LinkType *gitlab.LinkTypeValue `json:"link_type,omitempty"`
|
||||
}
|
||||
|
||||
type ReleaseFile struct {
|
||||
Open func() (io.ReadCloser, error)
|
||||
Name string
|
||||
Label string
|
||||
Path string
|
||||
}
|
||||
|
||||
func CreateLink(c *gitlab.Client, projectID, tagName string, asset *ReleaseAsset) (*gitlab.ReleaseLink, error) {
|
||||
releaseLink, _, err := c.ReleaseLinks.CreateReleaseLink(projectID, tagName, &gitlab.CreateReleaseLinkOptions{
|
||||
Name: asset.Name,
|
||||
URL: asset.URL,
|
||||
FilePath: asset.FilePath,
|
||||
LinkType: asset.LinkType,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return releaseLink, nil
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
Client *gitlab.Client
|
||||
IO *iostreams.IOStreams
|
||||
AssetFiles []*ReleaseFile
|
||||
AssetsLinks []*ReleaseAsset
|
||||
}
|
||||
|
||||
// UploadFiles uploads a file into a release repository.
|
||||
func (c *Context) UploadFiles(projectID, tagName string) error {
|
||||
if c.AssetFiles == nil {
|
||||
return nil
|
||||
}
|
||||
color := c.IO.Color()
|
||||
for _, file := range c.AssetFiles {
|
||||
fmt.Fprintf(c.IO.StdErr, "%s Uploading to release\t%s=%s %s=%s\n",
|
||||
color.ProgressIcon(), color.Blue("file"), file.Path,
|
||||
color.Blue("name"), file.Name)
|
||||
|
||||
projectFile, _, err := c.Client.Projects.UploadFile(
|
||||
projectID,
|
||||
file.Path,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gitlabBaseURL := fmt.Sprintf("%s://%s/", glinstance.OverridableDefaultProtocol(), glinstance.OverridableDefault())
|
||||
// projectFile.URL from upload: /uploads/<hash>/filename.txt
|
||||
linkURL := gitlabBaseURL + projectID + projectFile.URL
|
||||
filename := "/" + file.Name
|
||||
|
||||
_, err = CreateLink(c.Client, projectID, tagName, &ReleaseAsset{
|
||||
Name: &file.Label,
|
||||
URL: &linkURL,
|
||||
FilePath: &filename,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.AssetFiles = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) CreateReleaseAssetLinks(projectID string, tagName string) error {
|
||||
if c.AssetsLinks == nil {
|
||||
return nil
|
||||
}
|
||||
color := c.IO.Color()
|
||||
for _, asset := range c.AssetsLinks {
|
||||
releaseLink, err := CreateLink(c.Client, projectID, tagName, asset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(c.IO.StdErr, "%s Added release asset\t%s=%s %s=%s\n",
|
||||
color.GreenCheck(), color.Blue("name"), *asset.Name,
|
||||
color.Blue("url"), releaseLink.DirectAssetURL)
|
||||
}
|
||||
c.AssetsLinks = nil
|
||||
|
||||
return nil
|
||||
}
|
|
@ -15,3 +15,7 @@ func (c *ColorPalette) WarnIcon() string {
|
|||
func (c *ColorPalette) RedCheck() string {
|
||||
return c.Red("✓")
|
||||
}
|
||||
|
||||
func (c *ColorPalette) ProgressIcon() string {
|
||||
return c.Blue("•")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue