FUN with Git

Git is used as a DVCS for every FUN project involving code or documentation. In this chapter, you will find how we use Git on a daily-basis to code and collaborate with the team.

If you are looking for a good introduction to Git, take a look at the Git In Practice book from Mike McQuaid.

Git conventions

Commit granularity

We tend to favor low granularity-but-consistent commits to a long series of commit. If you have multiple commits in a feature branch, it means that you had to address multiple issues to achieve your feature. We can run the test suite on every commit and it should always stay green 😎.

Commit message

We follow an emoji-driven commit message format adapted from Angular guidelines. A typical commit message should look like:

<type>(<scope>) <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Where type must be an emoji chosen from the gitmoji guide.

And the scope should point to the django application or stack component that may be affected, e.g.:

  • docker
  • apps:core
  • plugins:foo

The subject contains succinct description of the change:

  • use the imperative, present tense: "change" not "changed" nor "changes"
  • don't capitalize first letter
  • no dot (.) at the end

Just as in the subject, use the imperative, present tense for the body: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with the previous behavior.

The footer should contain any information about breaking changes and is also the place to reference GitHub/GitLab issues that this commit closes.

Breaking changes should start with the word BREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.

Git workflows

We use different workflows to handle collaborative coding with Git. The chosen workflow depends on the context and historical reasons. If you need more insights on popular Git worflows, we invite you to read this section of the Git in Practice book.

Open-source projects

For the sake of simplicity, to ease interaction with the community, we use the GitHub flow for open-source projects. In a few words:

  • the master branch is always stable and deployable,
  • tags from the master branch are considered as releases,
  • contributors have to fork or create a new feature-branch to work on (if they are allowed to in the original repository) and propose a pull request to merge their branch to master.

FUN private projects

Historically, we use Git Flow for internal projects. You will find plenty of resources on the web about this workflow, so in a few words:

  • the master branch is considered as a stable and always deployable branch,
  • the develop branch is a working branch where developped features are merged,
  • contributors have to work on feature-branch that will target the develop branch,
  • hotfix and release branches are merged to master and back-ported to develop,
  • release branches create tags on the master branch when they are closed.

Working with forges

Declaring issues

For now, new issues are declared in a dedicated Trello board. This is a temporary situation. In the following, we will describe how it should be 🤓

When declaring a new issue, please describe as much as possible the purpose of your issue, and eventually make a proposal on how it should be solved or investigated. Choose wisely a label for this issue and please do not assign someone to it (unless you already discussed with her verbally and had an agreement).

Working with pull requests (PR)

We recommend to create a pull request (PR) or merge request (MR) in GitLab semantic as soon as possible with the WIP flag preceding your PR title, e.g. WIP: 😎(docker) add mongo service.

When your work is done on this PR, remove the WIP flag and please ensure that:

  • your feature or fix is tested (all continuous integration tests should be green and code coverage should not decrease),
  • your feature is documented,
  • your branch is up-to-date with the target branch (it should be rebased and force-pushed).

Once all of those requirements are met, ask for a review of your code by assigning maintainers to your PR. Your changes should be approved by at least one contributor of the core team to be merged.

Last but not least, a code review should not take more than half an hour per PR to be profitable for everyone. It means that you have anticipated the amount of changes required to achieve your work. If those changes are bigger than 500 lines, then you may consider to split your feature in multiple PRs.

Note that the target branch (develop or master) will be write-protected, i.e. no one is allowed to push to it. Hence you will need to use the forge UI to merge your PR once all tests are green and your changes have been approved. Our PR merging strategy is: rebase and merge ; we do not want a merge commit.

Releasing new software version

Whatever the language you are using on a FUN project, cooking a new release (e.g. 4.18.1) should follow a standard procedure described below:

  1. Create a new branch named: release/4.18.1,

  2. Bump the release number in the appropriate file, i.e. for python projects, the setup.cfg (or __init__.py, depending on the way you handle your package version) and/or package.json for node-based projects,

  3. Update the project's Changelog following the keepachangelog recommandations,

  4. Commit your changes with a standard message title like: Bump release to 4.18.1,

  5. Open a pull or merge request depending on the current forge of the project,

  6. Wait for an approval from your peers,

  7. Merge your pull or merge request,

  8. Checkout and pull changes from the master branch,

  9. Tag & push your commit: git tag v4.18.1 && git push origin --tags

Checking project tags consistency

As we are only Humans, we are error-prone per se. To avoid tagging consistency errors, we recommend to integrate the following tests in the project's continuous integration workflow before publishing a new release:

# Get current tag corresponding commit ID
tag_commit=$(git rev-list -n 1 $CIRCLE_TAG)

# Check that the tag refer to a commit in the $TARGET_BRANCH (e.g.
# the master branch)
git branch -a --contains ${tag_commit} | grep ${TARGET_BRANCH}

# Check that the current tag (vX.Y.Z) matches the release number in
# setup.cfg (X.Y.Z)
grep "$(echo $CIRCLE_TAG | sed 's/^v/version = /')" setup.cfg

In this example script $CIRCLE_TAG is an environment variable defined by the contious integration platform (CircleCI in this case) with the pushed tag value, and, $TARGET BRANCH is the Git branch that should have been tagged (e.g. the master branch).

results matching ""

    No results matching ""