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