Worklist + Github Integration

Intro
This article serves as brief synopsis of how the new Github-Worklist integration system works. Note that this guide only applies to projects where code can be tested on your local machine (iPhone, Android, native clients) and does not include any information about the sandbox environment we would normally use for a web app.

Git vs. SVN
For those of you who have not used git before, don't be scared. A biased comparison of Git vs SVN can be found here. The major thing for you to know is that git, unlike SVN, does not use a centralized repository. There are three repositories you'll be working with while you work on a worklist project.


 * 1) The worklist github account will house the master repository.
 * 2) Your github account will have a repository that is a fork of the worklist master repository.
 * 3) You will have a local repository on your computer that is a clone of your fork from github.

Worklist-Github flow
The first time you bid on a Github project on the worklist you will be asked to authorize the "worklist" application to use your Github account. This is required so that we can use the API to make fork/pull/merge requests on your behalf.

Before your first ever accepted bid on a Github Worklist project you will not yet have a fork of repository. We will therefore create a fork of Worklist's master repository in your Github account as soon as your first bid for a particular project is accepted. At this point you have a new git repository that has one branch, the master branch. It is a copy of the Worklist master repository at that point in time.

For any accepted bid on a Worklist Github project (wether it's the first or the 1000th) we will create a branch in your forked repository for the job that your bid was accepted on. The branch name will be the job number. It is branched from the Worklist's master repository for that project and therefore is an up to date version of the code for that project.

This branch is where you will perform all work required for that particular job.

Making modifications
To work on the project you'll need to clone the repository from your account on Github to your local machine. Once you've followed this guide to make sure that git is setup with your Github account it is as simple as running the following command.

This will clone your remote repository to whatever directory you ran the command in. ADDRESS_TO_GITHUB_REPO will be in one of the following formats (git@github.com:birarda/cp_ios.git, https://github.com/birarda/cp_ios.git).

You now have a local repository on your machine BUT BE CAREFUL. The local repository is likely currently on the master branch. All changes you make for a particular job should be made on the branch that has the job number as its name.

To see the branches in the repository you can type 'git branch -r'. The current branch is shown with a leading asterisk. The -r option allows you to see branches that are on your remote repository on github. Without that option you will only be shown branches in the local repository on your machine, which does not include the job specific branch until you've checked it out. To switch to a branch simply type.

Now that you've switched to the right branch you're good to go. Go ahead and make whatever changes you need to make to the code.

Once you believe that the code is ready you need to commit it to your local repository. A guide that covers creating, adding and committing files can be found here. This process is not extremely different than SVN. Make sure all of the files that you want included with the commit are tracked before committing. Contrary to our SVN convention, the commit message you add to your commit does not require the Worklist.net job number.

Now that the code has been committed to your local repository it must be pushed up to your remote repository on Github. This is done by using the  command.

Pulling in remote changes
If new changes have been merged to the Worklist master repo you'll need to pull them in before setting the job to REVIEW as your pull request cannot be pulled in unless you are up-to-date with the Worklist master repo on github.

NOTE: You can only pull in changes once any local modifications have been committed. Any additional changes you make while merging conflicts will be new commits to the branch that get included in the pull request.

In order to fetch the remote changes you need to add the Worklist's master repository for that project as a remote.

To add the Worklist repo as a remote repo you issue the following command. Note that you only need to run this command one time in your local repository, not each time you want to pull down remote changes.

Now that that Worklist's repository has been added as a remote you can use the following command to fetch any new changes from the master repo.

This will retrieve any commits from the Worklist's master that you do not have and store them in your local repo.

To bring these new commits into your current branch use the following command. If there are any merge conflicts they will be presented to you.

Note that you could also use  to fetch the changes and merge them immediately but I'd recommend against doing this as this setup causes git to try and solve the merge conflicts itself without allowing you to review them.

Resolving Conflicts
Sometimes when you pull in the changes from the Worklist's master repo there will be conflicts with your modifications. With regards to Xcode projects I'd recommend you use Xcode's tool for this as it makes handling the conflicts pretty easy. See the XCode integration section for information on that process.

If there are conflicts to resolve git will indicate that to you after performing  and. will show you the files that are in conflict.

At this point you can open up your editor and you will see in those files the code that is conflicting because it will be wrapped with arrow characters. Something like the following.

<<<<<<<<<<< HEAD

You'll be able to see from this which code was your local modification and which has been pulled down from Worklist HEAD. Simply rearrange the code to be the right combination of your modification and the upstream fetch.

You can also use a visual tool to resolve conflicts. Once you have one or more files in a conflicted state (after ) you can type. This will pull up the visual merge tool. The merge tool that is used will differ depending on your git settings / environment. On OS X the default is FileMerge, an uglier version of the tool used in Xcode. Use the visual merge tool to properly resolve the conflict.

No matter what the method you use once you resolve all conflicts you need to commit and push your changes to the remote repository. Even if you have no untracked changes you will still commit to say that merge conflicts have been handled. This puts your repo up-to-date with that latest fetch and means that we can pull in your pull request during REVIEW (as long as somebody's request hasn't been pulled in before you).

It is likely that you will get into situations where the code reviewer tells you to pull changes and commit and push so that your pull request can be pulled in automatically. Worklist repository admins will not handle the merge conflicts. This must be completed as part of the review process.

Xcode integration
As long as git is setup on your machine you can perform most of these tasks from within Xcode, if you prefer.

The local and remote repositories can be modified via the Organizer (Window->Organizer). Committing, pushing and pulling in remote changes can be done via the Source Control menu (File->Source Control)

If you use public key authentication with github anything you've already setup via the command line should work without any changes on your part. If you use traditional username-password authentication you may need to attach those credentials to your origin remote and the upstream remote in the Organizer.

I would recommend that you definitely use Xcode to pull in remote changes since the visual merge tool it uses is very good. Simply choose 'Pull' from the Source Control menu and then choose the right branch on the Worklist's repository that you should have added as a remote before (upstream/master). Xcode should detect which files are in conflict and show those to you so that you can properly merge the conflicts.

''It's possible that you are presented with an error message during this process. I've (Birarda) been having problems with Xcode 4.3.3 in pulling remote changes. I am presented the conflicts but when I make my choices and try and pull there is an error message about the usage of git merge. If this happens to you I'd recommend you use  on the command line as the interface it offers is a similar but uglier version of the Xcode visual merge tool. There are instructions for that above in the resolving conflicts section.''

Functional Review
NOTE: Part of the benefit of switching over to Github is that mobile jobs will now start to follow the normal Worklist.net convention and will go through a functional review by the job's runner.

Now go and switch your job status on worklist.net to FUNCTIONAL. The runner will receive an email with a link to your forked git repository. They will clone a copy of your repository locally to perform the functional review.

Code Review
Once the runner confirms that the functional review is complete you should switch the job to REVIEW. This will use the Github API to create a pull request from the job branch in your forked repo on Github to the Worklist's master repository on Github. A code reviewer will go through the pull request on GitHub and, thanks to GitHub's diff functionality, enter any comments and suggestions within the diff itself as comments to specific lines.

You can make additions / changes to the pull request by making changes locally and then committing and pushing them up to github (always on the job's branch) using the process I outlined above. By pushing new changes to the branch on github they will automatically be added to the pull request.

Once the review is complete you can go ahead and set the job on Worklist.net to COMPLETE. At this point the runner or a senior member of the team will accept the pull request and merge the code into the master repository on the Worklist account on Github and set the job to DONE.