Contributing
:wave: Hey there! Thanks for considering taking the time to contribute to
git-bug. This page contains some general guidelines, and instructions for
getting started as a contributor to this project.
- Get the source code
 - Software requirements
 - 4.0 | Post-installation tasks
 - Useful development commands
 - Submitting changes
 
Get the source code
Clone this repository to your system in a way you're comfortable with. Below, we
show a command that clones the repository using SSH, and places it in
~/code/git-bug.
git clone git@github.com:git-bug/git-bug ~/code/git-bug
[!TIP] If you wish to clone the repository to another location on disk, change
~/code/git-bugto your desired path (e.g. your current directory can be used with.or by omitting the path argument). The rest of this documentation will refer to~/code/git-bugin all instances, so make sure you change them there to match the location you've cloned the repository.
Software requirements
This repository uses nix to provide a consistent development environment,
ensuring that each contributor has the same revision of each dependency and tool
installed. It is strongly encouraged to use nix when contributing to
git-bug to remove the "it works on my machine" class of errors, and ensure you
have a smoother experience passing the CI pipelines (wrt formatting and such).
While you can manually install the tools and packages we use and
hack on this project on your own, you will miss out on the hermeticity and
standardization that our development shell provides. You may end up fighting
with failing CI pipelines more often, or have to figure out how to perform
various tasks on your own. Using the development shell ensures you always have
every tool you need to contribute to git-bug, and that each tool is always
configured correctly.
Because of this, we encourage all contributors to follow the documentation below to install the dependencies for the development shell.
[!NOTE] In the future, we will provide a container image with
nixpre-installed and everything configured to get you started. This will be able to be pulled like any other image, and will be made compatible with VSCode's "devcontainer" feature and GitHub Codespaces.For more information, see the tracking issue.
1.0 | Install nix
To install nix, you can follow the official instructions.
We recommend following the instructions for multi-user mode where applicable,
instead of single-user mode.
[!IMPORTANT] The rest of this document assumes you have successfully installed
nix.
2.0 | Enable nix-command and flakes
nix-command and flakes are two optional configuration properties that we
depend on in order to provide the development shell. You'll need to make sure
that these are enabled.
NixOS
Add the following to your system configuration:
nix.settings.experimental-features = [ "nix-command" "flakes" ];
Other
Add the following to ~/.config/nix.conf or /etc/nix/nix.conf:
experimental-features = nix-command flakes
[!IMPORTANT] The rest of this document assume you have enabled these options.
3.0 | Install and configure direnv
direnv can be used to automatically activate the development
shell (using //:.envrc). It can be installed either with nix, or
independently.
With nix (suggested for users new to nix)
nix --extra-experimental-options 'flakes nix-command' profile install nixpkgs\#direnv
Next, run the following commands to apply the optional configuration for
direnv. Be sure to change references to ~/code/git-bug if you have cloned the
repository somewhere else.
Create a configuration file for direnv
touch ~/.config/direnv/direnv.toml
Disable the warning for shells with longer load times
This is optional, but recommended, as it helps reduce visual clutter.
nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \ put -t int -v 0 ".global.warn_timeout"
Disable printing of the environment variables that change
This is optional, but recommended, as it helps reduce visual clutter.
nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \ put -t bool -v true ".global.hide_env_diff"
Configure automatic activation of the development shell
This is optional, but strongly recommended.
nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv.toml \ put -v "~/code/git-bug/.envrc" ".whitelist.exact[]"
Alternatively, simply run direnv allow after moving into the repository for
the first time.
IMPORTANT
If you choose not to allow the shell to be automatically activated, you will need to typenix developevery time you want to activate it, and this will swap you into bash and change your prompt. You'll have a far better experience allowingdirenvto automatically manage activation and deactivation.
Configure your shell
This final step is crucial -- be sure to configure your shell for direnv.
Using home-manager
programs.direnv = {
  enable = true;
  nix-direnv.enable = true;
  # one of the following, depending on your shell
  # enableZshIntegration = true;
  # enableBashIntegration = true;
  # enableFishIntegration = true;
  # enableNushellIntegration = true;
  config = {
    hide_env_diff = true;
    warn_timeout = 0;
    whitelist.exact = [ "~/code/git-bug/.envrc" ];
  };
}
4.0 | Post-installation tasks
Congratulations! If you've reached this section of the documentation, chances are that you have a working development environment for contributing to this repository. Read below for some additional tasks you should complete.
4.1 | Open a new shell
In order for the installation to take effect, you will need to open a new shell. It is recommended to do this and complete the test (described below) prior to closing the shell you ran the installation script in, just in case you run into issues and need to refer to any output it provided.
4.2 | Test the development shell
To test that the development shell is active, you will need to move to the
repository's directory. If you installed and properly configured direnv for
automatic activation, the shell should activate upon changing directories.
{ test -n "$IN_NIX_SHELL" && echo "ACTIVE"; } || echo "INACTIVE"
If you have activated the development shell, you will see ACTIVE printed to
the console. If you have not, you will see INACTIVE printed to the console.
Useful development commands
make build- buildgit-bugand output the binary at./git-bugmake build/debug- build a debugger-friendly binary
make install- buildgit-bug, and install it to$GOPATH/binnix fmt- format everything (configured in//:treefmt.nix)nix fmt <path...>to restrict the scope to given directories or files- see 
nix fmt --helpfor more information 
nix flake checkto run lint/format checks and all tests defined in//nix/checksgo generate- generate cli documentation and shell completion files- this is automatically executed by many 
maketargets, e.g.make build 
- this is automatically executed by many 
 go test ./commands -update- update golden files used in tests- this is required when changing the output of CLI commands, if the files in
//commands/testdata/...do not match the new output format 
- this is required when changing the output of CLI commands, if the files in
 pinactto pin any newly-added github action librariespinact upgradeto upgrade action libraries
[!NOTE] There is an ongoing effort to simplify the commands you need to call in our environment, with a trend toward
nix, whilemakemay continue to be supported for common workflows (e.g. building a release binary).
Submitting changes
You can submit your changes in the typical fork-based workflow to this repository on GitHub. That is: fork this repository, push to a branch to your repository, and create a pull request.
If you are in the development shell, you have the gh command line tool
available for use with github.
Push early, push often
We encourage pushing small changes. There is no such thing as a contribution being "too small". If you're working on a big feature or large refactor, we encourage you to think about how to introduce it incrementally, in byte-sized chunks, and submit those smaller changes frequently.
Pull requests are squashed
All Pull Requests in this repository are squash merged. The resulting commit's subject and body is set as such:
- The subject is set to the PR title, appended with the PR's number
 - The body is set to the contents of the PR description, otherwise known as the first comment in the "Discussion" tab
 
Draft vs Ready
Pull Requests can be marked as "ready for review", or as a "draft". Drafts are less likely to get reviewed, for the simple fact that in English, the word "draft" (in relation to a change) implies that the work is not yet ready, or still being worked on. That said, we encourage you to iterate locally, especially if you are in the earlier stages of a change.
Any PR, even a draft, triggers the pipelines to run our test suite. Note, however, that due to the cost (in terms of time and finance) associated with running the pipelines, we may, at our discretion, exclude various parts of our test suite from draft PRs.
Singular unit of change
Please keep any one PR limited to a singular unit of change. That is, do your best to avoid making multiple different changes in the same tree / PR. This helps make it simpler to reason about a change during review, and reduces the chance that your proposal ends up spawning five different conversations that each dig down their own rabbit hole.
Good examples of a singular unit of change:
- Renaming a function (or method or class or interface or...)
 - Adding a new endpoint
 - Deprecating a thing
 - Removing all of one type of thing (e.g. "remove all unused functions")
 
Aim to make sure that your change does one thing.
Examples of what we do not want to see in a given PR:
- Rename function Foo and add function Bar
 - Update Baz and Foo
 - Move Thing and upgrade Bar
 - Deprecate Zam and add a new function Zoo
 
Generally speaking, look out for the word "and". If you find yourself needing to write this word in a commit message when describing what your change does, consider whether it would be best to split those changes up into individual trees.