Skip to content
This repository has been archived by the owner on Aug 10, 2023. It is now read-only.

Latest commit

 

History

History
195 lines (148 loc) · 8.67 KB

CONTRIBUTING.md

File metadata and controls

195 lines (148 loc) · 8.67 KB

Thanks for your interest in contributing to our project.

How to contribute to INLOOP

Report bugs or suggest new features

INLOOP is made by humans and humans make mistakes. We encourage anyone to open issues in our issue tracker. Bug reports should clearly describe the problem and include a step by step description on how to reliably reproduce the problem.

Submit pull requests

This is the preferred way of contributing. We also use this approach (aka the Github flow) internally to peer review changes.

  1. Fork our repo and create a branch for the feature or bugfix. The branch name should be descriptive and in kebab case, i.e., all lowercase with - separating words. It should begin with the GitHub issue number (if any). For example: refactor-html, add-registration-tests or 123-refactor-js-code.
  2. Add commits and be sure to follow our rules for commit messages. Don't mix unrelated changes into one commit.
  3. Open a pull request so we can review the changes and give feedback. Additionally, our CI will check if the test suite succeeds.

New code needs to include unit tests, documentation and must follow our coding conventions.

Git setup

If not done already, configure your real name and email:

git config --global user.name "John Doe"
git config --global user.email [email protected]

Apply the following configuration to your local Git clone of INLOOP:

git config merge.ff false
git config pull.rebase true

Python dependency management

We use poetry to manage Python dependencies. The tool reads and saves requirements from and to pyproject.toml and poetry.lock files. The latter one contains exact versions and hashes of all dependencies (transitive deps included), ensuring reproducible installations.

Most important poetry commands

  • Add a dependency: poetry add some-package.
    • Use poetry add --dev some-package if your package is only needed during development.
  • Add a dependency with a version constraint: poetry add some-package@^1.2.3.
    • This can also be used to update the version constraint of an existing dependency, e.g., when moving from Django 1.11 to 2.0.
    • Check the poetry manual for details about possible constraints.
    • Beware, zsh users: you should escape the caret (^) symbol used in caret constraints.
  • Update a dependency: poetry update some-package.
    • In other words, this updates the pinned version in poetry.lock.
    • Keep in mind that the version constraints in pyproject.toml still apply.
  • Update poetry itself: poetry self update.
    • This will only work if poetry was installed with the recommended installation method and not with pip or pipx.
    • In our CI setup, poetry is installed with pip and the version is pinned in tools/ci-requirements.txt.

Dependency update process

General rules:

  • Update dependencies individually.
  • Perform work on an isolated branch, e.g., update-dependencies.
  • Create separate commits for individual version changes in poetry.lock.

Steps:

  1. Update the given dependency, let's say Django: poetry update django.
  2. Ensure tests succeed locally: make test.
  3. Review the changes to poetry.lock with git diff and note the version before and after the change.
  4. Commit changes with a commit message of the form: Bump django from 1.11.28 to 1.11.29, i.e., "Bump X from Y to Z".
  5. Push the branch, create a PR and wait for the CI to finish its checks.

Upgrading Django major or minor versions

In our pyproject.toml, the Django version is specified with a "tilde constraint" to avoid automatic switches to the next minor or major version, e.g., from 1.11.x to 1.12.y or from 1.11.x to 2.0.y.

Thus, poetry update django will at most update the patch version, e.g., from 1.11.28 to 1.11.29.

The reason for this is that major or minor Django version upgrades should only be done manually with careful review of the release notes and thorough testing.

For a major or minor upgrade, you need to run poetry add again with an updated version constraint. For example, to upgrade from the current Django 1.11 to the latest version, run poetry add django@latest. This will update pyproject.toml in addition to poetry.lock, and thus both need to be included in your "Bump django …" commit (see previous section).

Rules for contributing code

Size your PRs

Do one thing at a time and don't bite off more than you can chew. Long living branches are usually a sign that a feature needs to be split up. Furthermore, chances are high that such a branch will be hard to integrate into main. Divide and conquer!

Coding conventions

  • Use an editor that understands our .editorconfig file. This ensures all contributions conform to the same indentation style, maximum line length, encoding etc.
  • All languages – write code that's easy to read:
    • Keep functions/methods small (ideally half a screen page). Split if necessary.
    • Separate data from code as much as possible.
    • Document what your code does in doc comments (not how it does something).
  • Python:
    • Use Python 3.
    • Code must be (auto-)formatted according to the black code style (which in turn formats code to conform to PEP-8) and a maximum line length of 99 characters.
      • This will be enforced by the CI build.
      • Be sure to configure your editor to do this for you. Modern editors such as VS Code can be configured to automatically invoke the black code formatter when a file is saved.
    • Don't use relative imports.
    • Docstrings must follow the Google Python Style Guide for Comments and be surrounded by three double quotes ("""). Don't use reStructured Text style comments.
  • HTML (Django templates):
    • Don't use XML style empty tags (good: <br>, bad: <br />).
    • Use the W3C Nu validator to verify that the output of processed templates is valid HTML5.
  • JavaScript:
    • New code should use modern JavaScript, a.k.a. ECMAScript 2015 or ES6.
      • Start JS files with "use strict";.
      • Write classes with the class syntax.
      • Prefer let over var, use const whenever possible.
      • Use arrow function expressions where appropriate.
    • Use the new APIs: Promise API, Fetch API, etc.
    • Avoid deep nesting.
    • Avoid polluting the global namespace (window).
    • Avoid inline scripts (i.e., inside <script> tags).
    • Don't use jQuery if there's an easy JS-native way to do it.
    • Docstrings must follow the JSDoc documentation specifications.

Commit messages

Rules (courtesy of Chris Beams):

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why (not how)

Model message (based on Tim Pope's):

Capitalized, short (50 chars or less) summary

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

- Bullet points are possible, too
- Another bullet point

Fixes: #123
See also: #456, #789

For example, take a look at the following commits in our repo: