The developer and maintainer corner

This chapter is a kind of unstructured “howto” that states the various development and maintenance rules for the hots project. The poor man’s quality assurance plan.

This chapter is opened to be restructured in the future.

Git workflow and life cycle

The “main” git branch

The “main” branch contains the source trees from which the public releases of the hots software products are built and distributed to the registries (PyPI, Docker hub, doc site).

Each release is identified by a Git tag named with the software distribution version.

The changes in the “main” branch are processed by merging the “dev” branch when all issues from a milestone are considered as fixed, tested and relevant documentation changes are written.

Warning

The only change allowed directly in this branch is the VERSION.txt file.

The “dev” branch

The “dev” branch contains the “bleeding edge” version of the hots software, tests and documentation.

The changes in the “dev” branch are processed by merging a personal branch when the issues from the personal branch are considered closed, and the unit tests don’t report any failure.

Warning

Only “quick fix” changes are allowed directly in the “dev” branch.

Personal branches

Personal branches are created by forking the dev branch, by individual developers in order to fix one or more issues.

The release cycle

Step 1: fork the “dev” branch in a personal branch

Refresh your clone of the dev branch:

git checkout dev
git pull

Step 2: create your personal branch:

git checkout -b <your-new-personal-branch>

Hint

The name of the branch must contain your name or nick, a very short title of the planned change and the issue numbers (usually only one).

Example: eleclercq-cmdline-24

Step 3: Share your changes to the “dev” branch

Your changes are done and tested. Time to share your work. You should first squash your commits in order to keep only the relevant ones. This blog article explains why and how to do it.

The “dev” branch may have changed since you forked it at step 2. In that case, you must replay these changes into your personal branch.

git co dev
git pull
git co <your-personal-branch>
git rebase dev

Important

This “rebase” operation may introduce silent conflicts. So make sure the unit tests don’t raise any failure after rebasing.

git push

Point your browser to the hots Git repository, then in the CI / CD ‣ Pipelines menu selection. You should see the progress of the CI / CD operations. Once the CI steps are successfully executed, you should issue a new merge request to share your work with your teammates.

Hint

The benefits of a merge request over a direct Git merge operation are:

  • All merges to “dev” are recorded in a shared place.

  • You may ask for a code review from your teammates before the merge is executed.

  • A “dry run” merge is executed such it identifies potential conflicts.

  • You and your teammates may browse the changes in details using the links in the merge request page.

Once the merge request is executed, you must inspect the CI / CD pipeline, and fix potential issues directly in the “dev” branch.

Tags and releases

When the dev branch is ready to be merged into the main branch, in most cases we would update the version (for a new feature, a bug fixed …). A new tag can then be created, and mostly a new release based on this tag. This tag should therefore match the version in “VERSION.txt” file which should have been updated.

Note

When a new push (mostly a merge request) happens in main branch with a new version number in “VERSION.txt” file, a new version of the package is published automatically to PyPi from GitHub.

Coding style

Code style

Code style must comply with “PEP 8 - Style Guide for Python code” requirements.

Python IDEs like PyCharm or Microsoft VSCode have an “autopep8” feature that helps you to keep this rule respected.

Comments

Inline comments (# …) must say what the code does in a high level view and not explain the language.

Bad examples:

# Increment the counter
counter += 1

# "+=" is the "add right to left" operator
counter += 1

Good example:

# Prepare to visit next item
counter += 1

The “good ratio” is about 1 line comment for 10 lines of code.

Type hints (PEP 484)

All functions and methods that take part of the public API must use type hints as described by the “PEP 484 - Type hints” document.

This is an essential help for the code documentation as well as an IDE helper for completions.

Example:

def is_closed(handle: int) -> bool:
    """
    Checks a stuff is closed
    ...
    """

Docstrings

Docstrings of public API resources will be written in ReStructuredText and may be processed by Sphinx exactly like the lines you are reading.

In addition, the descriptions of relevant arguments, keyword arguments, attributes, exceptions, (…) will be expressed using the Google style.

Example:

from decimal import Decimal

class BankAccount:
    """Person or company bank account

    Attributes:
        holder: The possessing person or company.
        balance: actual account amount
    """
    def __init__(self, holder: AccountHolder) -> None:
        self.holder = holder
        self.balance: Decimal = Decimal("0.00")

    def credit(self, value: Decimal) -> Decimal:
        """Add a value to the balance

        Args:
            value: to be added to the balance (may be < 0)

        Returns:
            Updated balance

        Raises:
            ValueError: if the resulting amount below 0
        """
        if self.balance + value < 0:
            raise ValueError("Negative balance is forbidden, operation will be canceled")
        self.balance += value
        return self.balance

Running the tests

The unit tests are executed through the pytest command. The default options sit in the pyproject.toml file. The tests codes and resources are hosted in the tests/... directory.

As above stated, the unit tests are powered by the third party pytest tool.