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