Development:Workflow

From OpenLP
Jump to: navigation, search

Introduction

In OpenLP we'll be using the following workflow. This allows us to work efficiently, keep our code at it's best, work independently and keep features isolated.

If you haven't yet read the page on Bazaar, it is recommended that you do that before reading this page.

Utilities that help

For those who like GUI's, you can download and install Bazaar Explorer for Linux, Windows and Mac OS X.

Test-Driven Development

When we first developed OpenLP we decided not to write tests "to get the first release out faster." This was a bad idea and we're paying for it now. The codebase has numberous bugs and structural issues which decent tests from the beginning could have prevented. In order to help prevent further problems, we now try to practice an informal form of Test-Driven Development.

Writing Tests

Thanks to our absence of tests historically, we have a huge amount of technical debt in unwritten tests. In order to lessen this technical debt, every single merge is required to contain at least one new test. Ideally, if you are adding a feature, your feature should be thoroughly tested. The only way to know something works properly is to write tests for it.

Take a look at our page on writing tests for more in-depth information.

Code Coverage

At the time of writing we have 48% of our codebase covered by tests. This number should obviously be 100% but it's not going to be an overnight transformation. Use the coverage plugin for nose to see which lines are covered, and which are not.

CodeCoverage.png

One of the great things about viewing the code coverage is that it gamifies writing tests.

Version Control Workflow

The core of the development workflow is the version control workflow.

Diagram

Here's a diagram to help you understand how the workflow works:

Workflows gatekeeper.png

Getting Started

The first thing you'll want to do is to create a shared repository. This is a directory that holds all our branches, and a shared history (which means everything takes up less disk space).

I'm going to create this shared repository in my Projects directory:

@:~$ cd Projects
@:~/Projects$ bzr init-repo openlp

Now that I've created this shared repository, I'm going to check out the trunk. This is the main branch where all the other branches are merged into.

@:~/Projects$ cd openlp
@:~/Projects/openlp$ bzr checkout lp:openlp trunk

Great! Now I have a directory called trunk in my ~/Projects/openlp directory, which contains the main branch of all the code. (note "lp:" is telling bzr to look on Launchpad for the openlp project).

Please note: You cannot commit or push to trunk. Trunk is read-only for anyone other than the OpenLP Core team.

Branching

When you want to do some work in a particular area, or on a particular area, you'll want to create a new branch for this work. Once this branch is created, you'll work in it until you've completed what you set out to do.

First make sure your checkout of trunk is up to date:

@:~/Projects/openlp/trunk$ bzr update

Now let's create a new branch:

@:~/Projects/openlp$ bzr branch trunk dualdisplay

Great! Once this command is finished, I'll have a branch called dualdisplay. Now I can work in this branch until I've got all the dual display code looking and working nicely. Note that this branch only exists in my local repository at this point.

Committing

When I've made some changes, and they work, and I'm happy with them, I can commit my changes to this branch so that I create a new revision, and I don't lose the changes. Committing changes only updates my local repository, it does not share the changes with anyone else.

@:~/Projects/openlp/dualdisplay$ bzr commit -m "fixed spelling"

or when you are fixing a bug:

@:~/Projects/openlp/dualdisplay$ bzr commit -m "fixed bug #12345 'Crash on Start up'" --fixes lp:12345

Run Tests Locally

Before you can submit your code back to the project, you need to make sure your changes are working and you haven't broken anything else. For this you need to write unit tests, and then run them.

If all the tests pass, including your own, you can push the code up the Launchpad.

Pushing

When my code is at a stage where I want to merge it with the trunk code, I first need to push it up to Launchpad.net.

@:~/Projects/openlp/dualdisplay$ bzr push lp:~raoul-snyman/openlp/dualdisplay

This command will create a publically viewable branch in my account on Launchpad. Then if I want this code merged with OpenLP's trunk, I need to go to Launchpad and propose a merged.

Remember that you can only push to your own account on Launchpad, but you can branch from anyone's account.

Running Your Tests on Jenkins

Before you can propose a merge, you need to run all the tests again, this time on our Continuous Integration server. If all the tests pass, you can propose a merge.

Proposing A Merge

Now you need to go to the OpenLP code page on Launchpad and look for your branch that you just pushed your code to. Click on the link there, and on the details page you should see a link a little way down that says "Propose for merging". Click on this link, and specify lp:openlp as the branch to merge this code into.

Once this merge proposal has been created, an e-mail is sent to the core team, who will then review your proposed merge. Once you have at least 2 approvals (and if you're part of the core team, you can't approve your own proposal!), one of the core team will merge your code to trunk and mark the proposal as merged.

Updating

Once the merge has happened, most folk will want to update their trunk.

@:~/Projects/openlp/trunk$ bzr update

If you want the latest changes from trunk in a branch that you are working on (please note, this is not necessary, bzr takes care of merging things like this), then you'll want to merge trunk into your branch. You can find out how to merge in the section below.

Merging

On some occasions, trunk will be updated while you are working in a separate branch, and you want to pull those changes from trunk across to your branch. This is how we get it right.

Firstly, you need to go to your copy of trunk.

@:~$ cd ~/Projects/openlp/trunk
@:~/Projects/openlp/trunk$

Then make sure your checkout of trunk is up to date:

@:~/Projects/openlp/trunk$ bzr update

Then you need to navigate to your branch:

@:~/Projects/openlp/trunk$ cd ../dualdisplay
@:~/Projects/openlp/dualdisplay$

Then merge from your local copy of trunk into your branch:

@:~/Projects/openlp/dualdisplay$ bzr merge ../trunk

Once you have merged, you will be a alerted to any possible conflicts in the merge. There are two ways to resolve these conflicts:

  1. Manually:
    Edit the conflicted file, and look for the conflicts and fix them up.
  2. Semi-Automatically:
    A really good tool to use on Linux is KDiff3, which can automatically merge most conflicts. Simply select your base, "mine" and "theirs" files, and the output file, and then choose what stays and what goes.

And once that is merged and all the conflicts are resolved, you'll need to commit.

@:~/Projects/openlp/dualdisplay$ bzr commit

Note for core developers:

If you are not the author of the changes, you need to specify the author of the merge.

@:~/Projects/openlp/trunk$ bzr commit --author "Spam Eggs <spam@eggs.org>"