Release Asset Management (#619)
Add release asset management. This includes a series of subcommands under `tea release assets`: - `tea release assets create <release-tag> <asset> [<asset>...]`: Upload one or more release attachments - `tea release assets delete <release tag> <attachment name> [<attachment name>...]`: Delete one or more release attachments - `tea release assets list <release tag>`: List Release Attachments Co-authored-by: Dane Bouchie <dbouchie@iradimed.com> Reviewed-on: https://gitea.com/gitea/tea/pulls/619 Co-authored-by: danebou <danebou@noreply.gitea.com> Co-committed-by: danebou <danebou@noreply.gitea.com>
This commit is contained in:
parent
20479663f0
commit
4c0cef090d
19
README.md
19
README.md
|
@ -29,15 +29,16 @@
|
||||||
COMMANDS
|
COMMANDS
|
||||||
help, h Shows a list of commands or help for one command
|
help, h Shows a list of commands or help for one command
|
||||||
ENTITIES:
|
ENTITIES:
|
||||||
issues, issue, i List, create and update issues
|
issues, issue, i List, create and update issues
|
||||||
pulls, pull, pr Manage and checkout pull requests
|
pulls, pull, pr Manage and checkout pull requests
|
||||||
labels, label Manage issue labels
|
labels, label Manage issue labels
|
||||||
milestones, milestone, ms List and create milestones
|
milestones, milestone, ms List and create milestones
|
||||||
releases, release, r Manage releases
|
releases, release, r Manage releases
|
||||||
times, time, t Operate on tracked times of a repository's issues & pulls
|
release assets, release asset, r a Manage release attachments
|
||||||
organizations, organization, org List, create, delete organizations
|
times, time, t Operate on tracked times of a repository's issues & pulls
|
||||||
repos, repo Show repository details
|
organizations, organization, org List, create, delete organizations
|
||||||
comment, c Add a comment to an issue / pr
|
repos, repo Show repository details
|
||||||
|
comment, c Add a comment to an issue / pr
|
||||||
HELPERS:
|
HELPERS:
|
||||||
open, o Open something of the repository in web browser
|
open, o Open something of the repository in web browser
|
||||||
notifications, notification, n Show notifications
|
notifications, notification, n Show notifications
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/tea/cmd/attachments"
|
||||||
|
"code.gitea.io/tea/cmd/flags"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdReleaseAttachments represents a release attachment (file attachment)
|
||||||
|
var CmdReleaseAttachments = cli.Command{
|
||||||
|
Name: "assets",
|
||||||
|
Aliases: []string{"asset", "a"},
|
||||||
|
Category: catEntities,
|
||||||
|
Usage: "Manage release assets",
|
||||||
|
Description: "Manage release assets",
|
||||||
|
ArgsUsage: " ", // command does not accept arguments
|
||||||
|
Action: attachments.RunReleaseAttachmentList,
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
&attachments.CmdReleaseAttachmentList,
|
||||||
|
&attachments.CmdReleaseAttachmentCreate,
|
||||||
|
&attachments.CmdReleaseAttachmentDelete,
|
||||||
|
},
|
||||||
|
Flags: flags.AllDefaultFlags,
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package attachments
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"code.gitea.io/tea/cmd/flags"
|
||||||
|
"code.gitea.io/tea/modules/context"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdReleaseAttachmentCreate represents a sub command of Release Attachments to create a release attachment
|
||||||
|
var CmdReleaseAttachmentCreate = cli.Command{
|
||||||
|
Name: "create",
|
||||||
|
Aliases: []string{"c"},
|
||||||
|
Usage: "Create one or more release attachments",
|
||||||
|
Description: `Create one or more release attachments`,
|
||||||
|
ArgsUsage: "<release-tag> <asset> [<asset>...]",
|
||||||
|
Action: runReleaseAttachmentCreate,
|
||||||
|
Flags: flags.AllDefaultFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runReleaseAttachmentCreate(cmd *cli.Context) error {
|
||||||
|
ctx := context.InitCommand(cmd)
|
||||||
|
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||||
|
client := ctx.Login.Client()
|
||||||
|
|
||||||
|
if ctx.Args().Len() < 2 {
|
||||||
|
return fmt.Errorf("No release tag or assets specified.\nUsage:\t%s", ctx.Command.UsageText)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := ctx.Args().First()
|
||||||
|
if len(tag) == 0 {
|
||||||
|
return fmt.Errorf("Release tag needed to create attachment")
|
||||||
|
}
|
||||||
|
|
||||||
|
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, asset := range ctx.Args().Slice()[1:] {
|
||||||
|
var file *os.File
|
||||||
|
if file, err = os.Open(asset); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Base(asset)
|
||||||
|
|
||||||
|
if _, _, err = ctx.Login.Client().CreateReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, file, filePath); err != nil {
|
||||||
|
file.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package attachments
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/tea/cmd/flags"
|
||||||
|
"code.gitea.io/tea/modules/context"
|
||||||
|
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdReleaseAttachmentDelete represents a sub command of Release Attachments to delete a release attachment
|
||||||
|
var CmdReleaseAttachmentDelete = cli.Command{
|
||||||
|
Name: "delete",
|
||||||
|
Aliases: []string{"rm"},
|
||||||
|
Usage: "Delete one or more release attachments",
|
||||||
|
Description: `Delete one or more release attachments`,
|
||||||
|
ArgsUsage: "<release tag> <attachment name> [<attachment name>...]",
|
||||||
|
Action: runReleaseAttachmentDelete,
|
||||||
|
Flags: append([]cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "confirm",
|
||||||
|
Aliases: []string{"y"},
|
||||||
|
Usage: "Confirm deletion (required)",
|
||||||
|
},
|
||||||
|
}, flags.AllDefaultFlags...),
|
||||||
|
}
|
||||||
|
|
||||||
|
func runReleaseAttachmentDelete(cmd *cli.Context) error {
|
||||||
|
ctx := context.InitCommand(cmd)
|
||||||
|
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||||
|
client := ctx.Login.Client()
|
||||||
|
|
||||||
|
if ctx.Args().Len() < 2 {
|
||||||
|
return fmt.Errorf("No release tag or attachment names specified.\nUsage:\t%s", ctx.Command.UsageText)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := ctx.Args().First()
|
||||||
|
if len(tag) == 0 {
|
||||||
|
return fmt.Errorf("Release tag needed to delete attachment")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ctx.Bool("confirm") {
|
||||||
|
fmt.Println("Are you sure? Please confirm with -y or --confirm.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
existing, _, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||||
|
ListOptions: gitea.ListOptions{Page: -1},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range ctx.Args().Slice()[1:] {
|
||||||
|
var attachment *gitea.Attachment
|
||||||
|
for _, a := range existing {
|
||||||
|
if a.Name == name {
|
||||||
|
attachment = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if attachment == nil {
|
||||||
|
return fmt.Errorf("Release does not have attachment named '%s'", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.DeleteReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, attachment.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getReleaseAttachmentByName(owner, repo string, release int64, name string, client *gitea.Client) (*gitea.Attachment, error) {
|
||||||
|
al, _, err := client.ListReleaseAttachments(owner, repo, release, gitea.ListReleaseAttachmentsOptions{
|
||||||
|
ListOptions: gitea.ListOptions{Page: -1},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(al) == 0 {
|
||||||
|
return nil, fmt.Errorf("Release does not have any attachments")
|
||||||
|
}
|
||||||
|
for _, a := range al {
|
||||||
|
if a.Name == name {
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Attachment does not exist")
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package attachments
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/tea/cmd/flags"
|
||||||
|
"code.gitea.io/tea/modules/context"
|
||||||
|
"code.gitea.io/tea/modules/print"
|
||||||
|
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdReleaseAttachmentList represents a sub command of release attachment to list release attachments
|
||||||
|
var CmdReleaseAttachmentList = cli.Command{
|
||||||
|
Name: "list",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
|
Usage: "List Release Attachments",
|
||||||
|
Description: "List Release Attachments",
|
||||||
|
ArgsUsage: "<release-tag>", // command does not accept arguments
|
||||||
|
Action: RunReleaseAttachmentList,
|
||||||
|
Flags: append([]cli.Flag{
|
||||||
|
&flags.PaginationPageFlag,
|
||||||
|
&flags.PaginationLimitFlag,
|
||||||
|
}, flags.AllDefaultFlags...),
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunReleaseAttachmentList list release attachments
|
||||||
|
func RunReleaseAttachmentList(cmd *cli.Context) error {
|
||||||
|
ctx := context.InitCommand(cmd)
|
||||||
|
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
||||||
|
client := ctx.Login.Client()
|
||||||
|
|
||||||
|
tag := ctx.Args().First()
|
||||||
|
if len(tag) == 0 {
|
||||||
|
return fmt.Errorf("Release tag needed to list attachments")
|
||||||
|
}
|
||||||
|
|
||||||
|
release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
attachments, _, err := ctx.Login.Client().ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
|
||||||
|
ListOptions: ctx.GetListOptions(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
print.ReleaseAttachmentsList(attachments, ctx.Output)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) {
|
||||||
|
rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{
|
||||||
|
ListOptions: gitea.ListOptions{Page: -1},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(rl) == 0 {
|
||||||
|
return nil, fmt.Errorf("Repo does not have any release")
|
||||||
|
}
|
||||||
|
for _, r := range rl {
|
||||||
|
if r.TagName == tag {
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Release tag does not exist")
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ var CmdReleases = cli.Command{
|
||||||
&releases.CmdReleaseCreate,
|
&releases.CmdReleaseCreate,
|
||||||
&releases.CmdReleaseDelete,
|
&releases.CmdReleaseDelete,
|
||||||
&releases.CmdReleaseEdit,
|
&releases.CmdReleaseEdit,
|
||||||
|
&CmdReleaseAttachments,
|
||||||
},
|
},
|
||||||
Flags: flags.AllDefaultFlags,
|
Flags: flags.AllDefaultFlags,
|
||||||
}
|
}
|
||||||
|
|
54
docs/CLI.md
54
docs/CLI.md
|
@ -789,6 +789,60 @@ Edit one or more releases
|
||||||
|
|
||||||
**--title, -t**="": Change Title
|
**--title, -t**="": Change Title
|
||||||
|
|
||||||
|
### assets, asset, a
|
||||||
|
|
||||||
|
Manage release assets
|
||||||
|
|
||||||
|
**--login, -l**="": Use a different Gitea Login. Optional
|
||||||
|
|
||||||
|
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||||
|
|
||||||
|
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||||
|
|
||||||
|
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||||
|
|
||||||
|
#### list, ls
|
||||||
|
|
||||||
|
List Release Attachments
|
||||||
|
|
||||||
|
**--limit, --lm**="": specify limit of items per page
|
||||||
|
|
||||||
|
**--login, -l**="": Use a different Gitea Login. Optional
|
||||||
|
|
||||||
|
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||||
|
|
||||||
|
**--page, -p**="": specify page, default is 1
|
||||||
|
|
||||||
|
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||||
|
|
||||||
|
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||||
|
|
||||||
|
#### create, c
|
||||||
|
|
||||||
|
Create one or more release attachments
|
||||||
|
|
||||||
|
**--login, -l**="": Use a different Gitea Login. Optional
|
||||||
|
|
||||||
|
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||||
|
|
||||||
|
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||||
|
|
||||||
|
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||||
|
|
||||||
|
#### delete, rm
|
||||||
|
|
||||||
|
Delete one or more release attachments
|
||||||
|
|
||||||
|
**--confirm, -y**: Confirm deletion (required)
|
||||||
|
|
||||||
|
**--login, -l**="": Use a different Gitea Login. Optional
|
||||||
|
|
||||||
|
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
|
||||||
|
|
||||||
|
**--remote, -R**="": Discover Gitea login from remote. Optional
|
||||||
|
|
||||||
|
**--repo, -r**="": Override local repository path or gitea repository slug to interact with. Optional
|
||||||
|
|
||||||
## times, time, t
|
## times, time, t
|
||||||
|
|
||||||
Operate on tracked times of a repository's issues & pulls
|
Operate on tracked times of a repository's issues & pulls
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package print
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReleaseAttachmentsList prints a listing of release attachments
|
||||||
|
func ReleaseAttachmentsList(attachments []*gitea.Attachment, output string) {
|
||||||
|
t := tableWithHeader(
|
||||||
|
"Name",
|
||||||
|
"Size",
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, attachment := range attachments {
|
||||||
|
t.addRow(
|
||||||
|
attachment.Name,
|
||||||
|
formatSize(attachment.Size),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.print(output)
|
||||||
|
}
|
Loading…
Reference in New Issue