mirror of https://gitlab.com/gitlab-org/cli.git
171 lines
4.9 KiB
Go
171 lines
4.9 KiB
Go
package upload
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/MakeNowJust/heredoc"
|
|
"github.com/spf13/cobra"
|
|
"github.com/xanzy/go-gitlab"
|
|
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
|
"gitlab.com/gitlab-org/cli/commands/release/releaseutils"
|
|
"gitlab.com/gitlab-org/cli/commands/release/releaseutils/upload"
|
|
"gitlab.com/gitlab-org/cli/internal/config"
|
|
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
|
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
|
)
|
|
|
|
type UploadOpts struct {
|
|
TagName string
|
|
AssetLinksAsJson string
|
|
|
|
AssetLinks []*upload.ReleaseAsset
|
|
AssetFiles []*upload.ReleaseFile
|
|
|
|
IO *iostreams.IOStreams
|
|
HTTPClient func() (*gitlab.Client, error)
|
|
BaseRepo func() (glrepo.Interface, error)
|
|
Config func() (config.Config, error)
|
|
}
|
|
|
|
func NewCmdUpload(f *cmdutils.Factory, runE func(opts *UploadOpts) error) *cobra.Command {
|
|
opts := &UploadOpts{
|
|
IO: f.IO,
|
|
Config: f.Config,
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "upload <tag> [<files>...]",
|
|
Short: "Upload release asset files or links to GitLab Release",
|
|
Long: heredoc.Doc(`Upload release assets to GitLab Release
|
|
|
|
You can define the display name by appending '#' after the file name.
|
|
The link type comes after the display name (eg. 'myfile.tar.gz#My display name#package')
|
|
`),
|
|
Args: func() cobra.PositionalArgs {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
if len(args) < 1 {
|
|
return &cmdutils.FlagError{Err: errors.New("no tag name provided")}
|
|
}
|
|
if len(args) < 2 && opts.AssetLinksAsJson == "" {
|
|
return cmdutils.FlagError{Err: errors.New("no files specified")}
|
|
}
|
|
return nil
|
|
}
|
|
}(),
|
|
Example: heredoc.Doc(`
|
|
Upload a release asset with a display name
|
|
$ glab release upload v1.0.1 '/path/to/asset.zip#My display label'
|
|
|
|
Upload a release asset with a display name and type
|
|
$ glab release upload v1.0.1 '/path/to/asset.png#My display label#image'
|
|
|
|
Upload all assets in a specified folder
|
|
$ glab release upload v1.0.1 ./dist/*
|
|
|
|
Upload all tarballs in a specified folder
|
|
$ glab release upload v1.0.1 ./dist/*.tar.gz
|
|
|
|
Upload release assets links specified as JSON string
|
|
$ glab release upload v1.0.1 --assets-links='
|
|
[
|
|
{
|
|
"name": "Asset1",
|
|
"url":"https://<domain>/some/location/1",
|
|
"link_type": "other",
|
|
"filepath": "path/to/file"
|
|
}
|
|
]'
|
|
`),
|
|
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 = releaseutils.AssetsFromArgs(args[1:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if opts.AssetFiles == nil && opts.AssetLinksAsJson == "" {
|
|
return cmdutils.FlagError{Err: errors.New("no files specified")}
|
|
}
|
|
|
|
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 runE != nil {
|
|
return runE(opts)
|
|
}
|
|
|
|
return deleteRun(opts)
|
|
},
|
|
}
|
|
|
|
cmd.Flags().StringVarP(&opts.AssetLinksAsJson, "assets-links", "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 deleteRun(opts *UploadOpts) error {
|
|
start := time.Now()
|
|
|
|
client, err := opts.HTTPClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
repo, err := opts.BaseRepo()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
color := opts.IO.Color()
|
|
var resp *gitlab.Response
|
|
|
|
opts.IO.Logf("%s validating tag %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 {
|
|
if resp != nil && (resp.StatusCode == 404 || resp.StatusCode == 403) {
|
|
return cmdutils.WrapError(err, "release does not exist. Create a new release with `glab release create "+opts.TagName+"`")
|
|
}
|
|
return cmdutils.WrapError(err, "failed to fetch release")
|
|
}
|
|
|
|
opts.IO.Logf("%s uploading release assets %s=%s %s=%s\n",
|
|
color.ProgressIcon(),
|
|
color.Blue("repo"), repo.FullName(),
|
|
color.Blue("tag"), opts.TagName)
|
|
// upload files and create asset link
|
|
if opts.AssetFiles != nil || opts.AssetLinks != nil {
|
|
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 cmdutils.WrapError(err, "upload failed")
|
|
}
|
|
|
|
// create asset link for assets provided as json
|
|
if err = uploadCtx.CreateReleaseAssetLinks(repo.FullName(), release.TagName); err != nil {
|
|
return cmdutils.WrapError(err, "failed to create release link")
|
|
}
|
|
}
|
|
|
|
opts.IO.Logf(color.Bold("%s upload succeeded after %0.2fs\n"), color.GreenCheck(), time.Since(start).Seconds())
|
|
return nil
|
|
}
|