Merge branch 'trunk' into delete-autolinks

This commit is contained in:
Michael Hoffman 2025-02-07 15:49:48 -05:00 committed by GitHub
commit 8d0ec0a6b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 102 additions and 37 deletions

View file

@ -4,23 +4,22 @@ Hi! Thanks for your interest in contributing to the GitHub CLI!
We accept pull requests for bug fixes and features where we've discussed the approach in an issue and given the go-ahead for a community member to work on it. We'd also love to hear about ideas for new features as issues.
Please do:
### Please do:
* Check issues to verify that a [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].
* Check issues to verify that a [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
* Mention `@cli/code-reviewers` when an issue you want to work on does not have clear Acceptance Criteria
* Open a pull request for any issue labelled [`help wanted`][hw] or [`good first issue`][gfi]
Please avoid:
### Please _do not_:
* 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.
* Open a pull request for issues without the `help wanted` label or explicit Acceptance Criteria
* Expand pull request scope to include changes that are not described in the issue's Acceptance Criteria
* Add installation instructions specifically for your OS/package manager
* Open 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
## Building the project

View file

@ -1,39 +1,52 @@
# Releasing
To initiate a new production deployment:
```sh
script/release vX.Y.Z
```
See `script/release --help` for more information.
> **Note:**
> Every production release will request an approval by the select few people before it can proceed.
> [!NOTE]
> Deployment workflow requires maintainer approval to run.
What this does is:
- Builds Linux binaries on Ubuntu;
- Builds and signs Windows binaries on Windows;
- Builds, signs, and notarizes macOS binaries on macOS;
- Uploads all release artifacts to a new GitHub Release;
- A new git tag `vX.Y.Z` is created in the remote repository;
- The changelog is [generated from the list of merged pull requests](https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes);
- Updates cli.github.com with the contents of the new release;
- Updates [GitHub CLI marketing site](https://cli.github.com) with the contents of the new release;
- Updates the [`gh` Homebrew formula](https://github.com/williammartin/homebrew-core/blob/master/Formula/g/gh.rb) in the [`homebrew/homebrew-core` repo](https://github.com/search?q=repo%3AHomebrew%2Fhomebrew-core+%22gh%22+in%3Atitle&type=pullrequests).
> [!NOTE]
> `Homebrew/formulae.brew.sh` makes new formula versions available every 15 minutes through scheduled [CI workflow](https://github.com/Homebrew/formulae.brew.sh/actions/workflows/tests.yml).
>
> For more information, see https://docs.brew.sh/Formula-Cookbook#an-introduction
To test out the build system while avoiding creating an actual release:
```sh
script/release --staging vX.Y.Z --branch patch-1 -p macos
```
The build artifacts will be available via `gh run download <RUN> -n macos`.
## General guidelines
* Features to be released should be reviewed and approved at least one day prior to the release.
* Feature releases should bump up the minor version number.
* Breaking releases should bump up the major version number. These should generally be rare.
- Features to be released should be reviewed and approved at least one day prior
to the release.
- Feature releases should bump up the minor version number.
- Breaking releases should bump up the major version number. These should
generally be rare.
## Test the build system locally
A local release can be created for testing without creating anything official on the release page.
A local release can be created for testing without creating anything official on
the release page.
1. Make sure GoReleaser is installed: `brew install goreleaser`
2. `script/release --local`
@ -45,5 +58,6 @@ Occasionally, it might be necessary to clean up a bad release and re-release.
1. Delete the release and associated tag
2. Re-release and monitor the workflow run logs
3. Open pull request updating [`gh` Homebrew formula](https://github.com/williammartin/homebrew-core/blob/master/Formula/g/gh.rb) with new SHA versions, linking the previous PR
3. Open pull request updating [`gh` Homebrew formula](https://github.com/williammartin/homebrew-core/blob/master/Formula/g/gh.rb)
with new SHA versions, linking the previous PR
4. Verify resulting Debian and RPM packages, Homebrew formula

2
go.mod
View file

@ -51,7 +51,7 @@ require (
golang.org/x/term v0.28.0
golang.org/x/text v0.21.0
google.golang.org/grpc v1.69.4
google.golang.org/protobuf v1.36.4
google.golang.org/protobuf v1.36.5
gopkg.in/h2non/gock.v1 v1.1.2
gopkg.in/yaml.v3 v3.0.1
)

4
go.sum
View file

@ -559,8 +559,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View file

@ -142,7 +142,8 @@ func genMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string)
fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine())
}
if hasLong {
fmt.Fprintf(w, "%s\n\n", cmd.Long)
longWithEscapedPipe := strings.ReplaceAll(cmd.Long, "|", "&#124;")
fmt.Fprintf(w, "%s\n\n", longWithEscapedPipe)
}
for _, g := range root.GroupedCommands(cmd) {

View file

@ -463,9 +463,11 @@ func processResponse(resp *http.Response, opts *ApiOptions, bodyWriter, headersW
var serverError string
if isJSON && (opts.RequestPath == "graphql" || resp.StatusCode >= 400) {
responseBody, serverError, err = parseErrorResponse(responseBody, resp.StatusCode)
if err != nil {
return
if !strings.EqualFold(opts.RequestMethod, "HEAD") {
responseBody, serverError, err = parseErrorResponse(responseBody, resp.StatusCode)
if err != nil {
return
}
}
}

View file

@ -1234,6 +1234,35 @@ func Test_apiRun_DELETE(t *testing.T) {
}
}
func Test_apiRun_HEAD(t *testing.T) {
ios, _, _, _ := iostreams.Test()
err := apiRun(&ApiOptions{
IO: ios,
Config: func() (gh.Config, error) {
return config.NewBlankConfig(), nil
},
HttpClient: func() (*http.Client, error) {
var tr roundTripper = func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 422,
Request: req,
Header: map[string][]string{
"Content-Type": {"application/json"},
}}, nil
}
return &http.Client{Transport: tr}, nil
},
MagicFields: []string(nil),
RawFields: []string(nil),
RequestMethod: "HEAD",
RequestMethodPassed: true,
})
if err != cmdutil.SilentError {
t.Fatalf("got error %v", err)
}
}
func Test_apiRun_inputFile(t *testing.T) {
tests := []struct {
name string

View file

@ -16,7 +16,7 @@ import (
func NewCmdConfig(f *cmdutil.Factory) *cobra.Command {
longDoc := strings.Builder{}
longDoc.WriteString("Display or change configuration settings for gh.\n\n")
longDoc.WriteString("Current respected settings:\n")
longDoc.WriteString("Current respected settings:\n\n")
for _, co := range config.Options {
longDoc.WriteString(fmt.Sprintf("- `%s`: %s", co.Key, co.Description))
if len(co.AllowedValues) > 0 {

View file

@ -9,6 +9,7 @@ import (
"strconv"
"time"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/api"
ghContext "github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/git"
@ -51,7 +52,15 @@ func NewCmdStatus(f *cmdutil.Factory, runF func(*StatusOptions) error) *cobra.Co
cmd := &cobra.Command{
Use: "status",
Short: "Show status of relevant pull requests",
Args: cmdutil.NoArgsQuoteReminder,
Long: heredoc.Docf(`
Show status of relevant pull requests.
The status shows a summary of pull requests that includes information such as
pull request number, title, CI checks, reviews, etc.
To see more details of CI checks, run %[1]sgh pr checks%[1]s.
`, "`"),
Args: cmdutil.NoArgsQuoteReminder,
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override
opts.BaseRepo = f.BaseRepo

View file

@ -23,7 +23,7 @@ type editItemOpts struct {
fieldID string
projectID string
text string
number float32
number float64
date string
singleSelectOptionID string
iterationID string
@ -123,7 +123,7 @@ func NewCmdEditItem(f *cmdutil.Factory, runF func(config editItemConfig) error)
editItemCmd.Flags().StringVar(&opts.fieldID, "field-id", "", "ID of the field to update")
editItemCmd.Flags().StringVar(&opts.projectID, "project-id", "", "ID of the project to which the field belongs to")
editItemCmd.Flags().StringVar(&opts.text, "text", "", "Text value for the field")
editItemCmd.Flags().Float32Var(&opts.number, "number", 0, "Number value for the field")
editItemCmd.Flags().Float64Var(&opts.number, "number", 0, "Number value for the field")
editItemCmd.Flags().StringVar(&opts.date, "date", "", "Date value for the field (YYYY-MM-DD)")
editItemCmd.Flags().StringVar(&opts.singleSelectOptionID, "single-select-option-id", "", "ID of the single select option value to set on the field")
editItemCmd.Flags().StringVar(&opts.iterationID, "iteration-id", "", "ID of the iteration value to set on the field")

View file

@ -47,6 +47,14 @@ func TestNewCmdeditItem(t *testing.T) {
itemID: "123",
},
},
{
name: "number with floating point value",
cli: "--number 123.45 --id 123",
wants: editItemOpts{
number: 123.45,
itemID: "123",
},
},
{
name: "field-id",
cli: "--field-id FIELD_ID --id 123",
@ -255,7 +263,7 @@ func TestRunItemEdit_Number(t *testing.T) {
// edit item
gock.New("https://api.github.com").
Post("/graphql").
BodyString(`{"query":"mutation UpdateItemValues.*","variables":{"input":{"projectId":"project_id","itemId":"item_id","fieldId":"field_id","value":{"number":2}}}}`).
BodyString(`{"query":"mutation UpdateItemValues.*","variables":{"input":{"projectId":"project_id","itemId":"item_id","fieldId":"field_id","value":{"number":123.45}}}}`).
Reply(200).
JSON(map[string]interface{}{
"data": map[string]interface{}{
@ -284,7 +292,7 @@ func TestRunItemEdit_Number(t *testing.T) {
config := editItemConfig{
io: ios,
opts: editItemOpts{
number: 2,
number: 123.45,
itemID: "item_id",
projectID: "project_id",
fieldID: "field_id",

View file

@ -250,7 +250,7 @@ type FieldValueNodes struct {
Field ProjectField
} `graphql:"... on ProjectV2ItemFieldLabelValue"`
ProjectV2ItemFieldNumberValue struct {
Number float32
Number float64
Field ProjectField
} `graphql:"... on ProjectV2ItemFieldNumberValue"`
ProjectV2ItemFieldSingleSelectValue struct {

View file

@ -131,7 +131,10 @@ func FindWorkflow(client *api.Client, repo ghrepo.Interface, workflowSelector st
if _, err := strconv.Atoi(workflowSelector); err == nil || isWorkflowFile(workflowSelector) {
workflow, err := getWorkflowByID(client, repo, workflowSelector)
if err != nil {
return nil, err
var httpErr api.HTTPError
if errors.As(err, &httpErr) && httpErr.StatusCode == 404 {
return nil, fmt.Errorf("workflow %s not found on the default branch", workflowSelector)
}
}
return []Workflow{*workflow}, nil
}