xref: /openbmc/docs/CONTRIBUTING.md (revision 146f9098)
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
149If the feedback seems favorable or requests more details, continue
150by submitting the design to gerrit starting with a copy of the
151[design_template](https://github.com/openbmc/docs/blob/master/designs/design-template.md).
152
153Submitting changes
154------------------
155
156We use git for almost everything. Most projects in OpenBMC use Gerrit to review
157patches. Changes to an upstream project (e.g. Yocto Project, systemd, or the
158Linux kernel) might need to be sent as patches or a git pull request.
159
160### Organizing Commits
161
162A good commit does exactly one thing. We prefer many small, atomic commits to
163one large commit which makes many functional changes.
164 - Too large: "convert foo to new API; also fix CVE 1234 in bar"
165 - Too small: "move abc.h to top of include list" and "move xyz.h to bottom of
166   include list"
167 - Just right: "convert foo to new API" and "convert foo from tab to space"
168
169Other commit tips:
170 - If your change has a specification, sketch out your ideas first
171   and work to get that accepted before completing the details.
172 - Work at most a few days before seeking review.
173 - Commit and review header files before writing code.
174 - Commit and review each implementation module separately.
175
176Often, creating small commits this way results in many commits that are
177dependent on prior commits; Gerrit handles this situation well, so feel free to
178push commits which are based on your change still in review. However, when
179possible, your commit should stand alone on top of master - "Fix whitespace in
180bar()" does not need to depend on "refactor foo()". Said differently, ensure
181that topics that are not related to each other semantically are also not
182related to each other in Git until they are merged into master.
183
184When pushing a stack of patches, these commits will show up with that same
185relationship in Gerrit. This means that each patch must be merged in order of
186that relationship. So if one of the patches in the middle needs to be changed,
187all the patches from that point on would need to be pushed to maintain the
188relationship. This will effectively rebase the unchanged patches, which would
189in turn trigger a new CI build. Ideally, changes from the entire patchset could
190be done all in one go to reduce unnecessary rebasing.
191
192When someone makes a comment on your commit in Gerrit, modify that commit and
193send it again to Gerrit. This typically involves `git rebase --interactive` or
194`git commit --amend`, for which there are many guides online. As mentioned in
195the paragraph above, when possible you should make changes to multiple patches
196in the same stack before you push, in order to minimize CI and notification
197churn from the rebase operations.
198
199Commits which include changes that can be tested by a unit test should also
200include a unit test to exercise that change, within the same commit. Unit tests
201should be clearly written - even more so than production code, unit tests are
202meant primarily to be read by humans - and should test both good and bad
203behaviors. Refer to the
204[testing documentation](https://github.com/openbmc/docs/blob/master/testing/local-ci-build.md)
205for help writing tests, as well as best practices.
206
207Ensure that your patch doesn't change unrelated areas. Be careful of
208accidental whitespace changes - this makes review unnecessarily difficult.
209
210### Formatting Commit Messages
211
212Your commit message should explain:
213
214 - Concisely, *what* change are you making? e.g. "libpldm: Add APIs to enable
215   PLDM Requester" This first line of your commit message is the subject line.
216 - Comprehensively, *why* are you making that change? In some cases, like a
217   small refactor, the why is fairly obvious. But in cases like the inclusion of
218   a new feature, you should explain why the feature is needed.
219 - Concisely, *how* did you test? (see below).
220
221Try to include the component you are changing at the front of your subject line;
222this typically comes in the form of the class, module, handler, or directory you
223are modifying. e.g. "apphandler: refactor foo to new API"
224
225Loosely, we try to follow the 50/72 rule for commit messages - that is, the
226subject line should not exceed 50 characters and the body should not exceed 72
227characters. This is common practice in many projects which use Git.
228
229All commit messages must include a "Signed-off-by" line, which indicates that
230you the contributor have agreed to the Developer Certificate of Origin
231(see below). This line must include the full name you commonly use, often a
232given name and a family name or surname. (ok: Sam Samuelsson, Robert A.
233Heinlein; not ok: xXthorXx, Sam, RAH)
234
235### Testing
236
237Each commit is expected to be tested. The expectation of testing may vary from
238subproject to subproject, but will typically include running all applicable
239automated tests and performing manual testing. Each commit should be tested
240separately, even if they are submitted together (an exception is when commits
241to different projects depend on each other).
242
243Commit messages should include a "Tested" field describing how you tested the
244code changes in the patch. Example:
245```
246    Tested: I ran unit tests with "make check" (added 2 new tests) and manually
247    tested on Witherspoon that Foo daemon no longer crashes at boot.
248```
249
250If the change required manual testing, describe what you did and what happened;
251if it used to do something else before your change, describe that too.  If the
252change can be validated entirely by running unit tests, say so in the "Tested:"
253field.
254
255### Linux Kernel
256
257The guidelines in the Linux kernel are very useful:
258
259https://www.kernel.org/doc/html/latest/process/submitting-patches.html
260
261https://www.kernel.org/doc/html/latest/process/submit-checklist.html
262
263Your contribution will generally need to be reviewed before being accepted.
264
265
266Submitting changes via Gerrit server to OpenBMC
267-----------------------------------------------
268
269The OpenBMC Gerrit server supports GitHub credentials, its link is:
270
271  https://gerrit.openbmc-project.xyz/#/q/status:open
272
273_One time setup_: Login to the WebUI with your GitHub credentials and verify on
274your Account Settings that your SSH keys were imported:
275
276  https://gerrit.openbmc-project.xyz/#/settings/
277
278Most repositories are supported by the Gerrit server, the current list can be
279found under Projects -> List:
280
281  https://gerrit.openbmc-project.xyz/#/admin/projects/
282
283If you're going to be working with Gerrit often, it's useful to create an SSH
284host block in ~/.ssh/config. Ex:
285```
286Host openbmc.gerrit
287        Hostname gerrit.openbmc-project.xyz
288        Port 29418
289        User your_github_id
290```
291
292From your OpenBMC git repository, add a remote to the Gerrit server, where
293'openbmc_repo' is the current git repository you're working on, such as
294phosphor-state-manager, and 'openbmc.gerrit' is the name of the Host previously
295added:
296
297  `git remote add gerrit ssh://openbmc.gerrit/openbmc/openbmc_repo`
298
299Alternatively, you can encode all the data in the URL:
300
301  `git remote add gerrit ssh://your_github_id@gerrit.openbmc-project.xyz:29418/openbmc/openbmc_repo`
302
303Then add the default branch for pushes to this remote:
304
305  `git config remote.gerrit.push HEAD:refs/for/master`
306
307Gerrit uses [Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html) to identify commits that belong to the same
308review.  Configure your git repository to automatically add a
309Change-Id to your commit messages.  The steps are:
310
311  `gitdir=$(git rev-parse --git-dir)`
312
313  `scp -p -P 29418 openbmc.gerrit:hooks/commit-msg ${gitdir}/hooks`
314
315To submit a change set, commit your changes, and push to the Gerrit server,
316where 'gerrit' is the name of the remote added with the git remote add command:
317
318  `git push gerrit`
319
320Sometimes you need to specify a topic (especially when working on a
321feature that spans across few projects) or (un)mark the change as
322Work-in-Progress. For that refer to [Gerrit
323documentation](https://gerrit-review.googlesource.com/Documentation/intro-user.html#topics).
324
325Gerrit will show you the URL link to your review.  You can also find
326your reviews from the [OpenBMC Gerrit server](https://gerrit.openbmc-project.xyz) search bar
327or menu (All > Open, or My > Changes).
328
329Invite reviewers to review your changes.  Each OpenBMC repository has
330a `MAINTAINERS` file that lists required reviewers who are subject
331matter experts.  Those reviewers may add additional reviewers.  To add
332reviewers from the Gerrit web page, click the "add reviewers" icon by
333the list of reviewers.
334
335You are expected to respond to all comments.  And remember to use the
336"reply" button to publish your replies for others to see.
337
338The review results in the proposed change being accepted, rejected for
339rework, or abandoned.  When you re-work your change, remember to use
340`git commit --amend` so Gerrit handles the update as a new patch of
341the same review.
342
343Each repository is governed by a small group of maintainers who are
344leaders with expertise in their area.  They are responsible for
345reviewing changes and maintaining the quality of the code.  You'll
346need a maintainer to accept your change, and they will look to the
347other reviewers for guidance.  When accepted, your change will merge
348into the OpenBMC project.
349
350
351References to non-public resources
352----------------------------------------
353
354Code and commit messages shall not refer to companies' internal documents
355or systems (including bug trackers). Other developers may not have access to
356these, making future maintenance difficult.
357
358Code contributed to OpenBMC must build from the publicly available sources,
359with no dependencies on non-public resources (URLs, repositories, etc).
360
361Best practices for D-Bus interfaces
362----------------------------------
363
364 * New D-Bus interfaces should be reusable
365
366 * Type signatures should and use the simplest types possible, appropriate
367   for the data passed. For example, don't pass numbers as ASCII strings.
368
369 * D-Bus interfaces are defined in the `phosphor-dbus-interfaces` repository at:
370
371     https://github.com/openbmc/phosphor-dbus-interfaces
372
373See: http://dbus.freedesktop.org/doc/dbus-api-design.html
374
375
376Best practices for C
377--------------------
378
379There are numerous resources available elsewhere, but a few items that are
380relevant to OpenBMC work:
381
382 * Do not use `system(<some shell pipeline>)`. Reading and writing from
383   files should be done with the appropriate system calls.
384
385   Generally, it's much better to use `fork(); execve()` if you do need to
386   spawn a process, especially if you need to provide variable arguments.
387
388 * Use the `stdint` types (eg, `uint32_t`, `int8_t`) for data that needs to be
389   a certain size. Use the `PRIxx` macros for printf, if necessary.
390
391 * Don't assume that `char` is signed or unsigned.
392
393 * Beware of endian considerations when reading to & writing from
394   C types
395
396 * Declare internal-only functions as `static`, declare read-only data
397   as `const` where possible.
398
399 * Ensure that your code compiles without warnings, especially for changes
400   to the kernel.
401
402## Pace of Review
403
404Contributors who are used to code reviews by their team internal to their own
405company, or who are not used to code reviews at all, are sometimes surprised by
406the pace of code reviews in open source projects. Try to keep in mind that those
407reviewing your patch may be contributing to OpenBMC in a volunteer or
408partial-time capacity, may be in a timezone far from your own, and may
409have very deep review queues already of patches which have been waiting longer
410than yours. Do everything you can to make it easy for the reviewer to review
411your contribution.
412
413If you feel your patch has been missed entirely, of course, it's
414alright to email the maintainers (addresses available in MAINTAINERS file) or
415ping them on Discord - but a reasonable timeframe to do so is on the order of a
416week, not on the order of hours.
417
418The maintainers' job is to ensure that incoming patches are as correct and easy
419to maintain as possible. Part of the nature of open source is attrition -
420contributors can come and go easily - so maintainers tend not to put stock in
421promises such as "I will add unit tests in a later patch" or "I will be
422implementing this proposal by the end of next month." This often manifests as
423reviews which may seem harsh or exacting; please keep in mind that the community
424is trying to collaborate with you to build a patch that will benefit the project
425on its own.
426
427Developer's Certificate of Origin 1.1
428-------------------------------------
429
430    By making a contribution to this project, I certify that:
431
432    (a) The contribution was created in whole or in part by me and I
433        have the right to submit it under the open source license
434        indicated in the file; or
435
436    (b) The contribution is based upon previous work that, to the best
437        of my knowledge, is covered under an appropriate open source
438        license and I have the right under that license to submit that
439        work with modifications, whether created in whole or in part
440        by me, under the same open source license (unless I am
441        permitted to submit under a different license), as indicated
442        in the file; or
443
444    (c) The contribution was provided directly to me by some other
445        person who certified (a), (b) or (c) and I have not modified
446        it.
447
448    (d) I understand and agree that this project and the contribution
449        are public and that a record of the contribution (including all
450        personal information I submit with it, including my sign-off) is
451        maintained indefinitely and may be redistributed consistent with
452        this project or the open source license(s) involved.
453