Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit multiple issues, PRs in parallel #7259

Merged
merged 5 commits into from
Apr 25, 2023
Merged

Edit multiple issues, PRs in parallel #7259

merged 5 commits into from
Apr 25, 2023

Conversation

heaths
Copy link
Contributor

@heaths heaths commented Apr 1, 2023

Resolves #5782 by allowing multiple issues or PRs to be edited in parallel, and querying for shared fields once to reduce network requests.

@heaths
Copy link
Contributor Author

heaths commented Apr 1, 2023

This is not complete, but I was hoping for an early review to see if you're good with this approach. It's similar to some other CLI commands and what I've done in some GH extensions.

It allows interactive with only 1 issue per discussion in #5782. Since I check early as part of argument validation, the editRun function is roughly the same, with a couple of interactive checks to prompt. That would only actually happen if there was 1 issue, so the logic is left as-is and simple.

There's still a few things to do:

  • Do the same for gh pr edit (will do this in a separate PR)
  • Reorder or refactor how shared editable fields are fetched since the defaults are no longer set. In manual testing, I found that this breaks the flow e.g., selecting "Assignees" does not show anyone or allow you to specify someone and instead just asked to submit, prompting for Y/n.
  • Add tests for issue's and PR's editRun functions.

@heaths
Copy link
Contributor Author

heaths commented Apr 3, 2023

@mislav @samcoe what do you think of the direction here? I'll make similar changes to pr edit and adds tests for multiple issues for both.

I refactored the brunt of the lookup code into separate methods because so many commands call the singular version, so it seemed like a good idea to consolidate all the checks therein; though, part of me feels that may be unnecessary in an EXE project because those commands only work with a single issue anyway. Perhaps a separate method could just panic on completely unexpected results e.g., multiple outputs, which shouldn't happen. Sort of like runtime asserts you should never hit anyway. Thoughts?

Copy link
Contributor

@samcoe samcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heaths Thanks for getting start on this. Left a handful of inline code comments. Let me know if you have any questions about them.

pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/shared/lookup.go Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Show resolved Hide resolved
pkg/cmd/pr/shared/editable.go Outdated Show resolved Hide resolved
pkg/cmd/issue/shared/lookup.go Show resolved Hide resolved
@heaths
Copy link
Contributor Author

heaths commented Apr 10, 2023

@samcoe I'm done with runtime changes and manual testing but having problems with writing tests. What's used in cli/cli is rather limited, making it difficult to identify specific requests unlike gock used in cli/go-gh. For example, I need to return an error from an updateIssue to test the success + failure collection code. Seems the Matcher isn't capable, though I haven't fully explored what all other code is potentially doing here. May need to write my own matcher. Or, what about introducing gock into cli/cli?

Updated: I added a matcher for mutations - could do the same for queries, but didn't need it so it'd get no coverage - in lieu of gock and this allows me to test the failure scenarios for both issue queries and updates.

If you're good with this pattern, I'll replicate the same for PRs. Basically, I sort and output all the successful issue URLs first and then the failed URLs since the CLI would return a error as the final line: it'd be all grouped together.

Alternatively, I considered aggregating all errors into a single one, but the CLI currently targets Go 1.19 and not 1.20 so there's no built-in error wrapping. I'm open to changing that for this PR, though.

Copy link
Contributor

@samcoe samcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking real good, almost there I think! Appreciate your patients going through this review process.

pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit.go Outdated Show resolved Hide resolved
pkg/cmd/issue/shared/lookup.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit_test.go Outdated Show resolved Hide resolved
pkg/cmd/issue/edit/edit_test.go Outdated Show resolved Hide resolved
pkg/httpmock/stub.go Outdated Show resolved Hide resolved
Resolves cli#5782 by allowing multiple issues or PRs to be edited in parallel, and querying for shared fields once to reduce network requests.
Also resolves other PR feedback
@heaths heaths marked this pull request as ready for review April 16, 2023 06:33
@heaths heaths requested a review from a team as a code owner April 16, 2023 06:33
@heaths heaths requested review from samcoe and removed request for a team April 16, 2023 06:33
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label Apr 16, 2023
@cliAutomation cliAutomation added this to Needs review 🤔 in The GitHub CLI Apr 16, 2023
@heaths
Copy link
Contributor Author

heaths commented Apr 16, 2023

@samcoe as far as issues go, this should be ready. I rebased on trunk but it may take a little more time to make the changes to PRs. When I first looked at this, I took a cursory glance and it seemed that, as with some other places in the CLI, issues and PRs shared more code than they actual do once I started digging in.

On that note, would you consider taking issues first? And should I refactor PRs or issues to actually share more? Issues have the function we'd be discussing while PRs uses a Finder. PRs also don't prompt for what to edit, but I don't intend to change that unless you wanted me to. I'm trying to keep refactoring to a minimum to reduce risk, so for now I'll continue with such minimal changes unless you want me to unify the code more.

Copy link
Contributor

@samcoe samcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heaths This looks great to me! Thanks for the hard work on this.

I don't see a problem with merging/releasing this before pr edit gets changed. I don't think they need to be shipped together, each feature provides value on its own.

For pr edit I think keeping the change set to a minimum is the right approach and we shouldn't try to refactor the two commands to share more code unless it really makes sense. As you said, the two commands have some differing behavior so I think it is completely fine if we end up with some duplicate code.

The GitHub CLI automation moved this from Needs review 🤔 to Needs to be merged 🎉 Apr 16, 2023
@heaths
Copy link
Contributor Author

heaths commented Apr 17, 2023

@samcoe I've got a few ideas of how to support this for PRs while keeping changes to a minimum. Almost all PR commands use the Finder and Finder.Find would be a lot to duplicate as I did with IssuesFromArgsWithFields, but like that function simply calling one within another doesn't work ideally. What if, instead, I do what I did originally with IssuesFromArgsWithFields and had a singular function that calls the plural variant and either assumes or asserts a single PR is returned (probably safe to assume)? Finder.Find is already using errgroup so adding another goroutine seems insignificant.

The idea would be that no selectors means the current branch as it is currently, but then condition into a loop of 1 or more PR numbers, URLs, or branch names. Find could be a wrapper that assumes a single issue is returned, while MultiFind ("multi" seems to be a common enough prefix in the codebase, but I'm open to other suggestions, of course) can return multiple. That was initially the goal of IssuesFromArgsWithFields but I appreciate it wasn't using errgroup or even a wait group before, but Find already does.

If you'd prefer - I know we overlap a bit in your afternoon / my morning - perhaps we could chat over Teams.

@samcoe
Copy link
Contributor

samcoe commented Apr 18, 2023

@heaths Agreed that changing finder.Find would cause too much of a wide spreading change and that adding a new function is the the better approach. I am partial to the name finder.FindMultiple but I don't have strong opinions on it. This overall approach seems good to me.

@heaths
Copy link
Contributor Author

heaths commented Apr 18, 2023

@samcoe I more or less started down that path, though with a different name. I like yours better and will change it.

The only widespread change I ended up doing was making FindOptions.Selector and BaseBranch []string and renaming them plurally. The single + multiple fields just felt so wrong I couldn't bring myself to do it. Sure, it touched ~10 files but it's all 1- or 2-liners. I'll continue with that for a separate PR.

Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hard work on this @heaths and @samcoe for stewarding this! 🚀

@@ -41,6 +36,70 @@ func IssueFromArgWithFields(httpClient *http.Client, baseRepoFn func() (ghrepo.I
return issue, baseRepo, err
}

// IssuesFromArgWithFields loads 1 or more issues or pull requests with the specified fields. If some of the fields
// could not be fetched by GraphQL, this returns non-nil issues and a *PartialLoadError.
func IssuesFromArgsWithFields(httpClient *http.Client, baseRepoFn func() (ghrepo.Interface, error), args []string, fields []string) ([]*api.Issue, ghrepo.Interface, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the async nature of this function's implementation, the resulting slice of api.Issue results does not necessarily match the order of input args. It doesn't seem like that negatively affects the rest of the edit implementation, but I wonder will this be apparent to future callers of this function. Just a thought!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order shouldn't matter, true, and since it didn't even handle multiple issues before I don't foresee any regression. That said, @samcoe and I did briefly discuss whether to just lexically sort the issues or try to match the order in which they were specified - the latter of which didn't seem necessary. Could still be done, though. I would hope - and see on reason - callers would care about the order specified.

@mislav mislav merged commit 17679cf into cli:trunk Apr 25, 2023
The GitHub CLI automation moved this from Needs to be merged 🎉 to Pending Release 🥚 Apr 25, 2023
@heaths heaths deleted the issue5782 branch April 25, 2023 16:18
renovate bot added a commit to scottames/dots that referenced this pull request Apr 29, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [aquaproj/aqua-registry](https://togithub.com/aquaproj/aqua-registry)
| minor | `v3.158.0` -> `v3.159.0` |
| [cli/cli](https://togithub.com/cli/cli) | minor | `v2.27.0` ->
`v2.28.0` |
| [weaveworks/eksctl](https://togithub.com/weaveworks/eksctl) | minor |
`v0.138.0` -> `v0.139.0` |

---

### Release Notes

<details>
<summary>aquaproj/aqua-registry</summary>

###
[`v3.159.0`](https://togithub.com/aquaproj/aqua-registry/releases/tag/v3.159.0)

[Compare
Source](https://togithub.com/aquaproj/aqua-registry/compare/v3.158.1...v3.159.0)


[Issues](https://togithub.com/aquaproj/aqua-registry/issues?q=is%3Aissue+milestone%3Av3.159.0)
| [Pull
Requests](https://togithub.com/aquaproj/aqua-registry/pulls?q=is%3Apr+milestone%3Av3.159.0)
| aquaproj/aqua-registry@v3.158.0...v3.159.0

#### 🎉 New Packages


[#&#8203;11807](https://togithub.com/aquaproj/aqua-registry/issues/11807)
[kubecfg/kubecfg](https://togithub.com/kubecfg/kubecfg): A tool for
managing complex enterprise Kubernetes environments as code

[#&#8203;11808](https://togithub.com/aquaproj/aqua-registry/issues/11808)
[loov/goda](https://togithub.com/loov/goda): Go Dependency Analysis
toolkit

#### Fixes


[#&#8203;11806](https://togithub.com/aquaproj/aqua-registry/issues/11806)
solidiquis/erdtree: Follow up changes of erdtree v2.0.0

https://github.com/solidiquis/erdtree/releases/tag/v2.0.0

> Perhaps the most important change to note is that the compiled binary
has been renamed from et to erd in order to address the following issue
> regarding name collisions with other programs
>
> -
[solidiquis/erdtree#23

###
[`v3.158.1`](https://togithub.com/aquaproj/aqua-registry/releases/tag/v3.158.1)

[Compare
Source](https://togithub.com/aquaproj/aqua-registry/compare/v3.158.0...v3.158.1)


[Issues](https://togithub.com/aquaproj/aqua-registry/issues?q=is%3Aissue+milestone%3Av3.158.1)
| [Pull
Requests](https://togithub.com/aquaproj/aqua-registry/pulls?q=is%3Apr+milestone%3Av3.158.1)
| aquaproj/aqua-registry@v3.158.0...v3.158.1

#### Fixes


[#&#8203;11790](https://togithub.com/aquaproj/aqua-registry/issues/11790)
Follow up changes of cli/cli v2.28.0
[@&#8203;kyontan](https://togithub.com/kyontan)

GitHub's CLI (cli/cli) changed format for macOS to zip (from tar.gz)
since v2.28.0

See https://github.com/cli/cli/releases/tag/v2.28.0 for details.

</details>

<details>
<summary>cli/cli</summary>

### [`v2.28.0`](https://togithub.com/cli/cli/releases/tag/v2.28.0):
GitHub CLI 2.28.0

[Compare Source](https://togithub.com/cli/cli/compare/v2.27.0...v2.28.0)

#### What's New

-   macOS binaries are now signed and notarized
- ⚠️ macOS archives attached to our releases are no longer `.tar.gz`,
but `.zip` instead. This is because `.tar.gz` archives cannot be
notarized.
- The `checksums.txt` file attached to every release now includes the
checksum of the Windows MSI installer too.

- macOS and Windows binaries are now compiled from their respective
platforms and have `cgo` enabled. This might help resolve respecting
system proxy settings and avoid related networking issues.

- `issue edit`: edit multiple issues at the same time by
[@&#8203;heaths](https://togithub.com/heaths) in
[cli/cli#7259

- Add `gh org list` by
[@&#8203;joshkraft](https://togithub.com/joshkraft) in
[cli/cli#7257

- `ssh-key`: add ability to manage signing keys by
[@&#8203;kousikmitra](https://togithub.com/kousikmitra) in
[cli/cli#7270

- `search`: enable owner flag to take multiple values by
[@&#8203;kousikmitra](https://togithub.com/kousikmitra) in
[cli/cli#7305

- `codespace`: add `--web` flag for `list` & `create` commands by
[@&#8203;doaortu](https://togithub.com/doaortu) in
[cli/cli#7288

- Our Debian & RPM packages now ship with shell completion scripts by
[@&#8203;Xerkus](https://togithub.com/Xerkus) in
[cli/cli#7293

- `run list`: add `--event` and `--created` filters by
[@&#8203;cawfeecake](https://togithub.com/cawfeecake) in
[cli/cli#7363
[cli/cli#7352

- `repo`: add `visibility` JSON field by
[@&#8203;yeikel](https://togithub.com/yeikel) in
[cli/cli#7337

#### What's Changed

- Fix typo in `cs stop` command: `Stoppping` -> `Stopping` by
[@&#8203;FalseDev](https://togithub.com/FalseDev) in
[cli/cli#7318
- Update go-gh to v2 by [@&#8203;samcoe](https://togithub.com/samcoe) in
[cli/cli#7299
- `auth login`: normalize host name by
[@&#8203;tuananhlai](https://togithub.com/tuananhlai) in
[cli/cli#6999
- build(deps): bump github.com/cenkalti/backoff/v4 from 4.2.0 to 4.2.1
by [@&#8203;dependabot](https://togithub.com/dependabot) in
[cli/cli#7323
- Clarify how SSH keys are selected for `gh codespace ssh` by
[@&#8203;jkeech](https://togithub.com/jkeech) in
[cli/cli#7325
- Initialize deployment.yml workflow file by
[@&#8203;mislav](https://togithub.com/mislav) in
[cli/cli#7328
- Fix `gh cs ports` requiring `sudo` for privileged port numbers by
[@&#8203;cmbrose](https://togithub.com/cmbrose) in
[cli/cli#7326
- Correct some typos by [@&#8203;goggle](https://togithub.com/goggle) in
[cli/cli#7342
- Diacritics substitution in prompt by
[@&#8203;benjlevesque](https://togithub.com/benjlevesque) in
[cli/cli#7205
- gh: move `CODEOWNERS` inside the `.github/` dir by
[@&#8203;SauravMaheshkar](https://togithub.com/SauravMaheshkar) in
[cli/cli#7366
- Pretty-print gh api output when using --jq by
[@&#8203;mjpieters](https://togithub.com/mjpieters) in
[cli/cli#7236

#### New Contributors

- [@&#8203;joshkraft](https://togithub.com/joshkraft) made their first
contribution in
[cli/cli#7257
- [@&#8203;kousikmitra](https://togithub.com/kousikmitra) made their
first contribution in
[cli/cli#7270
- [@&#8203;doaortu](https://togithub.com/doaortu) made their first
contribution in
[cli/cli#7288
- [@&#8203;FalseDev](https://togithub.com/FalseDev) made their first
contribution in
[cli/cli#7318
- [@&#8203;tuananhlai](https://togithub.com/tuananhlai) made their first
contribution in
[cli/cli#6999
- [@&#8203;goggle](https://togithub.com/goggle) made their first
contribution in
[cli/cli#7342
- [@&#8203;Xerkus](https://togithub.com/Xerkus) made their first
contribution in
[cli/cli#7293
- [@&#8203;cawfeecake](https://togithub.com/cawfeecake) made their first
contribution in
[cli/cli#7363
- [@&#8203;yeikel](https://togithub.com/yeikel) made their first
contribution in
[cli/cli#7337
- [@&#8203;SauravMaheshkar](https://togithub.com/SauravMaheshkar) made
their first contribution in
[cli/cli#7366
- [@&#8203;mjpieters](https://togithub.com/mjpieters) made their first
contribution in
[cli/cli#7236

**Full Changelog**: cli/cli@v2.27.0...v2.28.0

</details>

<details>
<summary>weaveworks/eksctl</summary>

###
[`v0.139.0`](https://togithub.com/weaveworks/eksctl/releases/tag/v0.139.0):
eksctl 0.139.0 (permalink)

[Compare
Source](https://togithub.com/weaveworks/eksctl/compare/0.138.0...0.139.0)

### Release v0.139.0

#### 🚀 Features

- Security Policy for eksctl project
([#&#8203;6541](https://togithub.com/weaveworks/eksctl/issues/6541))

#### 🐛 Bug Fixes

- Fix flux version validation
([#&#8203;6530](https://togithub.com/weaveworks/eksctl/issues/6530))

#### 📝 Documentation

- Fix empty info block on Default Addon Upgrades page
([#&#8203;6524](https://togithub.com/weaveworks/eksctl/issues/6524))
- Update installation instructions
([#&#8203;6376](https://togithub.com/weaveworks/eksctl/issues/6376))
- AWS Private link support for fully private cluster
([#&#8203;6408](https://togithub.com/weaveworks/eksctl/issues/6408))

#### Acknowledgments

Weaveworks would like to sincerely thank:
[@&#8203;thezanke](https://togithub.com/thezanke), and
[@&#8203;yuxiang-zhang](https://togithub.com/yuxiang-zhang)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/scottames/dots).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS41OC4yIiwidXBkYXRlZEluVmVyIjoiMzUuNjMuMSJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
jtpetty pushed a commit that referenced this pull request May 22, 2023
Allows multiple issues or PRs to be edited in parallel, and querying for shared fields once to reduce network requests.

Co-authored-by: Sam Coe <samcoe@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external pull request originating outside of the CLI core team
Projects
No open projects
The GitHub CLI
  
Pending Release 🥚
Development

Successfully merging this pull request may close these issues.

Consider batching some operations like issue edit
4 participants