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