Merge branch 'trunk' into bagtoad/cli-8946-list-licenses-and-gitignore-options

This commit is contained in:
Kynan Ware 2024-10-06 14:01:58 -06:00 committed by GitHub
commit 04ed1ed1a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 202 additions and 44 deletions

View file

@ -6,9 +6,10 @@ We accept pull requests for bug fixes and features where we've discussed the app
Please do:
* Check existing issues to verify that the [bug][bug issues] or [feature request][feature request issues] has not already been submitted.
* Check existing issues to verify that an existing [bug][bug issues] or [feature request][feature request issues] issue does not already exist for the same problem or feature.
* Open an issue if things aren't working as expected.
* Open an issue to propose a significant change.
* Open an issue to propose a design for an issue labelled [`needs-design` and `help wanted`][needs design and help wanted], following the [proposing a design guidelines](#proposing-a-design) instructions below.
* Open a pull request to fix a bug.
* Open a pull request to fix documentation about a command.
* Open a pull request for any issue labelled [`help wanted`][hw] or [`good first issue`][gfi].
@ -52,7 +53,21 @@ We generate manual pages from source on every release. You do not need to submit
## Design guidelines
You may reference the [CLI Design System][] when suggesting features, and are welcome to use our [Google Docs Template][] to suggest designs.
### Proposing a design
You may propose a design to solve an open bug or feature request issue that has both [the `needs-design` and `help-wanted` labels][needs design and help wanted].
To propose a design:
- Open a new issue using the [design proposal issue template](./ISSUE_TEMPLATE/submit-a-design-proposal.md).
- Include a link to the issue that the design is for.
- Describe the design you are proposing to resolve the issue, leveraging the [CLI Design System][].
- Mock up the design you are proposing using our [Google Docs Template][] or code blocks.
- Mock ups should cleary illustrate the command(s) being run and the expected output(s).
### (core team only) Revewing a design
A member of the core team will [triage](../docs/triage.md) the design proposal. Once a member of the core team has reviewed the design, they may add the [`help wanted`][hw] label to the issue, so a PR can be opened to provide the implementation.
## Resources
@ -62,6 +77,7 @@ You may reference the [CLI Design System][] when suggesting features, and are we
[bug issues]: https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+label%3Abug
[needs design and help wanted]: https://github.com/cli/cli/issues?q=state%3Aclosed%20is%3Aissue%20label%3Aneeds-design%20label%3A%22help%20wanted%22
[feature request issues]: https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement
[hw]: https://github.com/cli/cli/labels/help%20wanted
[gfi]: https://github.com/cli/cli/labels/good%20first%20issue

View file

@ -0,0 +1,58 @@
---
name: "🎨 Submit a design proposal"
about: Submit a design to resolve an open issue that has both `needs-design` and `help-wanted` labels
title: ''
labels: enhancement
assignees: ''
---
<!-- See [CONTRIBUTING.md](../CONTRIBUTING.md#proposing-a-design) for more information.-->
### Link to issue for design submission
<!--
Provide a link to the issue this design is for.
All design submissions must be linked to an open issue that
has both the `needs-design` and `help-wanted` labels.
-->
### Proposed Design
<!--
Describe the design you are proposing to resolve the issue.
All CLI designs must adhere to the [Primer CLI design reference](https://primer.style/cli/).
-->
### Mockup
<!--
Provide a mockup of the design you are proposing. All mockups should clearly illustrate the command(s) being run and the expected output(s).
When color and formatting are important, consider using our [CLI design Google Docs Template](https://docs.google.com/document/d/1JIRErIUuJ6fTgabiFYfCH3x91pyHuytbfa0QLnTfXKM/edit#heading=h.or54sa47ylpg).
Code blocks can also be used to submit a design mockup - remember to include the command(s) being run. Example:
```shell
$ gh issue list --json title -L 5
[
{
"title": "`gh pr checks <pr> --required` should not fail when there are no required checks"
},
{
"title": "gh pr view commits should include commit description"
},
{
"title": "Adapt the color of the device code to the color used by the terminal"
},
{
"title": "`gh pr create` does not default to fork when user has write access to upstream"
},
{
"title": "First party discussions support"
}
]
```
-->

5
.github/SECURITY.md vendored
View file

@ -2,7 +2,10 @@ GitHub takes the security of our software products and services seriously, inclu
If you believe you have found a security vulnerability in GitHub CLI, you can report it to us in one of two ways:
* Report it to this repository directly using [private vulnerability reporting][]. Such reports are not eligible for a bounty reward.
* Report it to this repository directly using [private vulnerability reporting][].
* Include a description of your investigation of the GitHub CLI's codebase and why you believe an exploit is possible.
* POCs and links to code are greatly encouraged.
* Such reports are not eligible for a bounty reward.
* Submit the report through [HackerOne][] to be eligible for a bounty reward.

View file

@ -43,12 +43,29 @@ sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.re
sudo dnf install gh --repo gh-cli
```
<details>
<summary>Show dnf5 commands</summary>
If you're using `dnf5`, commands will vary slightly:
```bash
sudo dnf5 install dnf5-plugins
sudo dnf5 config-manager addrepo --from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf5 install gh --repo gh-cli
```
For more details, check out the [`dnf5 config-manager` documentation](https://dnf5.readthedocs.io/en/latest/dnf5_plugins/config-manager.8.html).
</details>
Alternatively, install from the [community repository](https://packages.fedoraproject.org/pkgs/gh/gh/):
```bash
sudo dnf install gh
```
> [!NOTE]
> If errors regarding GPG signatures occur, see [cli/cli#9569](https://github.com/cli/cli/issues/9569) for steps to fix this.
Upgrade:
```bash
@ -91,6 +108,9 @@ sudo zypper ref
sudo zypper update gh
```
> [!NOTE]
> If errors regarding GPG signatures occur, see [cli/cli#9569](https://github.com/cli/cli/issues/9569) for steps to fix this.
## Manual installation
* [Download release binaries][releases page] that match your platform; or

View file

@ -33,27 +33,32 @@ the changeset is feasible and to allow the associated CI run for new contributor
- can this be closed outright?
- e.g. spam/junk
- add the `invalid` label
- close without comment
- do we not want to do it?
- e.g. have already discussed not wanting to do or duplicate issue
- e.g. we have already discussed not wanting to do or it's a duplicate issue
- add the appropriate label (e.g. `duplicate`)
- comment and close
- are we ok with outside contribution for this?
- e.g. the task is relatively straightforward, but no people on our team have the bandwidth to take it on at the moment
- do we want external contribution for this?
- e.g. the task is relatively straightforward, but the core team does not have the bandwidth to take it on
- ensure that the thread contains all the context necessary for someone new to pick this up
- add `help wanted` label
- add the `help wanted` label
- consider adding `good first issue` label
- do we want external design contribution for this?
- e.g. the task is worthwhile, but needs design work to flesh out the details before implementation and the core team does not have the bandwidth to take it on
- ensure that the thread contains all the context necessary for someone new to pick this up
- add both the `help wanted` and `needs-design` labels
- do we want to do it?
- add the `core` label
- comment acknowledging that
- add `core` label
- add to the project “TODO” column if this is something that should ship soon
- is it intriguing, but requires discussion?
- label `discuss`
- label `needs-investigation` if engineering research is required before action can be taken
- Add the `discuss` label
- Add the `needs-investigation` label if engineering research is required before action can be taken
- does it need more info from the issue author?
- ask the user for details
- add `needs-user-input` label
- add the `needs-user-input` label
- is it a usage/support question?
- consider converting the Issue to a Discussion
- Convert the Issue to a Discussion
## Weekly PR audit

4
go.mod
View file

@ -14,7 +14,7 @@ require (
github.com/cli/go-gh/v2 v2.10.0
github.com/cli/oauth v1.0.1
github.com/cli/safeexec v1.0.1
github.com/cpuguy83/go-md2man/v2 v2.0.4
github.com/cpuguy83/go-md2man/v2 v2.0.5
github.com/creack/pty v1.1.23
github.com/distribution/reference v0.5.0
github.com/gabriel-vasile/mimetype v1.4.5
@ -143,7 +143,7 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/theupdateframework/go-tuf v0.7.0 // indirect
github.com/theupdateframework/go-tuf/v2 v2.0.0 // indirect
github.com/theupdateframework/go-tuf/v2 v2.0.1 // indirect
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/transparency-dev/merkle v0.0.2 // indirect

7
go.sum
View file

@ -109,8 +109,9 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AX
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
@ -440,8 +441,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
github.com/theupdateframework/go-tuf/v2 v2.0.0 h1:rD8d9RotYBprZVgC+9oyTZ5MmawepnTSTqoDuxjWgbs=
github.com/theupdateframework/go-tuf/v2 v2.0.0/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
github.com/theupdateframework/go-tuf/v2 v2.0.1 h1:11p9tXpq10KQEujxjcIjDSivMKCMLguls7erXHZnxJQ=
github.com/theupdateframework/go-tuf/v2 v2.0.1/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8=
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=

View file

@ -72,7 +72,7 @@ func AuthFlow(oauthHost string, IO *iostreams.IOStreams, notice string, addition
return nil
}
fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), authURL)
_ = waitForEnter(IO.In)
if err := b.Browse(authURL); err != nil {

View file

@ -92,7 +92,7 @@ func (p *surveyPrompter) InputHostname() (string, error) {
var result string
err := p.ask(
&survey.Input{
Message: "GHE hostname:",
Message: "Hostname:",
}, &result, survey.WithValidator(func(v interface{}) error {
return ghinstance.HostnameValidator(v.(string))
}))

View file

@ -126,6 +126,12 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
// Disable local caching, so we get up-to-date response from TUF repository
tufOpt.CacheValidity = 0
// Target will be either the default trusted root, or the trust domain-qualified one
ghTR := defaultTR
if opts.TrustDomain != "" {
ghTR = fmt.Sprintf("%s.%s", opts.TrustDomain, defaultTR)
}
if opts.TufUrl != "" && opts.TufRootPath != "" {
tufRoot, err := os.ReadFile(opts.TufRootPath)
if err != nil {
@ -136,7 +142,7 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
tufOpt.RepositoryBaseURL = opts.TufUrl
tufOptions = append(tufOptions, tufConfig{
tufOptions: tufOpt,
targets: []string{defaultTR},
targets: []string{ghTR},
})
} else {
// Get from both Sigstore public good and GitHub private instance
@ -147,14 +153,9 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
tufOpt = verification.GitHubTUFOptions()
tufOpt.CacheValidity = 0
targets := []string{defaultTR}
if opts.TrustDomain != "" {
targets = append(targets, fmt.Sprintf("%s.%s",
opts.TrustDomain, defaultTR))
}
tufOptions = append(tufOptions, tufConfig{
tufOptions: tufOpt,
targets: targets,
targets: []string{ghTR},
})
}

View file

@ -59,6 +59,9 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
Long: heredoc.Docf(`
Authenticate with a GitHub host.
The default hostname is %[1]sgithub.com%[1]s. This can be overridden using the %[1]s--hostname%[1]s
flag.
The default authentication mode is a web-based browser flow. After completion, an
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
@ -222,21 +225,19 @@ func loginRun(opts *LoginOptions) error {
}
func promptForHostname(opts *LoginOptions) (string, error) {
options := []string{"GitHub.com", "GitHub Enterprise Server"}
options := []string{"GitHub.com", "Other"}
hostType, err := opts.Prompter.Select(
"What account do you want to log into?",
"Where do you use GitHub?",
options[0],
options)
if err != nil {
return "", err
}
isEnterprise := hostType == 1
hostname := ghinstance.Default()
if isEnterprise {
hostname, err = opts.Prompter.InputHostname()
isGitHubDotCom := hostType == 0
if isGitHubDotCom {
return ghinstance.Default(), nil
}
return hostname, err
return opts.Prompter.InputHostname()
}

View file

@ -2,6 +2,7 @@ package login
import (
"bytes"
"fmt"
"net/http"
"regexp"
"runtime"
@ -546,7 +547,7 @@ func Test_loginRun_Survey(t *testing.T) {
wantErrOut: regexp.MustCompile("Tip: you can generate a Personal Access Token here https://rebecca.chambers/settings/tokens"),
},
{
name: "choose enterprise",
name: "choose Other",
wantHosts: heredoc.Doc(`
brad.vickers:
users:
@ -563,8 +564,8 @@ func Test_loginRun_Survey(t *testing.T) {
prompterStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
switch prompt {
case "What account do you want to log into?":
return prompter.IndexFor(opts, "GitHub Enterprise Server")
case "Where do you use GitHub?":
return prompter.IndexFor(opts, "Other")
case "What is your preferred protocol for Git operations on this host?":
return prompter.IndexFor(opts, "HTTPS")
case "How would you like to authenticate GitHub CLI?":
@ -606,7 +607,7 @@ func Test_loginRun_Survey(t *testing.T) {
prompterStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
switch prompt {
case "What account do you want to log into?":
case "Where do you use GitHub?":
return prompter.IndexFor(opts, "GitHub.com")
case "What is your preferred protocol for Git operations on this host?":
return prompter.IndexFor(opts, "HTTPS")
@ -640,7 +641,7 @@ func Test_loginRun_Survey(t *testing.T) {
prompterStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
switch prompt {
case "What account do you want to log into?":
case "Where do you use GitHub?":
return prompter.IndexFor(opts, "GitHub.com")
case "What is your preferred protocol for Git operations on this host?":
return prompter.IndexFor(opts, "SSH")
@ -803,3 +804,50 @@ func Test_loginRun_Survey(t *testing.T) {
})
}
}
func Test_promptForHostname(t *testing.T) {
tests := []struct {
name string
options []string
selectedIndex int
// This is so we can test that the options in the function don't change
expectedSelection string
inputHostname string
expect string
}{
{
name: "select 'GitHub.com'",
selectedIndex: 0,
expectedSelection: "GitHub.com",
expect: "github.com",
},
{
name: "select 'Other'",
selectedIndex: 1,
expectedSelection: "Other",
inputHostname: "github.enterprise.com",
expect: "github.enterprise.com",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
promptMock := &prompter.PrompterMock{
SelectFunc: func(_ string, _ string, options []string) (int, error) {
if options[tt.selectedIndex] != tt.expectedSelection {
return 0, fmt.Errorf("expected %s at index %d, but got %s", tt.expectedSelection, tt.selectedIndex, options[tt.selectedIndex])
}
return tt.selectedIndex, nil
},
InputHostnameFunc: func() (string, error) {
return tt.inputHostname, nil
},
}
opts := &LoginOptions{
Prompter: promptMock,
}
hostname, err := promptForHostname(opts)
require.NoError(t, err)
require.Equal(t, tt.expect, hostname)
})
}
}

View file

@ -29,6 +29,8 @@ import (
// ErrInitialCommitFailed indicates the initial commit when making a new extension failed.
var ErrInitialCommitFailed = errors.New("initial commit failed")
const darwinAmd64 = "darwin-amd64"
type Manager struct {
dataDir func() string
lookPath func(string) (string, error)
@ -266,13 +268,16 @@ func (m *Manager) installBin(repo ghrepo.Interface, target string) error {
// if using an ARM-based Mac and an arm64 binary is unavailable, fall back to amd64 if a relevant binary is available and Rosetta 2 is installed
if asset == nil && isMacARM {
for _, a := range r.Assets {
if strings.HasSuffix(a.Name, "darwin-amd64") {
if strings.HasSuffix(a.Name, darwinAmd64) {
if !hasRosetta() {
return fmt.Errorf(
"%[1]s unsupported for %[2]s. Install Rosetta with `softwareupdate --install-rosetta` to use the available darwin-amd64 binary, or open an issue: `gh issue create -R %[3]s/%[1]s -t'Support %[2]s'`",
repo.RepoName(), platform, repo.RepoOwner())
"%[1]s unsupported for %[2]s. Install Rosetta with `softwareupdate --install-rosetta` to use the available %[3]s binary, or open an issue: `gh issue create -R %[4]s/%[1]s -t'Support %[2]s'`",
repo.RepoName(), platform, darwinAmd64, repo.RepoOwner())
}
fallbackMessage := fmt.Sprintf("%[1]s not available for %[2]s. Falling back to compatible %[3]s binary", repo.RepoName(), platform, darwinAmd64)
fmt.Fprintln(m.io.Out, fallbackMessage)
asset = &a
break
}

View file

@ -1098,7 +1098,7 @@ func TestManager_Install_amd64_when_supported(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "FAKE BINARY", string(fakeBin))
assert.Equal(t, "", stdout.String())
assert.Equal(t, "gh-bin-ext not available for darwin-arm64. Falling back to compatible darwin-amd64 binary\n", stdout.String())
assert.Equal(t, "", stderr.String())
}