Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gh for openSUSE:Factory checked in 
at 2023-09-21 22:23:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gh (Old)
 and      /work/SRC/openSUSE:Factory/.gh.new.1770 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gh"

Thu Sep 21 22:23:33 2023 rev:38 rq:1112794 version:2.35.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/gh/gh.changes    2023-09-08 21:16:19.068136269 
+0200
+++ /work/SRC/openSUSE:Factory/.gh.new.1770/gh.changes  2023-09-21 
22:24:16.091521209 +0200
@@ -1,0 +2,18 @@
+Wed Sep 20 12:15:33 UTC 2023 - pdos...@suse.com
+
+- Update to version 2.35.0:
+  * Cleanup release create around new --notes-from-tag flag (#8016)
+  * Document when gh auth login writes oauth token to plain text (#7781)
+  * Show full permissions URL in `gh cs create` (#7983)
+  * build(deps): bump goreleaser/goreleaser-action from 4 to 5
+  * moved remoteTagExists under if NotesFromTag exists and added three tests
+  * Clarify list repo behavior (#7964)
+  * Reinforce not opening PRs without approval on an issue
+  * Delete local tag when running `gh release delete --cleanup-tag` (#7884)
+  * Add `--all` flag to `alias delete` command (#7900)
+  * Move homebrew bump fork to personal repo
+  * Revert "Add a test workflow for homebrew bump investigations (#7951)"
+  * Add a test workflow for homebrew bump investigations (#7951)
+  * Add `gh release create [<tag>] --notes-from-tag`
+
+-------------------------------------------------------------------

Old:
----
  cli-2.34.0.tar.gz

New:
----
  cli-2.35.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gh.spec ++++++
--- /var/tmp/diff_new_pack.skKXie/_old  2023-09-21 22:24:17.563574625 +0200
+++ /var/tmp/diff_new_pack.skKXie/_new  2023-09-21 22:24:17.563574625 +0200
@@ -19,7 +19,7 @@
 %define goflags "-buildmode=pie -trimpath -mod=vendor -modcacherw"
 %define sname cli
 Name:           gh
-Version:        2.34.0
+Version:        2.35.0
 Release:        0
 Summary:        The official CLI for GitHub
 License:        MIT
@@ -40,6 +40,7 @@
 Requires:       %{name} = %{version}
 Requires:       bash-completion
 Supplements:    (gh and bash-completion)
+BuildArch:      noarch
 
 %description bash-completion
 Bash command line completion support for %{name}.

++++++ _service ++++++
--- /var/tmp/diff_new_pack.skKXie/_old  2023-09-21 22:24:17.591575641 +0200
+++ /var/tmp/diff_new_pack.skKXie/_new  2023-09-21 22:24:17.595575787 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/cli/cli</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v2.34.0</param>
+    <param name="revision">v2.35.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>
@@ -16,7 +16,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="disabled">
-    <param name="archive">cli-2.34.0.tar.gz</param>
+    <param name="archive">cli-2.35.0.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.skKXie/_old  2023-09-21 22:24:17.611576367 +0200
+++ /var/tmp/diff_new_pack.skKXie/_new  2023-09-21 22:24:17.615576513 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/cli/cli</param>
-              <param 
name="changesrevision">e5f499f3012907f2191e85bb1d6fbfc16b71173f</param></service></servicedata>
+              <param 
name="changesrevision">94fbbdf9b5b81a433c8bb60cd16b8d179822d834</param></service></servicedata>
 (No newline at EOF)
 

++++++ cli-2.34.0.tar.gz -> cli-2.35.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/.github/CONTRIBUTING.md 
new/cli-2.35.0/.github/CONTRIBUTING.md
--- old/cli-2.34.0/.github/CONTRIBUTING.md      2023-09-06 09:46:43.000000000 
+0200
+++ new/cli-2.35.0/.github/CONTRIBUTING.md      2023-09-19 10:26:52.000000000 
+0200
@@ -16,6 +16,7 @@
 Please avoid:
 
 * Opening pull requests for issues marked `needs-design`, 
`needs-investigation`, or `blocked`.
+* Opening pull requests that haven't been approved for work in an issue
 * Adding installation instructions specifically for your OS/package manager.
 * Opening pull requests for any issue marked `core`. These issues require 
additional context from
   the core CLI team at GitHub and any external pull requests will not be 
accepted.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/.github/workflows/deployment.yml 
new/cli-2.35.0/.github/workflows/deployment.yml
--- old/cli-2.34.0/.github/workflows/deployment.yml     2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/.github/workflows/deployment.yml     2023-09-19 
10:26:52.000000000 +0200
@@ -40,7 +40,7 @@
         with:
           go-version: ${{ inputs.go_version }}
       - name: Install GoReleaser
-        uses: goreleaser/goreleaser-action@v4
+        uses: goreleaser/goreleaser-action@v5
         with:
           version: "~1.17.1"
           install-only: true
@@ -92,7 +92,7 @@
           security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s 
-k "$keychain_password" "$keychain"
           rm "$RUNNER_TEMP/cert.p12"
       - name: Install GoReleaser
-        uses: goreleaser/goreleaser-action@v4
+        uses: goreleaser/goreleaser-action@v5
         with:
           version: "~1.17.1"
           install-only: true
@@ -140,7 +140,7 @@
         env:
           CERT_CONTENTS: ${{ secrets.WINDOWS_CERT_PFX }}
       - name: Install GoReleaser
-        uses: goreleaser/goreleaser-action@v4
+        uses: goreleaser/goreleaser-action@v5
         with:
           version: "~1.17.1"
           install-only: true
@@ -342,6 +342,6 @@
           formula-name: gh
           formula-path: Formula/g/gh.rb
           tag-name: ${{ inputs.tag_name }}
-          push-to: cli/homebrew-core
+          push-to: williammartin/homebrew-core
         env:
           COMMITTER_TOKEN: ${{ secrets.HOMEBREW_PR_PAT }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/git/client.go new/cli-2.35.0/git/client.go
--- old/cli-2.34.0/git/client.go        2023-09-06 09:46:43.000000000 +0200
+++ new/cli-2.35.0/git/client.go        2023-09-19 10:26:52.000000000 +0200
@@ -322,6 +322,19 @@
        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...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/git/client_test.go 
new/cli-2.35.0/git/client_test.go
--- old/cli-2.34.0/git/client_test.go   2023-09-06 09:46:43.000000000 +0200
+++ new/cli-2.35.0/git/client_test.go   2023-09-19 10:26:52.000000000 +0200
@@ -558,6 +558,45 @@
        }
 }
 
+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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/internal/config/config.go 
new/cli-2.35.0/internal/config/config.go
--- old/cli-2.34.0/internal/config/config.go    2023-09-06 09:46:43.000000000 
+0200
+++ new/cli-2.35.0/internal/config/config.go    2023-09-19 10:26:52.000000000 
+0200
@@ -220,7 +220,7 @@
 // Login will set user, git protocol, and auth token for the given hostname.
 // If the encrypt option is specified it will first try to store the auth token
 // in encrypted storage and will fall back to the plain text config file.
-func (c *AuthConfig) Login(hostname, username, token, gitProtocol string, 
secureStorage bool) error {
+func (c *AuthConfig) Login(hostname, username, token, gitProtocol string, 
secureStorage bool) (bool, error) {
        var setErr error
        if secureStorage {
                if setErr = keyring.Set(keyringServiceName(hostname), "", 
token); setErr == nil {
@@ -228,8 +228,10 @@
                        _ = c.cfg.Remove([]string{hosts, hostname, oauthToken})
                }
        }
+       insecureStorageUsed := false
        if !secureStorage || setErr != nil {
                c.cfg.Set([]string{hosts, hostname, oauthToken}, token)
+               insecureStorageUsed = true
        }
        if username != "" {
                c.cfg.Set([]string{hosts, hostname, "user"}, username)
@@ -237,7 +239,7 @@
        if gitProtocol != "" {
                c.cfg.Set([]string{hosts, hostname, "git_protocol"}, 
gitProtocol)
        }
-       return ghConfig.Write(c.cfg)
+       return insecureStorageUsed, ghConfig.Write(c.cfg)
 }
 
 // Logout will remove user, git protocol, and auth token for the given 
hostname.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/alias/delete/delete.go 
new/cli-2.35.0/pkg/cmd/alias/delete/delete.go
--- old/cli-2.34.0/pkg/cmd/alias/delete/delete.go       2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/alias/delete/delete.go       2023-09-19 
10:26:52.000000000 +0200
@@ -2,6 +2,7 @@
 
 import (
        "fmt"
+       "sort"
 
        "github.com/cli/cli/v2/internal/config"
        "github.com/cli/cli/v2/pkg/cmdutil"
@@ -14,6 +15,7 @@
        IO     *iostreams.IOStreams
 
        Name string
+       All  bool
 }
 
 func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) 
*cobra.Command {
@@ -23,12 +25,19 @@
        }
 
        cmd := &cobra.Command{
-               Use:   "delete <alias>",
-               Short: "Delete an alias",
-               Args:  cobra.ExactArgs(1),
+               Use:   "delete {<alias> | --all}",
+               Short: "Delete set aliases",
+               Args:  cobra.MaximumNArgs(1),
                RunE: func(cmd *cobra.Command, args []string) error {
-                       opts.Name = args[0]
-
+                       if len(args) == 0 && !opts.All {
+                               return cmdutil.FlagErrorf("specify an alias to 
delete or `--all`")
+                       }
+                       if len(args) > 0 && opts.All {
+                               return cmdutil.FlagErrorf("cannot use `--all` 
with alias name")
+                       }
+                       if len(args) > 0 {
+                               opts.Name = args[0]
+                       }
                        if runF != nil {
                                return runF(opts)
                        }
@@ -36,6 +45,8 @@
                },
        }
 
+       cmd.Flags().BoolVar(&opts.All, "all", false, "Delete all aliases")
+
        return cmd
 }
 
@@ -47,25 +58,40 @@
 
        aliasCfg := cfg.Aliases()
 
-       expansion, err := aliasCfg.Get(opts.Name)
-       if err != nil {
-               return fmt.Errorf("no such alias %s", opts.Name)
-
+       aliases := make(map[string]string)
+       if opts.All {
+               aliases = aliasCfg.All()
+               if len(aliases) == 0 {
+                       return cmdutil.NewNoResultsError("no aliases 
configured")
+               }
+       } else {
+               expansion, err := aliasCfg.Get(opts.Name)
+               if err != nil {
+                       return fmt.Errorf("no such alias %s", opts.Name)
+               }
+               aliases[opts.Name] = expansion
+       }
+
+       for name := range aliases {
+               if err := aliasCfg.Delete(name); err != nil {
+                       return fmt.Errorf("failed to delete alias %s: %w", 
name, err)
+               }
        }
 
-       err = aliasCfg.Delete(opts.Name)
-       if err != nil {
-               return fmt.Errorf("failed to delete alias %s: %w", opts.Name, 
err)
-       }
-
-       err = cfg.Write()
-       if err != nil {
+       if err := cfg.Write(); err != nil {
                return err
        }
 
        if opts.IO.IsStdoutTTY() {
                cs := opts.IO.ColorScheme()
-               fmt.Fprintf(opts.IO.ErrOut, "%s Deleted alias %s; was %s\n", 
cs.SuccessIconWithColor(cs.Red), opts.Name, expansion)
+               keys := make([]string, 0, len(aliases))
+               for k := range aliases {
+                       keys = append(keys, k)
+               }
+               sort.Strings(keys)
+               for _, k := range keys {
+                       fmt.Fprintf(opts.IO.ErrOut, "%s Deleted alias %s; was 
%s\n", cs.SuccessIconWithColor(cs.Red), k, aliases[k])
+               }
        }
 
        return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/alias/delete/delete_test.go 
new/cli-2.35.0/pkg/cmd/alias/delete/delete_test.go
--- old/cli-2.34.0/pkg/cmd/alias/delete/delete_test.go  2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/alias/delete/delete_test.go  2023-09-19 
10:26:52.000000000 +0200
@@ -11,78 +11,174 @@
        "github.com/cli/cli/v2/pkg/iostreams"
        "github.com/google/shlex"
        "github.com/stretchr/testify/assert"
-       "github.com/stretchr/testify/require"
 )
 
-func TestAliasDelete(t *testing.T) {
-       _ = config.StubWriteConfig(t)
-
+func TestNewCmdDelete(t *testing.T) {
        tests := []struct {
-               name       string
-               config     string
-               cli        string
-               isTTY      bool
-               wantStdout string
-               wantStderr string
-               wantErr    string
+               name    string
+               input   string
+               output  DeleteOptions
+               wantErr bool
+               errMsg  string
        }{
                {
-                       name:       "no aliases",
-                       config:     "",
-                       cli:        "co",
-                       isTTY:      true,
-                       wantStdout: "",
-                       wantStderr: "",
-                       wantErr:    "no such alias co",
+                       name:    "no arguments",
+                       input:   "",
+                       wantErr: true,
+                       errMsg:  "specify an alias to delete or `--all`",
+               },
+               {
+                       name:  "specified alias",
+                       input: "co",
+                       output: DeleteOptions{
+                               Name: "co",
+                       },
+               },
+               {
+                       name:  "all flag",
+                       input: "--all",
+                       output: DeleteOptions{
+                               All: true,
+                       },
+               },
+               {
+                       name:    "specified alias and all flag",
+                       input:   "co --all",
+                       wantErr: true,
+                       errMsg:  "cannot use `--all` with alias name",
                },
                {
-                       name: "delete one",
+                       name:    "too many arguments",
+                       input:   "il co",
+                       wantErr: true,
+                       errMsg:  "accepts at most 1 arg(s), received 2",
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       ios, _, _, _ := iostreams.Test()
+                       f := &cmdutil.Factory{
+                               IOStreams: ios,
+                       }
+                       argv, err := shlex.Split(tt.input)
+                       assert.NoError(t, err)
+                       var gotOpts *DeleteOptions
+                       cmd := NewCmdDelete(f, func(opts *DeleteOptions) error {
+                               gotOpts = opts
+                               return nil
+                       })
+                       cmd.SetArgs(argv)
+                       cmd.SetIn(&bytes.Buffer{})
+                       cmd.SetOut(io.Discard)
+                       cmd.SetErr(io.Discard)
+                       _, err = cmd.ExecuteC()
+                       if tt.wantErr {
+                               assert.EqualError(t, err, tt.errMsg)
+                               return
+                       }
+                       assert.NoError(t, err)
+                       assert.Equal(t, tt.output.Name, gotOpts.Name)
+                       assert.Equal(t, tt.output.All, gotOpts.All)
+               })
+       }
+}
+
+func TestDeleteRun(t *testing.T) {
+       tests := []struct {
+               name        string
+               config      string
+               isTTY       bool
+               opts        *DeleteOptions
+               wantAliases map[string]string
+               wantStdout  string
+               wantStderr  string
+               wantErrMsg  string
+       }{
+               {
+                       name: "delete alias",
                        config: heredoc.Doc(`
                                aliases:
                                  il: issue list
                                  co: pr checkout
                        `),
-                       cli:        "co",
-                       isTTY:      true,
-                       wantStdout: "",
+                       isTTY: true,
+                       opts: &DeleteOptions{
+                               Name: "co",
+                               All:  false,
+                       },
+                       wantAliases: map[string]string{
+                               "il": "issue list",
+                       },
                        wantStderr: "✓ Deleted alias co; was pr checkout\n",
                },
+               {
+                       name: "delete all aliases",
+                       config: heredoc.Doc(`
+                               aliases:
+                                 il: issue list
+                                 co: pr checkout
+                       `),
+                       isTTY: true,
+                       opts: &DeleteOptions{
+                               All: true,
+                       },
+                       wantAliases: map[string]string{},
+                       wantStderr:  "✓ Deleted alias co; was pr 
checkout\n✓ Deleted alias il; was issue list\n",
+               },
+               {
+                       name: "delete alias that does not exist",
+                       config: heredoc.Doc(`
+                               aliases:
+                                 il: issue list
+                                 co: pr checkout
+                       `),
+                       isTTY: true,
+                       opts: &DeleteOptions{
+                               Name: "unknown",
+                       },
+                       wantAliases: map[string]string{
+                               "il": "issue list",
+                               "co": "pr checkout",
+                       },
+                       wantErrMsg: "no such alias unknown",
+               },
+               {
+                       name:  "delete all aliases when none exist",
+                       isTTY: true,
+                       opts: &DeleteOptions{
+                               All: true,
+                       },
+                       wantAliases: map[string]string{},
+                       wantErrMsg:  "no aliases configured",
+               },
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
-                       cfg := config.NewFromString(tt.config)
-
                        ios, _, stdout, stderr := iostreams.Test()
-                       ios.SetStdoutTTY(tt.isTTY)
                        ios.SetStdinTTY(tt.isTTY)
+                       ios.SetStdoutTTY(tt.isTTY)
                        ios.SetStderrTTY(tt.isTTY)
+                       tt.opts.IO = ios
 
-                       factory := &cmdutil.Factory{
-                               IOStreams: ios,
-                               Config: func() (config.Config, error) {
-                                       return cfg, nil
-                               },
+                       cfg := config.NewFromString(tt.config)
+                       tt.opts.Config = func() (config.Config, error) {
+                               return cfg, nil
                        }
 
-                       cmd := NewCmdDelete(factory, nil)
-
-                       argv, err := shlex.Split(tt.cli)
-                       require.NoError(t, err)
-                       cmd.SetArgs(argv)
-
-                       cmd.SetIn(&bytes.Buffer{})
-                       cmd.SetOut(io.Discard)
-                       cmd.SetErr(io.Discard)
-
-                       _, err = cmd.ExecuteC()
-                       if tt.wantErr != "" {
-                               assert.EqualError(t, err, tt.wantErr)
-                               return
+                       err := deleteRun(tt.opts)
+                       if tt.wantErrMsg != "" {
+                               assert.EqualError(t, err, tt.wantErrMsg)
+                               writeCalls := cfg.WriteCalls()
+                               assert.Equal(t, 0, len(writeCalls))
+                       } else {
+                               assert.NoError(t, err)
+                               writeCalls := cfg.WriteCalls()
+                               assert.Equal(t, 1, len(writeCalls))
                        }
-                       require.NoError(t, err)
 
                        assert.Equal(t, tt.wantStdout, stdout.String())
                        assert.Equal(t, tt.wantStderr, stderr.String())
+                       assert.Equal(t, tt.wantAliases, cfg.Aliases().All())
                })
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/auth/login/login.go 
new/cli-2.35.0/pkg/cmd/auth/login/login.go
--- old/cli-2.34.0/pkg/cmd/auth/login/login.go  2023-09-06 09:46:43.000000000 
+0200
+++ new/cli-2.35.0/pkg/cmd/auth/login/login.go  2023-09-19 10:26:52.000000000 
+0200
@@ -58,7 +58,9 @@
                        Authenticate with a GitHub host.
 
                        The default authentication mode is a web-based browser 
flow. After completion, an
-                       authentication token will be stored internally.
+                       authentication token will be stored securely in the 
system credential store.
+                       If a credential store is not found or there is an issue 
using it gh will fallback to writing the token to a plain text file.
+                       See %[1]sgh auth status%[1]s for its stored location.
 
                        Alternatively, use %[1]s--with-token%[1]s to pass in a 
token on standard input.
                        The minimum required scopes for the token are: "repo", 
"read:org".
@@ -172,7 +174,8 @@
                        return fmt.Errorf("error validating token: %w", err)
                }
                // Adding a user key ensures that a nonempty host section gets 
written to the config file.
-               return authCfg.Login(hostname, "x-access-token", opts.Token, 
opts.GitProtocol, !opts.InsecureStorage)
+               _, loginErr := authCfg.Login(hostname, "x-access-token", 
opts.Token, opts.GitProtocol, !opts.InsecureStorage)
+               return loginErr
        }
 
        existingToken, _ := authCfg.Token(hostname)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/auth/refresh/refresh.go 
new/cli-2.35.0/pkg/cmd/auth/refresh/refresh.go
--- old/cli-2.34.0/pkg/cmd/auth/refresh/refresh.go      2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/auth/refresh/refresh.go      2023-09-19 
10:26:52.000000000 +0200
@@ -48,7 +48,8 @@
                        if err != nil {
                                return err
                        }
-                       return authCfg.Login(hostname, username, token, "", 
secureStorage)
+                       _, loginErr := authCfg.Login(hostname, username, token, 
"", secureStorage)
+                       return loginErr
                },
                HttpClient: &http.Client{},
                GitClient:  f.GitClient,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/auth/shared/login_flow.go 
new/cli-2.35.0/pkg/cmd/auth/shared/login_flow.go
--- old/cli-2.34.0/pkg/cmd/auth/shared/login_flow.go    2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/auth/shared/login_flow.go    2023-09-19 
10:26:52.000000000 +0200
@@ -22,7 +22,7 @@
 const defaultSSHKeyTitle = "GitHub CLI"
 
 type iconfig interface {
-       Login(string, string, string, string, bool) error
+       Login(string, string, string, string, bool) (bool, error)
 }
 
 type LoginOptions struct {
@@ -188,9 +188,13 @@
                fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", 
cs.SuccessIcon())
        }
 
-       if err := cfg.Login(hostname, username, authToken, gitProtocol, 
opts.SecureStorage); err != nil {
+       insecureStorageUsed, err := cfg.Login(hostname, username, authToken, 
gitProtocol, opts.SecureStorage)
+       if err != nil {
                return err
        }
+       if insecureStorageUsed {
+               fmt.Fprintf(opts.IO.ErrOut, "%s Authentication credentials 
saved in plain text\n", cs.Yellow("!"))
+       }
 
        if credentialFlow.ShouldSetup() {
                err := credentialFlow.Setup(hostname, username, authToken)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/auth/shared/login_flow_test.go 
new/cli-2.35.0/pkg/cmd/auth/shared/login_flow_test.go
--- old/cli-2.34.0/pkg/cmd/auth/shared/login_flow_test.go       2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/auth/shared/login_flow_test.go       2023-09-19 
10:26:52.000000000 +0200
@@ -18,11 +18,11 @@
 
 type tinyConfig map[string]string
 
-func (c tinyConfig) Login(host, username, token, gitProtocol string, encrypt 
bool) error {
+func (c tinyConfig) Login(host, username, token, gitProtocol string, encrypt 
bool) (bool, error) {
        c[fmt.Sprintf("%s:%s", host, "user")] = username
        c[fmt.Sprintf("%s:%s", host, "oauth_token")] = token
        c[fmt.Sprintf("%s:%s", host, "git_protocol")] = gitProtocol
-       return nil
+       return false, nil
 }
 
 func TestLogin_ssh(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/codespace/create.go 
new/cli-2.35.0/pkg/cmd/codespace/create.go
--- old/cli-2.34.0/pkg/cmd/codespace/create.go  2023-09-06 09:46:43.000000000 
+0200
+++ new/cli-2.35.0/pkg/cmd/codespace/create.go  2023-09-19 10:26:52.000000000 
+0200
@@ -11,7 +11,6 @@
        "github.com/cli/cli/v2/internal/codespaces"
        "github.com/cli/cli/v2/internal/codespaces/api"
        "github.com/cli/cli/v2/internal/ghrepo"
-       "github.com/cli/cli/v2/internal/text"
        "github.com/cli/cli/v2/pkg/cmdutil"
        "github.com/spf13/cobra"
 )
@@ -336,13 +335,12 @@
        var (
                isInteractive = a.io.CanPrompt()
                cs            = a.io.ColorScheme()
-               displayURL    = text.DisplayURL(allowPermissionsURL)
        )
 
        fmt.Fprintf(a.io.ErrOut, "You must authorize or deny additional 
permissions requested by this codespace before continuing.\n")
 
        if !isInteractive {
-               fmt.Fprintf(a.io.ErrOut, "%s in your browser to review and 
authorize additional permissions: %s\n", cs.Bold("Open this URL"), displayURL)
+               fmt.Fprintf(a.io.ErrOut, "%s in your browser to review and 
authorize additional permissions: %s\n", cs.Bold("Open this URL"), 
allowPermissionsURL)
                fmt.Fprintf(a.io.ErrOut, "Alternatively, you can run %q with 
the %q option to continue without authorizing additional permissions.\n", 
a.io.ColorScheme().Bold("create"), cs.Bold("--default-permissions"))
                return nil, cmdutil.SilentError
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/codespace/create_test.go 
new/cli-2.35.0/pkg/cmd/codespace/create_test.go
--- old/cli-2.34.0/pkg/cmd/codespace/create_test.go     2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/codespace/create_test.go     2023-09-19 
10:26:52.000000000 +0200
@@ -356,7 +356,39 @@
                        wantErr: cmdutil.SilentError,
                        wantStderr: `  ✓ Codespaces usage for this repository 
is paid for by monalisa
 You must authorize or deny additional permissions requested by this codespace 
before continuing.
-Open this URL in your browser to review and authorize additional permissions: 
example.com/permissions
+Open this URL in your browser to review and authorize additional permissions: 
https://example.com/permissions
+Alternatively, you can run "create" with the "--default-permissions" option to 
continue without authorizing additional permissions.
+`,
+               },
+               {
+                       name: "create codespace that requires accepting 
additional permissions for devcontainer path",
+                       fields: fields{
+                               apiClient: apiCreateDefaults(&apiClientMock{
+                                       CreateCodespaceFunc: func(ctx 
context.Context, params *api.CreateCodespaceParams) (*api.Codespace, error) {
+                                               if params.Branch != 
"feature-branch" {
+                                                       return nil, 
fmt.Errorf("got branch %q, want %q", params.Branch, "main")
+                                               }
+                                               if params.IdleTimeoutMinutes != 
30 {
+                                                       return nil, 
fmt.Errorf("idle timeout minutes was %v", params.IdleTimeoutMinutes)
+                                               }
+                                               return &api.Codespace{}, 
api.AcceptPermissionsRequiredError{
+                                                       AllowPermissionsURL: 
"https://example.com/permissions?ref=feature-branch&devcontainer_path=.devcontainer/actions/devcontainer.json";,
+                                               }
+                                       },
+                               }),
+                       },
+                       opts: createOptions{
+                               repo:             "monalisa/dotfiles",
+                               branch:           "feature-branch",
+                               devContainerPath: 
".devcontainer/actions/devcontainer.json",
+                               machine:          "GIGA",
+                               showStatus:       false,
+                               idleTimeout:      30 * time.Minute,
+                       },
+                       wantErr: cmdutil.SilentError,
+                       wantStderr: `  ✓ Codespaces usage for this repository 
is paid for by monalisa
+You must authorize or deny additional permissions requested by this codespace 
before continuing.
+Open this URL in your browser to review and authorize additional permissions: 
https://example.com/permissions?ref=feature-branch&devcontainer_path=.devcontainer/actions/devcontainer.json
 Alternatively, you can run "create" with the "--default-permissions" option to 
continue without authorizing additional permissions.
 `,
                },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/release/create/create.go 
new/cli-2.35.0/pkg/cmd/release/create/create.go
--- old/cli-2.34.0/pkg/cmd/release/create/create.go     2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/release/create/create.go     2023-09-19 
10:26:52.000000000 +0200
@@ -59,6 +59,7 @@
        GenerateNotes      bool
        NotesStartTag      string
        VerifyTag          bool
+       NotesFromTag       bool
 }
 
 func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) 
*cobra.Command {
@@ -92,6 +93,8 @@
 
                        To create a release from an annotated git tag, first 
create one locally with
                        git, push the tag to GitHub, then run this command.
+                       Use %[1]s--notes-from-tag%[1]s to automatically 
generate the release notes
+                       from the annotated git tag.
 
                        When using automatically generated release notes, a 
release title will also be automatically
                        generated unless a title was explicitly passed. 
Additional release notes can be prepended to
@@ -146,9 +149,17 @@
                                return cmdutil.FlagErrorf("tag required when 
not running interactively")
                        }
 
+                       if opts.NotesFromTag && (opts.GenerateNotes || 
opts.NotesStartTag != "") {
+                               return cmdutil.FlagErrorf("using 
`--notes-from-tag` with `--generate-notes` or `--notes-start-tag` is not 
supported")
+                       }
+
+                       if opts.NotesFromTag && opts.RepoOverride != "" {
+                               return cmdutil.FlagErrorf("using 
`--notes-from-tag` with `--repo` is not supported")
+                       }
+
                        opts.Concurrency = 5
 
-                       opts.BodyProvided = cmd.Flags().Changed("notes") || 
opts.GenerateNotes
+                       opts.BodyProvided = cmd.Flags().Changed("notes") || 
opts.GenerateNotes || opts.NotesFromTag
                        if notesFile != "" {
                                b, err := cmdutil.ReadFile(notesFile, 
opts.IO.In)
                                if err != nil {
@@ -176,6 +187,7 @@
        cmd.Flags().StringVar(&opts.NotesStartTag, "notes-start-tag", "", "Tag 
to use as the starting point for generating release notes")
        cmdutil.NilBoolFlag(cmd, &opts.IsLatest, "latest", "", "Mark this 
release as \"Latest\" (default: automatic based on date and version)")
        cmd.Flags().BoolVarP(&opts.VerifyTag, "verify-tag", "", false, "Abort 
in case the git tag doesn't already exist in the remote repository")
+       cmd.Flags().BoolVarP(&opts.NotesFromTag, "notes-from-tag", "", false, 
"Automatically generate notes from annotated tag")
 
        _ = cmdutil.RegisterBranchCompletionFlags(f.GitClient, cmd, "target")
 
@@ -241,6 +253,12 @@
        var tagDescription string
        if opts.RepoOverride == "" {
                tagDescription, _ = gitTagInfo(opts.GitClient, opts.TagName)
+
+               if opts.NotesFromTag && tagDescription == "" {
+                       return fmt.Errorf("cannot generate release notes from 
tag %s as it does not exist locally",
+                               opts.TagName)
+               }
+
                // If there is a local tag with the same name as specified
                // the user may not want to create a new tag on the remote
                // as the local one might be annotated or signed.
@@ -427,6 +445,13 @@
                        params["generate_release_notes"] = true
                }
        }
+       if opts.NotesFromTag {
+               if opts.Body == "" {
+                       params["body"] = tagDescription
+               } else {
+                       params["body"] = fmt.Sprintf("%s\n%s", opts.Body, 
tagDescription)
+               }
+       }
 
        hasAssets := len(opts.Assets) > 0
        draftWhileUploading := false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/release/create/create_test.go 
new/cli-2.35.0/pkg/cmd/release/create/create_test.go
--- old/cli-2.34.0/pkg/cmd/release/create/create_test.go        2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/release/create/create_test.go        2023-09-19 
10:26:52.000000000 +0200
@@ -321,6 +321,30 @@
                                VerifyTag:     true,
                        },
                },
+               {
+                       name:  "with --notes-from-tag",
+                       args:  "v1.2.3 --notes-from-tag",
+                       isTTY: false,
+                       want: CreateOptions{
+                               TagName:      "v1.2.3",
+                               BodyProvided: true,
+                               Concurrency:  5,
+                               Assets:       []*shared.AssetForUpload(nil),
+                               NotesFromTag: true,
+                       },
+               },
+               {
+                       name:    "with --notes-from-tag and --generate-notes",
+                       args:    "v1.2.3 --notes-from-tag --generate-notes",
+                       isTTY:   false,
+                       wantErr: "using `--notes-from-tag` with 
`--generate-notes` or `--notes-start-tag` is not supported",
+               },
+               {
+                       name:    "with --notes-from-tag and --notes-start-tag",
+                       args:    "v1.2.3 --notes-from-tag --notes-start-tag 
v1.2.3",
+                       isTTY:   false,
+                       wantErr: "using `--notes-from-tag` with 
`--generate-notes` or `--notes-start-tag` is not supported",
+               },
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
@@ -375,6 +399,7 @@
                        assert.Equal(t, tt.want.NotesStartTag, 
opts.NotesStartTag)
                        assert.Equal(t, tt.want.IsLatest, opts.IsLatest)
                        assert.Equal(t, tt.want.VerifyTag, opts.VerifyTag)
+                       assert.Equal(t, tt.want.NotesFromTag, opts.NotesFromTag)
 
                        require.Equal(t, len(tt.want.Assets), len(opts.Assets))
                        for i := range tt.want.Assets {
@@ -391,6 +416,7 @@
                isTTY      bool
                opts       CreateOptions
                httpStubs  func(t *testing.T, reg *httpmock.Registry)
+               runStubs   func(rs *run.CommandStubber)
                wantErr    string
                wantStdout string
                wantStderr string
@@ -405,6 +431,9 @@
                                BodyProvided: true,
                                Target:       "",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -434,6 +463,9 @@
                                Target:             "",
                                DiscussionCategory: "General",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -463,6 +495,9 @@
                                BodyProvided: true,
                                Target:       "main",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -491,6 +526,9 @@
                                Draft:        true,
                                Target:       "",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -519,6 +557,9 @@
                                BodyProvided:  true,
                                GenerateNotes: false,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -547,6 +588,9 @@
                                BodyProvided:  true,
                                GenerateNotes: true,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
                                        "url": 
"https://api.github.com/releases/123";,
@@ -576,6 +620,9 @@
                                GenerateNotes: true,
                                NotesStartTag: "v1.1.0",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases/generate-notes"),
                                        httpmock.RESTPayload(200, `{
@@ -616,6 +663,9 @@
                                GenerateNotes: true,
                                NotesStartTag: "v1.1.0",
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases/generate-notes"),
                                        httpmock.RESTPayload(200, `{
@@ -664,6 +714,9 @@
                                },
                                Concurrency: 1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, 
``))
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
@@ -721,6 +774,9 @@
                                },
                                Concurrency: 1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(200, 
``))
                        },
@@ -748,6 +804,9 @@
                                },
                                Concurrency: 1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, 
``))
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.StatusStringResponse(201, `{
@@ -782,6 +841,9 @@
                                },
                                Concurrency: 1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, 
``))
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.StatusStringResponse(201, `{
@@ -817,6 +879,9 @@
                                },
                                Concurrency: 1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(200, 
``))
                        },
@@ -845,6 +910,9 @@
                                DiscussionCategory: "general",
                                Concurrency:        1,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
                        httpStubs: func(t *testing.T, reg *httpmock.Registry) {
                                reg.Register(httpmock.REST("HEAD", 
"repos/OWNER/REPO/releases/tags/v1.2.3"), httpmock.StatusStringResponse(404, 
``))
                                reg.Register(httpmock.REST("POST", 
"repos/OWNER/REPO/releases"), httpmock.RESTPayload(201, `{
@@ -884,6 +952,94 @@
                        wantStdout: 
"https://github.com/OWNER/REPO/releases/tag/v1.2.3-final\n";,
                        wantStderr: ``,
                },
+               {
+                       name:  "with generate notes from tag",
+                       isTTY: false,
+                       opts: CreateOptions{
+                               TagName:      "v1.2.3",
+                               BodyProvided: true,
+                               Concurrency:  5,
+                               Assets:       []*shared.AssetForUpload(nil),
+                               NotesFromTag: true,
+                       },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "some tag 
message")
+                       },
+                       httpStubs: func(t *testing.T, reg *httpmock.Registry) {
+                               reg.Register(
+                                       httpmock.GraphQL("RepositoryFindRef"),
+                                       
httpmock.StringResponse(`{"data":{"repository":{"ref": {"id": "tag id"}}}}`),
+                               )
+                               reg.Register(
+                                       httpmock.REST("POST", 
"repos/OWNER/REPO/releases"),
+                                       httpmock.RESTPayload(201, `{
+                                               "url": 
"https://api.github.com/releases/123";,
+                                               "upload_url": 
"https://api.github.com/assets/upload";,
+                                               "html_url": 
"https://github.com/OWNER/REPO/releases/tag/v1.2.3";
+                                       }`, func(payload 
map[string]interface{}) {
+                                               assert.Equal(t, 
map[string]interface{}{
+                                                       "tag_name":   "v1.2.3",
+                                                       "draft":      false,
+                                                       "prerelease": false,
+                                                       "body":       "some tag 
message",
+                                               }, payload)
+                                       }))
+                       },
+                       wantStdout: 
"https://github.com/OWNER/REPO/releases/tag/v1.2.3\n";,
+                       wantStderr: "",
+               },
+               {
+                       name:  "with generate notes from tag and notes 
provided",
+                       isTTY: false,
+                       opts: CreateOptions{
+                               TagName:      "v1.2.3",
+                               Body:         "some notes here",
+                               BodyProvided: true,
+                               Concurrency:  5,
+                               Assets:       []*shared.AssetForUpload(nil),
+                               NotesFromTag: true,
+                       },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "some tag 
message")
+                       },
+                       httpStubs: func(t *testing.T, reg *httpmock.Registry) {
+                               reg.Register(
+                                       httpmock.GraphQL("RepositoryFindRef"),
+                                       
httpmock.StringResponse(`{"data":{"repository":{"ref": {"id": "tag id"}}}}`),
+                               )
+                               reg.Register(
+                                       httpmock.REST("POST", 
"repos/OWNER/REPO/releases"),
+                                       httpmock.RESTPayload(201, `{
+                                               "url": 
"https://api.github.com/releases/123";,
+                                               "upload_url": 
"https://api.github.com/assets/upload";,
+                                               "html_url": 
"https://github.com/OWNER/REPO/releases/tag/v1.2.3";
+                                       }`, func(payload 
map[string]interface{}) {
+                                               assert.Equal(t, 
map[string]interface{}{
+                                                       "tag_name":   "v1.2.3",
+                                                       "draft":      false,
+                                                       "prerelease": false,
+                                                       "body":       "some 
notes here\nsome tag message",
+                                               }, payload)
+                                       }))
+                       },
+                       wantStdout: 
"https://github.com/OWNER/REPO/releases/tag/v1.2.3\n";,
+                       wantStderr: "",
+               },
+               {
+                       name:  "with generate notes from tag and tag does not 
exist",
+                       isTTY: false,
+                       opts: CreateOptions{
+                               TagName:      "v1.2.3",
+                               BodyProvided: true,
+                               Concurrency:  5,
+                               Assets:       []*shared.AssetForUpload(nil),
+                               NotesFromTag: true,
+                       },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag --list`, 0, "")
+                       },
+                       wantErr: "cannot generate release notes from tag v1.2.3 
as it does not exist locally",
+               },
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
@@ -908,6 +1064,12 @@
 
                        tt.opts.GitClient = &git.Client{GitPath: 
"some/path/git"}
 
+                       rs, teardown := run.Stub()
+                       defer teardown(t)
+                       if tt.runStubs != nil {
+                               tt.runStubs(rs)
+                       }
+
                        err := createRun(&tt.opts)
                        if tt.wantErr != "" {
                                require.EqualError(t, err, tt.wantErr)
@@ -1451,34 +1613,34 @@
                },
        }
        for _, tt := range tests {
-               ios, _, stdout, stderr := iostreams.Test()
-               ios.SetStdoutTTY(true)
-               ios.SetStdinTTY(true)
-               ios.SetStderrTTY(true)
-               tt.opts.IO = ios
-
-               reg := &httpmock.Registry{}
-               defer reg.Verify(t)
-               tt.httpStubs(reg)
-               tt.opts.HttpClient = func() (*http.Client, error) {
-                       return &http.Client{Transport: reg}, nil
-               }
-
-               tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
-                       return ghrepo.FromFullName("OWNER/REPO")
-               }
-
-               tt.opts.Config = func() (config.Config, error) {
-                       return config.NewBlankConfig(), nil
-               }
-
-               tt.opts.Edit = func(_, _, val string, _ io.Reader, _, _ 
io.Writer) (string, error) {
-                       return val, nil
-               }
+               t.Run(tt.name, func(t *testing.T) {
+                       ios, _, stdout, stderr := iostreams.Test()
+                       ios.SetStdoutTTY(true)
+                       ios.SetStdinTTY(true)
+                       ios.SetStderrTTY(true)
+                       tt.opts.IO = ios
+
+                       reg := &httpmock.Registry{}
+                       defer reg.Verify(t)
+                       tt.httpStubs(reg)
+                       tt.opts.HttpClient = func() (*http.Client, error) {
+                               return &http.Client{Transport: reg}, nil
+                       }
 
-               tt.opts.GitClient = &git.Client{GitPath: "some/path/git"}
+                       tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
+                               return ghrepo.FromFullName("OWNER/REPO")
+                       }
+
+                       tt.opts.Config = func() (config.Config, error) {
+                               return config.NewBlankConfig(), nil
+                       }
+
+                       tt.opts.Edit = func(_, _, val string, _ io.Reader, _, _ 
io.Writer) (string, error) {
+                               return val, nil
+                       }
+
+                       tt.opts.GitClient = &git.Client{GitPath: 
"some/path/git"}
 
-               t.Run(tt.name, func(t *testing.T) {
                        pm := prompter.NewMockPrompter(t)
                        if tt.prompterStubs != nil {
                                tt.prompterStubs(t, pm)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/release/delete/delete.go 
new/cli-2.35.0/pkg/cmd/release/delete/delete.go
--- old/cli-2.34.0/pkg/cmd/release/delete/delete.go     2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/release/delete/delete.go     2023-09-19 
10:26:52.000000000 +0200
@@ -6,6 +6,7 @@
        "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 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 @@
        opts := &DeleteOptions{
                IO:         f.IOStreams,
                HttpClient: f.HttpClient,
+               GitClient:  f.GitClient,
                Prompter:   f.Prompter,
        }
 
@@ -43,6 +47,7 @@
                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 @@
        }
 
        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 @@
 
        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)
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/release/delete/delete_test.go 
new/cli-2.35.0/pkg/cmd/release/delete/delete_test.go
--- old/cli-2.34.0/pkg/cmd/release/delete/delete_test.go        2023-09-06 
09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/cmd/release/delete/delete_test.go        2023-09-19 
10:26:52.000000000 +0200
@@ -7,8 +7,10 @@
        "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 @@
                isTTY         bool
                opts          DeleteOptions
                prompterStubs func(*prompter.PrompterMock)
+               runStubs      func(*run.CommandStubber)
                wantErr       string
                wantStdout    string
                wantStderr    string
@@ -164,6 +167,9 @@
                                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 @@
                                SkipConfirm: false,
                                CleanupTag:  true,
                        },
+                       runStubs: func(rs *run.CommandStubber) {
+                               rs.Register(`git tag -d v1.2.3`, 0, "")
+                       },
                        wantStdout: ``,
                        wantStderr: ``,
                },
@@ -203,6 +212,12 @@
                        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 @@
                        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 != "" {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/cmd/repo/list/list.go 
new/cli-2.35.0/pkg/cmd/repo/list/list.go
--- old/cli-2.34.0/pkg/cmd/repo/list/list.go    2023-09-06 09:46:43.000000000 
+0200
+++ new/cli-2.35.0/pkg/cmd/repo/list/list.go    2023-09-19 10:26:52.000000000 
+0200
@@ -6,6 +6,7 @@
        "strings"
        "time"
 
+       "github.com/MakeNowJust/heredoc"
        "github.com/spf13/cobra"
 
        "github.com/cli/cli/v2/api"
@@ -52,9 +53,16 @@
        )
 
        cmd := &cobra.Command{
-               Use:     "list [<owner>]",
-               Args:    cobra.MaximumNArgs(1),
-               Short:   "List repositories owned by user or organization",
+               Use:   "list [<owner>]",
+               Args:  cobra.MaximumNArgs(1),
+               Short: "List repositories owned by user or organization",
+               Long: heredoc.Docf(`
+                       List repositories owned by a user or organization.
+
+                       Note that the list will only include repositories owned 
by the provided argument,
+                       and the %[1]s--fork%[1]s or %[1]s--source%[1]s flags 
will not traverse ownership boundaries. For example,
+                       when listing the forks in an organization, the output 
would not include those owned by individual users.
+               `, "`"),
                Aliases: []string{"ls"},
                RunE: func(c *cobra.Command, args []string) error {
                        if opts.Limit < 1 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.34.0/pkg/httpmock/stub.go 
new/cli-2.35.0/pkg/httpmock/stub.go
--- old/cli-2.34.0/pkg/httpmock/stub.go 2023-09-06 09:46:43.000000000 +0200
+++ new/cli-2.35.0/pkg/httpmock/stub.go 2023-09-19 10:26:52.000000000 +0200
@@ -181,6 +181,7 @@
                return httpResponse(responseStatus, req, 
bytes.NewBufferString(responseBody)), nil
        }
 }
+
 func GraphQLMutation(body string, cb func(map[string]interface{})) Responder {
        return func(req *http.Request) (*http.Response, error) {
                var bodyData struct {

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/gh/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.gh.new.1770/vendor.tar.gz differ: char 5, line 1

Reply via email to