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