1# Contributing <a name="contributing"></a>
  2
  3:wave: Hey there! Thanks for considering taking the time to contribute to
  4`git-bug`. This page contains some general guidelines, and instructions for
  5getting started as a contributor to this project.
  6
  7<!-- mdformat-toc start --slug=github --maxlevel=4 --minlevel=2 -->
  8
  9- [Get the source code](#get-the-source-code)
 10- [Software requirements](#software-requirements)
 11  - [1.0 | Install nix](#10--install-nix)
 12  - [2.0 | Enable `nix-command` and `flakes`](#20--enable-nix-command-and-flakes)
 13  - [3.0 | Install and configure `direnv`](#30--install-and-configure-direnv)
 14- [4.0 | Post-installation tasks](#40--post-installation-tasks)
 15  - [4.1 | Open a new shell](#41--open-a-new-shell)
 16  - [4.2 | Test the development shell](#42--test-the-development-shell)
 17- [Useful development commands](#useful-development-commands)
 18- [Submitting changes](#submitting-changes)
 19  - [Push early, push often](#push-early-push-often)
 20  - [Pull requests are squashed](#pull-requests-are-squashed)
 21  - [Draft vs Ready](#draft-vs-ready)
 22  - [Singular unit of change](#singular-unit-of-change)
 23
 24<!-- mdformat-toc end -->
 25
 26## Get the source code<a name="get-the-source-code"></a>
 27
 28Clone this repository to your system in a way you're comfortable with. Below, we
 29show a command that clones the repository using SSH, and places it in
 30`~/code/git-bug`.
 31
 32```
 33git clone git@github.com:git-bug/git-bug ~/code/git-bug
 34```
 35
 36> [!TIP]
 37> If you wish to clone the repository to another location on disk, change
 38> `~/code/git-bug` to your desired path (e.g. your current directory can be used
 39> with `.` or by omitting the path argument). The rest of this documentation
 40> will refer to `~/code/git-bug` in all instances, so make sure you change them
 41> there to match the location you've cloned the repository.
 42
 43## Software requirements<a name="software-requirements"></a>
 44
 45This repository uses `nix` to provide a consistent development environment,
 46ensuring that each contributor has the same revision of each dependency and tool
 47installed. It is **strongly** encouraged to use `nix` when contributing to
 48`git-bug` to remove the "it works on my machine" class of errors, and ensure you
 49have a smoother experience passing the CI pipelines (wrt formatting and such).
 50
 51While you can manually install the [tools and packages we use](./flake.nix) and
 52hack on this project on your own, you will miss out on the hermeticity and
 53standardization that our development shell provides. You may end up fighting
 54with failing CI pipelines more often, or have to figure out how to perform
 55various tasks on your own. Using the development shell ensures you always have
 56every tool you need to contribute to `git-bug`, and that each tool is always
 57configured correctly.
 58
 59Because of this, we encourage all contributors to follow the documentation below
 60to install the dependencies for the development shell.
 61
 62> [!NOTE]
 63> In the future, we will provide a container image with `nix` pre-installed and
 64> everything configured to get you started. This will be able to be pulled like
 65> any other image, and will be made compatible with VSCode's "devcontainer"
 66> feature and GitHub Codespaces.
 67>
 68> For more information, see the [tracking issue][issue/1364].
 69
 70______________________________________________________________________
 71
 72### 1.0 | Install nix<a name="10--install-nix"></a>
 73
 74To install `nix`, you can follow [the official instructions][install/nix].
 75
 76We recommend following the instructions for `multi-user mode` where applicable,
 77instead of `single-user mode`.
 78
 79> [!IMPORTANT]
 80> The rest of this document assumes you have successfully installed `nix`.
 81
 82______________________________________________________________________
 83
 84### 2.0 | Enable `nix-command` and `flakes`<a name="20--enable-nix-command-and-flakes"></a>
 85
 86`nix-command` and `flakes` are two optional configuration properties that we
 87depend on in order to provide the development shell. You'll need to make sure
 88that these are enabled.
 89
 90<details>
 91<summary><strong>NixOS</strong></summary>
 92
 93Add the following to your system configuration:
 94
 95<pre>
 96nix.settings.experimental-features = [ "nix-command" "flakes" ];
 97</pre>
 98
 99</details>
100
101<details>
102<summary><strong>Other</strong></summary>
103
104Add the following to `~/.config/nix.conf` or `/etc/nix/nix.conf`:
105
106<pre>
107experimental-features = nix-command flakes
108</pre>
109
110</details>
111
112> [!IMPORTANT]
113> The rest of this document assume you have enabled these options.
114
115______________________________________________________________________
116
117### 3.0 | Install and configure `direnv`<a name="30--install-and-configure-direnv"></a>
118
119[`direnv`][install/direnv] can be used to automatically activate the development
120shell (using [`//:.envrc`][envrc]). It can be installed either with `nix`, or
121independently.
122
123<details>
124<summary><strong>With nix</strong> <em>(suggested for users new to nix)</em></summary>
125
126<pre>
127nix --extra-experimental-options 'flakes nix-command' profile install nixpkgs\#direnv
128</pre>
129
130Next, run the following commands to apply the **optional** configuration for
131direnv. Be sure to change references to `~/code/git-bug` if you have cloned the
132repository somewhere else.
133
134<strong>Create a configuration file for <code>direnv</code></strong>
135
136<pre>touch ~/.config/direnv/direnv.toml</pre>
137
138<strong>Disable the warning for shells with longer load times</strong>
139
140_This is optional, but recommended, as it helps reduce visual clutter._
141
142<pre>
143nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \
144  put -t int -v 0 ".global.warn_timeout"
145</pre>
146
147<strong>Disable printing of the environment variables that change</strong>
148
149_This is optional, but recommended, as it helps reduce visual clutter._
150
151<pre>
152nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \
153  put -t bool -v true ".global.hide_env_diff"
154</pre>
155
156<strong>Configure automatic activation of the development shell</strong>
157
158_This is optional, but strongly recommended._
159
160<pre>
161nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv.toml \
162  put -v "~/code/git-bug/.envrc" ".whitelist.exact[]"
163</pre>
164
165Alternatively, simply run `direnv allow` after moving into the repository for
166the first time.
167
168> **IMPORTANT**<br /> If you choose not to allow the shell to be automatically
169> activated, you will need to type `nix develop` every time you want to activate
170> it, and this will swap you into bash and change your prompt. You'll have a far
171> better experience allowing `direnv` to automatically manage activation and
172> deactivation.
173
174<strong>Configure your shell</strong>
175
176This final step is crucial -- be sure to
177[configure your shell][install/direnv/shell] for direnv.
178
179</details>
180
181<details>
182<summary><strong>Using <code>home-manager</code></strong></summary>
183
184<pre>
185programs.direnv = {
186  enable = true;
187  nix-direnv.enable = true;
188
189  # one of the following, depending on your shell
190  # enableZshIntegration = true;
191  # enableBashIntegration = true;
192  # enableFishIntegration = true;
193  # enableNushellIntegration = true;
194
195  config = {
196    hide_env_diff = true;
197    warn_timeout = 0;
198
199    whitelist.exact = [ "~/code/git-bug/.envrc" ];
200  };
201}
202</pre>
203
204</details>
205
206______________________________________________________________________
207
208## 4.0 | Post-installation tasks<a name="40--post-installation-tasks"></a>
209
210Congratulations! If you've reached this section of the documentation, chances
211are that you have a working development environment for contributing to this
212repository. Read below for some additional tasks you should complete.
213
214### 4.1 | Open a new shell<a name="41--open-a-new-shell"></a>
215
216In order for the installation to take effect, you will need to open a new shell.
217It is recommended to do this and complete the test (described below) prior to
218closing the shell you ran the installation script in, just in case you run into
219issues and need to refer to any output it provided.
220
221### 4.2 | Test the development shell<a name="42--test-the-development-shell"></a>
222
223To test that the development shell is active, you will need to move to the
224repository's directory. If you installed and properly configured `direnv` for
225automatic activation, the shell should activate upon changing directories.
226
227```
228{ test -n "$IN_NIX_SHELL" && echo "ACTIVE"; } || echo "INACTIVE"
229```
230
231If you have activated the development shell, you will see `ACTIVE` printed to
232the console. If you have not, you will see `INACTIVE` printed to the console.
233
234______________________________________________________________________
235
236## Useful development commands<a name="useful-development-commands"></a>
237
238- `make build` - build `git-bug` and output the binary at `./git-bug`
239  - `make build/debug` - build a debugger-friendly binary
240- `make install` - build `git-bug`, and install it to `$GOPATH/bin`
241- `nix fmt` - format everything (configured in [`//:treefmt.nix`][treefmt])
242  - `nix fmt <path...>` to restrict the scope to given directories or files
243  - _see `nix fmt --help` for more information_
244- `nix flake check` to run lint/format checks and all tests defined in
245  `//nix/checks`
246- `go generate` - generate cli documentation and shell completion files
247  - this is automatically executed by many `make` targets, e.g. `make build`
248- `go test ./commands -update` - update golden files used in tests
249  - this is _required_ when changing the output of CLI commands, if the files in
250    `//commands/testdata/...` do not match the new output format
251- `pinact` to pin any newly-added github action libraries
252  - `pinact upgrade` to upgrade action libraries
253
254> [!NOTE]
255> There is an ongoing effort to simplify the commands you need to call in our
256> environment, with a trend toward `nix`, while `make` may continue to be
257> supported for common workflows (e.g. building a release binary).
258
259## Submitting changes<a name="submitting-changes"></a>
260
261You can submit your changes in the typical fork-based workflow to this
262repository on GitHub. That is: fork this repository, push to a branch to your
263repository, and create a pull request.
264
265If you are in the development shell, you have the `gh` command line tool
266available for use with github.
267
268### Push early, push often<a name="push-early-push-often"></a>
269
270We encourage pushing small changes. There is no such thing as a contribution
271being "too small". If you're working on a big feature or large refactor, we
272encourage you to think about how to introduce it incrementally, in byte-sized
273chunks, and submit those smaller changes frequently.
274
275### Pull requests are _squashed_<a name="pull-requests-are-squashed"></a>
276
277All Pull Requests in this repository are _squash merged_. The resulting commit's
278subject and body is set as such:
279
280- The subject is set to the PR title, appended with the PR's number
281- The body is set to the contents of the PR description, otherwise known as the
282  first comment in the "Discussion" tab
283
284### Draft vs Ready<a name="draft-vs-ready"></a>
285
286Pull Requests can be marked as "ready for review", or as a "draft". Drafts are
287less likely to get reviewed, for the simple fact that in English, the word
288"draft" (in relation to a change) implies that the work is not yet ready, or
289still being worked on. That said, we encourage you to iterate locally,
290especially if you are in the earlier stages of a change.
291
292Any PR, even a draft, triggers the pipelines to run our test suite. Note,
293however, that due to the cost (in terms of time and finance) associated with
294running the pipelines, we may, at our discretion, exclude various parts of our
295test suite from draft PRs.
296
297### Singular unit of change<a name="singular-unit-of-change"></a>
298
299Please keep any one PR limited to a singular unit of change. That is, do your
300best to avoid making multiple different changes in the same tree / PR. This
301helps make it simpler to reason about a change during review, and reduces the
302chance that your proposal ends up spawning five different conversations that
303each dig down their own rabbit hole.
304
305Good examples of a singular unit of change:
306
307- Renaming a function (or method or class or interface or...)
308- Adding a new endpoint
309- Deprecating a thing
310- Removing all of one type of thing (e.g. "remove all unused functions")
311
312Aim to make sure that your change does _one_ thing.
313
314Examples of what we _do not_ want to see in a given PR:
315
316- Rename function Foo and add function Bar
317- Update Baz and Foo
318- Move Thing and upgrade Bar
319- Deprecate Zam and add a new function Zoo
320
321Generally speaking, look out for the word "and". If you find yourself needing to
322write this word in a commit message when describing what your change does,
323consider whether it would be best to split those changes up into individual
324trees.
325
326______________________________________________________________________
327
328##### See more
329
330- [View the commit message guidelines][doc/contrib/commit]
331- [An overview of the architecture][doc/design/arch]
332- [Learn about the data model][doc/design/model]
333- [See how to create a new entity][example-entity]
334
335[doc/contrib/commit]: ./doc/contrib/commit-message-guidelines.md
336[doc/design/arch]: ./doc/design/architecture.md
337[doc/design/model]: ./doc/design/data-model.md
338[envrc]: ./.envrc
339[example-entity]: ./entity/dag/example_test.go
340[install/direnv]: https://github.com/direnv/direnv/blob/master/docs/installation.md
341[install/direnv/shell]: https://github.com/direnv/direnv/blob/master/docs/hook.md
342[install/nix]: https://nix.dev/install-nix
343[issue/1364]: https://github.com/git-bug/git-bug/issues/1364
344[treefmt]: ./treefmt.nix