Add --verify-tag to release edit command (#7646)
This commit is contained in:
parent
3dd3fb0319
commit
0d8c34bf59
7 changed files with 71 additions and 12 deletions
|
|
@ -157,6 +157,7 @@ func Test_deleteAssetRun(t *testing.T) {
|
|||
ios.SetStderrTTY(tt.isTTY)
|
||||
|
||||
fakeHTTP := &httpmock.Registry{}
|
||||
defer fakeHTTP.Verify(t)
|
||||
shared.StubFetchRelease(t, fakeHTTP, "OWNER", "REPO", tt.opts.TagName, `{
|
||||
"tag_name": "v1.2.3",
|
||||
"draft": false,
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ func Test_downloadRun_cloberAndSkip(t *testing.T) {
|
|||
tt.opts.IO = ios
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
// defer reg.Verify(t) // FIXME: intermittetly fails due to StubFetchRelease internals
|
||||
defer reg.Verify(t)
|
||||
shared.StubFetchRelease(t, reg, "OWNER", "REPO", "v1.2.3", `{
|
||||
"assets": [
|
||||
{ "name": "windows-64bit.zip", "size": 34,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type EditOptions struct {
|
|||
Draft *bool
|
||||
Prerelease *bool
|
||||
IsLatest *bool
|
||||
VerifyTag bool
|
||||
}
|
||||
|
||||
func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command {
|
||||
|
|
@ -81,6 +82,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
|
|||
cmd.Flags().StringVar(&opts.Target, "target", "", "Target `branch` or full commit SHA (default: main branch)")
|
||||
cmd.Flags().StringVar(&opts.TagName, "tag", "", "The name of the tag")
|
||||
cmd.Flags().StringVarP(¬esFile, "notes-file", "F", "", "Read release notes from `file` (use \"-\" to read from standard input)")
|
||||
cmd.Flags().BoolVar(&opts.VerifyTag, "verify-tag", false, "Abort in case the git tag doesn't already exist in the remote repository")
|
||||
|
||||
_ = cmdutil.RegisterBranchCompletionFlags(f.GitClient, cmd, "target")
|
||||
|
||||
|
|
@ -110,6 +112,17 @@ func editRun(tag string, opts *EditOptions) error {
|
|||
params["tag_name"] = release.TagName
|
||||
}
|
||||
|
||||
if opts.VerifyTag && opts.TagName != "" {
|
||||
remoteTagPresent, err := remoteTagExists(httpClient, baseRepo, opts.TagName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !remoteTagPresent {
|
||||
return fmt.Errorf("tag %s doesn't exist in the repo %s, aborting due to --verify-tag flag",
|
||||
opts.TagName, ghrepo.FullName(baseRepo))
|
||||
}
|
||||
}
|
||||
|
||||
editedRelease, err := editRelease(httpClient, baseRepo, release.DatabaseID, params)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -140,6 +140,15 @@ func Test_NewCmdEdit(t *testing.T) {
|
|||
Body: stringPtr("MY NOTES"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "verify-tag",
|
||||
args: "v1.2.0 --tag=v1.1.0 --verify-tag",
|
||||
isTTY: false,
|
||||
want: EditOptions{
|
||||
TagName: "v1.1.0",
|
||||
VerifyTag: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -189,6 +198,7 @@ func Test_NewCmdEdit(t *testing.T) {
|
|||
assert.Equal(t, tt.want.Draft, opts.Draft)
|
||||
assert.Equal(t, tt.want.Prerelease, opts.Prerelease)
|
||||
assert.Equal(t, tt.want.IsLatest, opts.IsLatest)
|
||||
assert.Equal(t, tt.want.VerifyTag, opts.VerifyTag)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -406,6 +416,21 @@ func Test_editRun(t *testing.T) {
|
|||
wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n",
|
||||
wantStderr: "",
|
||||
},
|
||||
{
|
||||
name: "error when remote tag does not exist and verify-tag flag is set",
|
||||
isTTY: true,
|
||||
opts: EditOptions{
|
||||
TagName: "v1.2.4",
|
||||
VerifyTag: true,
|
||||
},
|
||||
httpStubs: func(t *testing.T, reg *httpmock.Registry) {
|
||||
reg.Register(httpmock.GraphQL("RepositoryFindRef"),
|
||||
httpmock.StringResponse(`{"data":{"repository":{"ref": {"id": ""}}}}`))
|
||||
},
|
||||
wantErr: "tag v1.2.4 doesn't exist in the repo OWNER/REPO, aborting due to --verify-tag flag",
|
||||
wantStdout: "",
|
||||
wantStderr: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -416,7 +441,7 @@ func Test_editRun(t *testing.T) {
|
|||
ios.SetStderrTTY(tt.isTTY)
|
||||
|
||||
fakeHTTP := &httpmock.Registry{}
|
||||
// defer reg.Verify(t) // FIXME: intermittetly fails due to StubFetchRelease internals
|
||||
defer fakeHTTP.Verify(t)
|
||||
shared.StubFetchRelease(t, fakeHTTP, "OWNER", "REPO", "v1.2.3", `{
|
||||
"id": 12345,
|
||||
"tag_name": "v1.2.3"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cli/cli/v2/internal/ghinstance"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/cmd/release/shared"
|
||||
"github.com/shurcooL/githubv4"
|
||||
)
|
||||
|
||||
func editRelease(httpClient *http.Client, repo ghrepo.Interface, releaseID int64, params map[string]interface{}) (*shared.Release, error) {
|
||||
|
|
@ -48,3 +49,22 @@ func editRelease(httpClient *http.Client, repo ghrepo.Interface, releaseID int64
|
|||
err = json.Unmarshal(b, &newRelease)
|
||||
return &newRelease, err
|
||||
}
|
||||
|
||||
func remoteTagExists(httpClient *http.Client, repo ghrepo.Interface, tagName string) (bool, error) {
|
||||
gql := api.NewClientFromHTTP(httpClient)
|
||||
qualifiedTagName := fmt.Sprintf("refs/tags/%s", tagName)
|
||||
var query struct {
|
||||
Repository struct {
|
||||
Ref struct {
|
||||
ID string
|
||||
} `graphql:"ref(qualifiedName: $tagName)"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
variables := map[string]interface{}{
|
||||
"owner": githubv4.String(repo.RepoOwner()),
|
||||
"name": githubv4.String(repo.RepoName()),
|
||||
"tagName": githubv4.String(qualifiedTagName),
|
||||
}
|
||||
err := gql.Query(repo.RepoHost(), "RepositoryFindRef", &query, variables)
|
||||
return query.Repository.Ref.ID != "", err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cli/cli/v2/api"
|
||||
|
|
@ -224,11 +225,7 @@ func fetchReleasePath(ctx context.Context, httpClient *http.Client, host string,
|
|||
return &release, nil
|
||||
}
|
||||
|
||||
type testingT interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
func StubFetchRelease(t testingT, reg *httpmock.Registry, owner, repoName, tagName, responseBody string) {
|
||||
func StubFetchRelease(t *testing.T, reg *httpmock.Registry, owner, repoName, tagName, responseBody string) {
|
||||
path := "repos/OWNER/REPO/releases/tags/v1.2.3"
|
||||
if tagName == "" {
|
||||
path = "repos/OWNER/REPO/releases/latest"
|
||||
|
|
@ -239,10 +236,12 @@ func StubFetchRelease(t testingT, reg *httpmock.Registry, owner, repoName, tagNa
|
|||
if tagName != "" {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`query RepositoryReleaseByTag\b`),
|
||||
httpmock.GraphQLQuery(`{ "data": { "repository": { "release": null }}}`, func(q string, vars map[string]interface{}) {
|
||||
assert.Equal(t, owner, vars["owner"])
|
||||
assert.Equal(t, repoName, vars["name"])
|
||||
assert.Equal(t, tagName, vars["tagName"])
|
||||
}))
|
||||
httpmock.GraphQLQuery(`{ "data": { "repository": { "release": null }}}`,
|
||||
func(q string, vars map[string]interface{}) {
|
||||
assert.Equal(t, owner, vars["owner"])
|
||||
assert.Equal(t, repoName, vars["name"])
|
||||
assert.Equal(t, tagName, vars["tagName"])
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ func Test_viewRun(t *testing.T) {
|
|||
ios.SetStderrTTY(tt.isTTY)
|
||||
|
||||
fakeHTTP := &httpmock.Registry{}
|
||||
defer fakeHTTP.Verify(t)
|
||||
shared.StubFetchRelease(t, fakeHTTP, "OWNER", "REPO", tt.opts.TagName, fmt.Sprintf(`{
|
||||
"tag_name": "v1.2.3",
|
||||
"draft": false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue