Using the Github cli with Multiple Repos
Marc Dougherty
Posted on February 24, 2022
I have been using the Github CLI for a while now, and
I've found it to be really great when working in the context of a single
repository. But what happens when you're responsible for work in dozens of
repos? Keeping tabs on many repos can be done, thanks to the gh api
subcommand, and aliases!
gh api
allows you to call any github api endpoint, and for my particular
needs, the search/issues
endpoint is the most useful, as it searches both
issues and PRs.
There are two different ways to format responses, either with the --jq
flag,
which uses jq
syntax or --template
which uses Go's text/template
syntax. I
found prototyping with the jq
syntax to be nice, but the color and formatting
choices in the --template
flag won me over.
Note that the --template
args in the below examples are all the same, and they
produce output like this (but with some tasteful terminal colors, which do not
appear in markdown):
[ 98] chore(deps): update dependency maven to v3.6 (15 days ago)
https://github.com/GoogleCloudPlatform/cloud-run-samples/pull/98
More information about formatting output can be found in the gh
formatting
help.
My issues/PRs that need followup
In my job, my team is responsible for the care and feeding of many different
public github repositories, which requires a lot of issue triage, and pr
followups. Switching to each of these contexts to run gh issues
and
gh status
is pretty tiresome, so I made a command that uses gh api
to search
for open issues and PRs in any repo that are assigned to me:
gh api -XGET search/issues -f q='assignee:@me is:open ' \
--template '{{range .items -}}[{{.number | printf "%5.f" |autocolor "blue" }}] {{.title}} ({{ timeago .updated_at | autocolor "yellow+d" }}) {{printf "\n " }}{{.html_url}} {{print "\n" -}}{{end}}'
This command is not much fun to type, so I've created an alias within the gh
tool (not to be confused with shell aliases). However, using the gh alias set
command would require escaping the quotation marks, I chose to edit the config file directly - it lives at ~/.config/gh/config.yaml
on my linux machine. Adding the following block to the aliases
list will create the alias:
mine: |
api -XGET search/issues -f q="assignee:@me is:open"
--template '{{range .items -}}
[{{.number | printf "%4.f" |autocolor "blue" }}] {{.title}} ({{timeago .updated_at | autocolor "yellow+d" }})
{{print "\n " }}{{.html_url}} {{print "\n" -}}
{{end}}'"
(Note that the yaml heredoc syntax (|
) is used to allow a multi-line string.
Ensure the indentation is the same for all lines, or there may be problems
parsing your config!)
Now I can see all my assigned issues and PRs by running gh mine
!
Unclaimed team reviews
Tracking issues and PRs that are waiting on the team's review (that nobody has
claimed yet) can be done with a similar approach. Note that you'll need to update
the search query to use your own Github Organization and Team in the query below.
gh api -XGET search/issues -f q='team-review-requested:yourorg/yourteam is:open -review:approved no:assignee' \
--template '{{range .items -}}[{{.number | printf "%4.f" |autocolor "blue" }}] {{.title}} ({{timeago .updated_at | autocolor "yellow+d" }}) {{printf "\n " }}{{.html_url}} {{print "\n" -}}{{end}}'
or ready for your config.yml
:
teamreviews: |
api -XGET search/issues -f q="team-review-requested:yourorg/yourteam is:open -review:approved no:assignee"
--template '{{range .items -}}
[{{.number | printf "%4.f" |autocolor "blue" }}] {{.title}} ({{timeago .updated_at | autocolor "yellow+d" }})
{{printf "\n " }}{{.html_url}} {{print "\n" -}}
{{end}}'"
Other useful searches
By replacing the search query (the q
parameter) with another github search
query, you can use this method to display other handy results.
- Reviews I approved, but are not merged:
reviewed-by:@me review:approved is:open
- Incomplete reviews I am assigned to directly:
user-review-requested:@me -review:approved
(note the-
prefix, which will match un-approved PRs)
I found myself using the same display with different search queries, so I ended
up making an alias for doing arbitrary searches:
# global search, given a *quoted* github search string.
gsearch: |
api -XGET search/issues -f q="$1"
--template '{{range .items -}}
[{{.number | printf "%4.f" |autocolor "green" }}] {{.title}} ({{timeago .updated_at | autocolor "yellow+d" }})
{{- printf "\n " }}{{.html_url}} {{println -}}
{{end}}'
Future directions
I would like to have a bit of extra information about these PRs, like whether or
not their required checks are passing, all in the same output. To achieve this,
I'd probably have to write a
gh-extension.
To avoid replicating existing gh
functionality, there's a go-gh
library.
Do you use other github searches or gh
tricks to keep tabs on your work? Tell
me about it in the comments!
Posted on February 24, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024