Delete local tag when running gh release delete --cleanup-tag (#7884)
This commit is contained in:
parent
925473eeb1
commit
ba60f89f42
4 changed files with 83 additions and 9 deletions
|
|
@ -322,6 +322,19 @@ func (c *Client) ReadBranchConfig(ctx context.Context, branch string) (cfg Branc
|
|||
return
|
||||
}
|
||||
|
||||
func (c *Client) DeleteLocalTag(ctx context.Context, tag string) error {
|
||||
args := []string{"tag", "-d", tag}
|
||||
cmd, err := c.Command(ctx, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) DeleteLocalBranch(ctx context.Context, branch string) error {
|
||||
args := []string{"branch", "-D", branch}
|
||||
cmd, err := c.Command(ctx, args...)
|
||||
|
|
|
|||
|
|
@ -558,6 +558,45 @@ func TestClientReadBranchConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestClientDeleteLocalTag(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmdExitStatus int
|
||||
cmdStdout string
|
||||
cmdStderr string
|
||||
wantCmdArgs string
|
||||
wantErrorMsg string
|
||||
}{
|
||||
{
|
||||
name: "delete local tag",
|
||||
wantCmdArgs: `path/to/git tag -d v1.0`,
|
||||
},
|
||||
{
|
||||
name: "git error",
|
||||
cmdExitStatus: 1,
|
||||
cmdStderr: "git error message",
|
||||
wantCmdArgs: `path/to/git tag -d v1.0`,
|
||||
wantErrorMsg: "failed to run git: git error message",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd, cmdCtx := createCommandContext(t, tt.cmdExitStatus, tt.cmdStdout, tt.cmdStderr)
|
||||
client := Client{
|
||||
GitPath: "path/to/git",
|
||||
commandContext: cmdCtx,
|
||||
}
|
||||
err := client.DeleteLocalTag(context.Background(), "v1.0")
|
||||
assert.Equal(t, tt.wantCmdArgs, strings.Join(cmd.Args[3:], " "))
|
||||
if tt.wantErrorMsg == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tt.wantErrorMsg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDeleteLocalBranch(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/git"
|
||||
"github.com/cli/cli/v2/internal/ghinstance"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/cmd/release/shared"
|
||||
|
|
@ -19,10 +20,12 @@ type iprompter interface {
|
|||
}
|
||||
|
||||
type DeleteOptions struct {
|
||||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Prompter iprompter
|
||||
HttpClient func() (*http.Client, error)
|
||||
GitClient *git.Client
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
RepoOverride string
|
||||
Prompter iprompter
|
||||
|
||||
TagName string
|
||||
SkipConfirm bool
|
||||
|
|
@ -33,6 +36,7 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
opts := &DeleteOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
GitClient: f.GitClient,
|
||||
Prompter: f.Prompter,
|
||||
}
|
||||
|
||||
|
|
@ -43,6 +47,7 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// support `-R, --repo` override
|
||||
opts.BaseRepo = f.BaseRepo
|
||||
opts.RepoOverride, _ = cmd.Flags().GetString("repo")
|
||||
|
||||
opts.TagName = args[0]
|
||||
|
||||
|
|
@ -93,12 +98,13 @@ func deleteRun(opts *DeleteOptions) error {
|
|||
}
|
||||
|
||||
var cleanupMessage string
|
||||
mustCleanupTag := opts.CleanupTag
|
||||
if mustCleanupTag {
|
||||
err = deleteTag(httpClient, baseRepo, release.TagName)
|
||||
if err != nil {
|
||||
if opts.CleanupTag {
|
||||
if err := deleteTag(httpClient, baseRepo, release.TagName); err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.RepoOverride == "" {
|
||||
_ = opts.GitClient.DeleteLocalTag(context.Background(), release.TagName)
|
||||
}
|
||||
cleanupMessage = " and tag"
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +114,7 @@ func deleteRun(opts *DeleteOptions) error {
|
|||
|
||||
iofmt := opts.IO.ColorScheme()
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted release%s %s\n", iofmt.SuccessIconWithColor(iofmt.Red), cleanupMessage, release.TagName)
|
||||
if !release.IsDraft && !mustCleanupTag {
|
||||
if !release.IsDraft && !opts.CleanupTag {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Note that the %s git tag still remains in the repository\n", iofmt.WarningIcon(), release.TagName)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/git"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/prompter"
|
||||
"github.com/cli/cli/v2/internal/run"
|
||||
"github.com/cli/cli/v2/pkg/cmd/release/shared"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/httpmock"
|
||||
|
|
@ -110,6 +112,7 @@ func Test_deleteRun(t *testing.T) {
|
|||
isTTY bool
|
||||
opts DeleteOptions
|
||||
prompterStubs func(*prompter.PrompterMock)
|
||||
runStubs func(*run.CommandStubber)
|
||||
wantErr string
|
||||
wantStdout string
|
||||
wantStderr string
|
||||
|
|
@ -164,6 +167,9 @@ func Test_deleteRun(t *testing.T) {
|
|||
SkipConfirm: true,
|
||||
CleanupTag: true,
|
||||
},
|
||||
runStubs: func(rs *run.CommandStubber) {
|
||||
rs.Register(`git tag -d v1.2.3`, 0, "")
|
||||
},
|
||||
wantStdout: ``,
|
||||
wantStderr: heredoc.Doc(`
|
||||
✓ Deleted release and tag v1.2.3
|
||||
|
|
@ -177,6 +183,9 @@ func Test_deleteRun(t *testing.T) {
|
|||
SkipConfirm: false,
|
||||
CleanupTag: true,
|
||||
},
|
||||
runStubs: func(rs *run.CommandStubber) {
|
||||
rs.Register(`git tag -d v1.2.3`, 0, "")
|
||||
},
|
||||
wantStdout: ``,
|
||||
wantStderr: ``,
|
||||
},
|
||||
|
|
@ -203,6 +212,12 @@ func Test_deleteRun(t *testing.T) {
|
|||
fakeHTTP.Register(httpmock.REST("DELETE", "repos/OWNER/REPO/releases/23456"), httpmock.StatusStringResponse(204, ""))
|
||||
fakeHTTP.Register(httpmock.REST("DELETE", "repos/OWNER/REPO/git/refs/tags/v1.2.3"), httpmock.StatusStringResponse(204, ""))
|
||||
|
||||
rs, teardown := run.Stub()
|
||||
defer teardown(t)
|
||||
if tt.runStubs != nil {
|
||||
tt.runStubs(rs)
|
||||
}
|
||||
|
||||
tt.opts.IO = ios
|
||||
tt.opts.Prompter = pm
|
||||
tt.opts.HttpClient = func() (*http.Client, error) {
|
||||
|
|
@ -211,6 +226,7 @@ func Test_deleteRun(t *testing.T) {
|
|||
tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
|
||||
return ghrepo.FromFullName("OWNER/REPO")
|
||||
}
|
||||
tt.opts.GitClient = &git.Client{GitPath: "some/path/git"}
|
||||
|
||||
err := deleteRun(&tt.opts)
|
||||
if tt.wantErr != "" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue