xref: /openbmc/docs/CONTRIBUTING.md (revision ba560cc31297caddfc157c540ae9e6d760d630e5)
1# Contributing to OpenBMC
2
3First off, thanks for taking the time to contribute! The following is a set of
4guidelines for contributing to an OpenBMC repository which are hosted in the
5[OpenBMC Organization](https://github.com/openbmc) on GitHub. Feel free to
6propose changes to this document.
7
8## Code of Conduct
9
10We enthusiastically adhere to our
11[Code of Conduct](https://github.com/openbmc/docs/blob/master/code-of-conduct.md).
12If you have any concerns, please check that document for guidelines on who can
13help you resolve them.
14
15## Inclusive Naming
16
17OpenBMC relies on the Open Compute Project to provide guidelines on inclusive
18naming. The OCP guidelines can be found here:
19
20<https://www.opencompute.org/documents/ocp-terminology-guidelines-for-inclusion-and-openness>
21
22## Structure
23
24OpenBMC has quite a modular structure, consisting of small daemons with a
25limited set of responsibilities. These communicate over D-Bus with other
26components, to implement the complete BMC system.
27
28The BMC's interfaces to the external world are typically through a separate
29daemon, which then translates those requests to D-Bus messages.
30
31These separate projects are then compiled into the final system by the overall
32'openbmc' build infrastructure.
33
34For future development, keep this design in mind. Components' functionality
35should be logically grouped, and keep related parts together where it makes
36sense.
37
38## Starting out
39
40Before you make a contribution, execute one of the OpenBMC Contributor License
41Agreements, _One time only_:
42
43- [Individual CLA](https://drive.google.com/file/d/1k3fc7JPgzKdItEfyIoLxMCVbPUhTwooY)
44- [Corporate CLA](https://drive.google.com/file/d/1d-2M8ng_Dl2j1odsvZ8o1QHAdHB-pNSH)
45
46If you work for someone, consider asking them to execute the corporate CLA. This
47allows other contributors that work for your employer to skip the CLA signing
48process, they can just be added to the existing CCLA Schedule A.
49
50After signing a CLA, send it to <manager@lfprojects.org>.
51
52If you're looking for a place to get started with OpenBMC, you may want to take
53a look at the issues tagged with 'bitesize'. These are fixes or enhancements
54that don't require extensive knowledge of the OpenBMC codebase, and are easier
55for a newcomer to start working with.
56
57Check out that list here:
58
59<https://github.com/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+user%3Aopenbmc+label%3Abitesize>
60
61If you need further details on any of these issues, feel free to add comments.
62
63Performing code reviews is another good way to get started. Go to
64<https://gerrit.openbmc.org> and click on the "all" and "open" menu items, or if
65you are interested in a particular repository - for example, "bmcweb" - type
66"status:open project:openbmc/bmcweb" into the search bar and press the "search"
67button. Then select a review. Remember to be positive and add value with every
68review comment.
69
70## Coding style
71
72Components of the OpenBMC sources should have a consistent style. If the source
73is coming from another project, we choose to follow the existing style of the
74upstream project. Otherwise, conventions are chosen based on the language.
75
76### Python
77
78Python source should all conform to PEP8. This style is well established within
79the Python community and can be verified with the 'pycodestyle' tool.
80
81<https://www.python.org/dev/peps/pep-0008/>
82
83### Python Formatting
84
85If a repository has a setup.cfg file present in its root directory, then CI will
86automatically verify the Python code meets the
87[pycodestyle](http://pycodestyle.pycqa.org/en/latest/intro.html) requirements.
88This enforces PEP 8 standards on all Python code.
89
90OpenBMC standards for Python match with PEP 8 so in general, a blank setup.cfg
91file is all that's needed. If so desired, enforcement of 80 (vs. the default 79)
92chars is fine as well:
93
94```toml
95[pycodestyle]
96max-line-length = 80
97```
98
99By default, pycodestyle does not enforce the following rules: E121, E123, E126,
100E133, E226, E241, E242, E704, W503, and W504. These rules are ignored because
101they are not unanimously accepted and PEP 8 does not enforce them. It is at the
102repository maintainer's discretion as to whether to enforce the aforementioned
103rules. These rules can be enforced by adding the following to the setup.cfg:
104
105```toml
106[pycodestyle]
107ignore= NONE
108```
109
110### JavaScript
111
112We follow the
113[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html).
114
115[Example .clang-format](https://www.github.com/openbmc/docs/blob/master/style/javascript/.clang-format)
116
117### HTML/CSS
118
119We follow the
120[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html).
121
122### C
123
124For C code, we typically use the Linux coding style, which is documented at:
125
126<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst>
127
128In short:
129
130- Indent with tabs instead of spaces, set at 8 columns
131
132- 80-column lines
133
134- Opening braces on the end of a line, except for functions
135
136This style can mostly be verified with 'astyle' as follows:
137
138```bash
139astyle --style=linux --indent=tab=8 --indent=force-tab=8
140```
141
142### C++
143
144See [C++ Style and Conventions](./cpp-style-and-conventions.md).
145
146## Planning changes
147
148If you are making a nontrivial change, you should plan how to introduce it to
149the OpenBMC development community.
150
151If you are planning a new function, you should get agreement that your change
152will be accepted. As early as you can, introduce the change via the OpenBMC
153Discord server or email list to start the discussion. You may find a better way
154to do what you need.
155
156If the feedback seems favorable or requests more details, continue by submitting
157the design to gerrit starting with a copy of the
158[design_template](https://github.com/openbmc/docs/blob/master/designs/design-template.md).
159
160## Submitting changes
161
162We use git for almost everything. Most projects in OpenBMC use Gerrit to review
163patches. Changes to an upstream project (e.g. Yocto Project, systemd, or the
164Linux kernel) might need to be sent as patches or a git pull request.
165
166### Organizing Commits
167
168A good commit does exactly one thing. We prefer many small, atomic commits to
169one large commit which makes many functional changes.
170
171- Too large: "convert foo to new API; also fix CVE 1234 in bar"
172- Too small: "move abc.h to top of include list" and "move xyz.h to bottom of
173  include list"
174- Just right: "convert foo to new API" and "convert foo from tab to space"
175
176Other commit tips:
177
178- If your change has a specification, sketch out your ideas first and work to
179  get that accepted before completing the details.
180- Work at most a few days before seeking review.
181- Commit and review header files before writing code.
182- Commit and review each implementation module separately.
183
184Often, creating small commits this way results in many commits that are
185dependent on prior commits; Gerrit handles this situation well, so feel free to
186push commits which are based on your change still in review. However, when
187possible, your commit should stand alone on top of master - "Fix whitespace in
188bar()" does not need to depend on "refactor foo()". Said differently, ensure
189that topics that are not related to each other semantically are also not related
190to each other in Git until they are merged into master.
191
192When pushing a stack of patches, these commits will show up with that same
193relationship in Gerrit. This means that each patch must be merged in order of
194that relationship. So if one of the patches in the middle needs to be changed,
195all the patches from that point on would need to be pushed to maintain the
196relationship. This will effectively rebase the unchanged patches, which would in
197turn trigger a new CI build. Ideally, changes from the entire patchset could be
198done all in one go to reduce unnecessary rebasing.
199
200When someone makes a comment on your commit in Gerrit, modify that commit and
201send it again to Gerrit. This typically involves `git rebase --interactive` or
202`git commit --amend`, for which there are many guides online. As mentioned in
203the paragraph above, when possible you should make changes to multiple patches
204in the same stack before you push, in order to minimize CI and notification
205churn from the rebase operations.
206
207Commits which include changes that can be tested by a unit test should also
208include a unit test to exercise that change, within the same commit. Unit tests
209should be clearly written - even more so than production code, unit tests are
210meant primarily to be read by humans - and should test both good and bad
211behaviors. Refer to the
212[testing documentation](https://github.com/openbmc/docs/blob/master/testing/local-ci-build.md)
213for help writing tests, as well as best practices.
214
215Ensure that your patch doesn't change unrelated areas. Be careful of accidental
216whitespace changes - this makes review unnecessarily difficult.
217
218### Formatting Commit Messages
219
220Your commit message should explain:
221
222- Concisely, _what_ change are you making? e.g. "libpldm: Add APIs to enable
223  PLDM Requester" This first line of your commit message is the subject line.
224- Comprehensively, _why_ are you making that change? In some cases, like a small
225  refactor, the why is fairly obvious. But in cases like the inclusion of a new
226  feature, you should explain why the feature is needed.
227- Concisely, _how_ did you test? (see below).
228
229Try to include the component you are changing at the front of your subject line;
230this typically comes in the form of the class, module, handler, or directory you
231are modifying. e.g. "apphandler: refactor foo to new API"
232
233Commit messages should follow the 50/72 rule: the subject line should not exceed
23450 characters and the body should not exceed 72 characters. This is common
235practice in many projects which use Git.
236
237Exceptions to this are allowed in the form of links, which can be represented in
238the form of:
239
240```markdown
241This implements [1]
242
243....
244
245[1]: https://openbmc.org/myverylongurl.
246```
247
248All commit messages must include a "Signed-off-by" line, which indicates that
249you the contributor have agreed to the Developer Certificate of Origin (see
250below). This line must include the full name you commonly use, often a given
251name and a family name or surname. (ok: Sam Samuelsson, Robert A. Heinlein; not
252ok: xXthorXx, Sam, RAH)
253
254### Testing
255
256Each commit is expected to be tested. The expectation of testing may vary from
257subproject to subproject, but will typically include running all applicable
258automated tests and performing manual testing. Each commit should be tested
259separately, even if they are submitted together (an exception is when commits to
260different projects depend on each other).
261
262Commit messages should include a "Tested" field describing how you tested the
263code changes in the patch. Example:
264
265```text
266    Tested: I ran unit tests with "make check" (added 2 new tests) and manually
267    tested on Witherspoon that Foo daemon no longer crashes at boot.
268```
269
270If the change required manual testing, describe what you did and what happened;
271if it used to do something else before your change, describe that too. If the
272change can be validated entirely by running unit tests, say so in the "Tested:"
273field.
274
275### Linux Kernel
276
277The guidelines in the Linux kernel are very useful:
278
279- <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>
280- <https://www.kernel.org/doc/html/latest/process/submit-checklist.html>
281
282Your contribution will generally need to be reviewed before being accepted.
283
284## Submitting changes via Gerrit server to OpenBMC
285
286The OpenBMC Gerrit server supports GitHub credentials, its link is:
287
288<https://gerrit.openbmc.org/#/q/status:open>
289
290_One time setup_: Login to the WebUI with your GitHub credentials and verify on
291your Account Settings that your SSH keys were imported:
292
293<https://gerrit.openbmc.org/#/settings/>
294
295Most repositories are supported by the Gerrit server, the current list can be
296found under Projects -> List:
297
298<https://gerrit.openbmc.org/#/admin/projects/>
299
300If you're going to be working with Gerrit often, it's useful to create an SSH
301host block in ~/.ssh/config. Ex:
302
303```text
304Host openbmc.gerrit
305        Hostname gerrit.openbmc.org
306        Port 29418
307        User your_github_id
308```
309
310From your OpenBMC git repository, add a remote to the Gerrit server, where
311'openbmc_repo' is the current git repository you're working on, such as
312phosphor-state-manager, and 'openbmc.gerrit' is the name of the Host previously
313added:
314
315`git remote add gerrit ssh://openbmc.gerrit/openbmc/openbmc_repo`
316
317Alternatively, you can encode all the data in the URL:
318
319`git remote add gerrit ssh://your_github_id@gerrit.openbmc.org:29418/openbmc/openbmc_repo`
320
321Then add the default branch for pushes to this remote:
322
323`git config remote.gerrit.push HEAD:refs/for/master`
324
325Gerrit uses
326[Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html)
327to identify commits that belong to the same review. Configure your git
328repository to automatically add a Change-Id to your commit messages. The steps
329are:
330
331```bash
332gitdir=$(git rev-parse --git-dir)
333curl https://gerrit.openbmc.org/tools/hooks/commit-msg -o ${gitdir}/hooks/commit-msg
334chmod +x ${gitdir}/hooks/commit-msg`
335```
336
337To submit a change set, commit your changes, and push to the Gerrit server,
338where 'gerrit' is the name of the remote added with the git remote add command:
339
340`git push gerrit`
341
342Sometimes you need to specify a topic (especially when working on a feature that
343spans across few projects) or (un)mark the change as Work-in-Progress. For that
344refer to
345[Gerrit documentation](https://gerrit-review.googlesource.com/Documentation/intro-user.html#topics).
346
347Gerrit will show you the URL link to your review. You can also find your reviews
348from the [OpenBMC Gerrit server](https://gerrit.openbmc.org) search bar or menu
349(All > Open, or My > Changes).
350
351Invite reviewers to review your changes. Each OpenBMC repository has an `OWNERS`
352file that lists required reviewers who are subject matter experts. Those
353reviewers may add additional reviewers. To add reviewers from the Gerrit web
354page, click the "add reviewers" icon by the list of reviewers.
355
356You are expected to respond to all comments. And remember to use the "reply"
357button to publish your replies for others to see.
358
359The review results in the proposed change being accepted, rejected for rework,
360or abandoned. When you re-work your change, remember to use `git commit --amend`
361so Gerrit handles the update as a new patch of the same review.
362
363Each repository is governed by a small group of maintainers who are leaders with
364expertise in their area. They are responsible for reviewing changes and
365maintaining the quality of the code. You'll need a maintainer to accept your
366change, and they will look to the other reviewers for guidance. When accepted,
367your change will merge into the OpenBMC project.
368
369## References to non-public resources
370
371Code and commit messages shall not refer to companies' internal documents or
372systems (including bug trackers). Other developers may not have access to these,
373making future maintenance difficult.
374
375Code contributed to OpenBMC must build from the publicly available sources, with
376no dependencies on non-public resources (URLs, repositories, etc).
377
378## Best practices for D-Bus interfaces
379
380- New D-Bus interfaces should be reusable
381
382- Type signatures should and use the simplest types possible, appropriate for
383  the data passed. For example, don't pass numbers as ASCII strings.
384
385- D-Bus interfaces are defined in the `phosphor-dbus-interfaces` repository at:
386
387<https://github.com/openbmc/phosphor-dbus-interfaces>
388
389See: <http://dbus.freedesktop.org/doc/dbus-api-design.html>
390
391## Best practices for C
392
393There are numerous resources available elsewhere, but a few items that are
394relevant to OpenBMC work:
395
396- Do not use `system(<some shell pipeline>)`. Reading and writing from files
397  should be done with the appropriate system calls.
398
399  Generally, it's much better to use `fork(); execve()` if you do need to spawn
400  a process, especially if you need to provide variable arguments.
401
402- Use the `stdint` types (eg, `uint32_t`, `int8_t`) for data that needs to be a
403  certain size. Use the `PRIxx` macros for printf, if necessary.
404
405- Don't assume that `char` is signed or unsigned.
406
407- Beware of endian considerations when reading to & writing from C types
408
409- Declare internal-only functions as `static`, declare read-only data as `const`
410  where possible.
411
412- Ensure that your code compiles without warnings, especially for changes to the
413  kernel.
414
415## Best practices for Systemd usage
416
417- Systemd services should be contained within the OpenBMC repository they are
418  associated with
419
420- Systemd services should list their dependencies using Wants/After to ensure
421  required service are started
422
423- If your repository provides a shared library, it should appropriately handle
424  any D-Bus dependencies it has
425
426  This may be clear documentation on what type of error or exception is returned
427  or it may be ensuring the required D-Bus service is automatically activated
428  upon calling it.
429
430- See this
431  [doc](https://github.com/openbmc/docs/blob/master/architecture/openbmc-systemd.md)
432  for more information on OpenBMC and its use of Systemd
433
434## Pace of Review
435
436Contributors who are used to code reviews by their team internal to their own
437company, or who are not used to code reviews at all, are sometimes surprised by
438the pace of code reviews in open source projects. Try to keep in mind that those
439reviewing your patch may be contributing to OpenBMC in a volunteer or
440partial-time capacity, may be in a timezone far from your own, and may have very
441deep review queues already of patches which have been waiting longer than yours.
442Do everything you can to make it easy for the reviewer to review your
443contribution.
444
445If you feel your patch has been missed entirely, of course, it's alright to
446email the maintainers (addresses available in OWNERS file) or ping them on
447Discord - but a reasonable timeframe to do so is on the order of a week, not on
448the order of hours.
449
450The maintainers' job is to ensure that incoming patches are as correct and easy
451to maintain as possible. Part of the nature of open source is attrition -
452contributors can come and go easily - so maintainers tend not to put stock in
453promises such as "I will add unit tests in a later patch" or "I will be
454implementing this proposal by the end of next month." This often manifests as
455reviews which may seem harsh or exacting; please keep in mind that the community
456is trying to collaborate with you to build a patch that will benefit the project
457on its own.
458
459## Developer's Certificate of Origin 1.1
460
461```text
462    By making a contribution to this project, I certify that:
463
464    (a) The contribution was created in whole or in part by me and I
465        have the right to submit it under the open source license
466        indicated in the file; or
467
468    (b) The contribution is based upon previous work that, to the best
469        of my knowledge, is covered under an appropriate open source
470        license and I have the right under that license to submit that
471        work with modifications, whether created in whole or in part
472        by me, under the same open source license (unless I am
473        permitted to submit under a different license), as indicated
474        in the file; or
475
476    (c) The contribution was provided directly to me by some other
477        person who certified (a), (b) or (c) and I have not modified
478        it.
479
480    (d) I understand and agree that this project and the contribution
481        are public and that a record of the contribution (including all
482        personal information I submit with it, including my sign-off) is
483        maintained indefinitely and may be redistributed consistent with
484        this project or the open source license(s) involved.
485```
486