Easy GitHub CLI Extensions with Nix
GitHub CLI (gh
) is one of my favourite tools. In addition to its built-in commands, it allows you to write your own extensions. In this post, I will show you how to write a simple GitHub CLI extension and how to package it with Nix, in particular under Nix Home Manager.
GitHub CLI and Its Extensions
GitHub CLI (gh
) is the official command-line tool for GitHub. It provides a set of commands for interacting with GitHub repositories, issues, pull requests, and more. It also provides convenience functionality to issue authenticated API requests to both REST and GraphQL APIs of GitHub:
$ gh api repos/vst/hostpatrol/releases \
--jq ".[]|[.name,.created_at]|@csv" |
qsv table
v0.0.15 2024-04-19T07:19:14Z
v0.0.14 2024-04-16T02:48:40Z
v0.0.13 2024-04-15T01:46:18Z
[...]
… or:
$ gh api graphql -f query='
query {
viewer {
login
}
}
'
{
"data": {
"viewer": {
"login": "vst"
}
}
}
In addition to its built-in commands, gh
allows you to write aliases or your own extensions. For example, you can define an alias to list all your repositories:
$ gh alias set pv 'pr view'
$ gh pv
...
Extensions are more powerful than aliases. They are written in any language and installed as a binary or a script. The extension is executed as a subcommand of gh
. You may check out the official gh extensions documentation for more details or available extensions on GitHub.
Nix Home Manager and gh
Nix Home Manager is a tool for managing a user environment with Nix. It already has a nice way to install and configure gh
with the programs.gh
option:
{
# ...
programs.gh = {
enable = true;
settings = {
aliases = {
co = "pr checkout";
pv = "pr view";
};
};
extensions = [
pkgs.gh-s
];
};
# ...
}
Note the programs.gh.extensions
option. It allows you to install any gh
extension from the Nixpkgs repository. However, if you want to write your own extension, you need to package it yourself. That is not a big deal!
Writing a Simple Extension
Let’s say, we want to write an extension that lists all the repositories of the user. The extension is a simple shell script that uses the gh
command to list the repositories current user owns and tabulates with xsv
command:
#!/usr/bin/env bash
gh api \
user/repos \
--method GET \
--raw-field type=owner \
--paginate \
--jq '.[]|[.full_name,.url]|@csv' |
xsv table
Now, we can add it into the programs.gh.extensions
option in the Nix Home Manager configuration:
{
# ...
programs.gh = {
enable = true;
settings = {
aliases = {
co = "pr checkout";
pv = "pr view";
lr = "list-repos";
};
};
extensions = [
pkgs.gh-s
(pkgs.writeShellApplication {
name = "gh-list-my-repos";
derivationArgs = {
pname = "gh-list-my-repos";
};
runtimeInputs = [ pkgs.gh pkgs.xsv ];
text = ''
#!/usr/bin/env bash
gh api \
user/repos \
--method GET \
--raw-field type=owner \
--paginate \
--jq '.[]|[.full_name,.url]|@csv' |
xsv table
'';
})
];
};
# ...
}
Note that:
- We used the
writeShellApplication
function to create a shell script. - We added the
gh
andxsv
packages as runtime inputs. - We added extra derivation arguments to set the package name which is needed by Nix Home Manager to install and locate the extension.
That’s it! You can now use the list-my-repos
command as a subcommand of gh
:
$ gh list-my-repos
...