Skip to content

Coding and Workflow

Enrique Acosta edited this page Nov 15, 2019 · 11 revisions

So you are ready to start making changes to WeBWorK. You have a github.com account with a fork of the github.com/openwebwork repository. (See https://github.com/openwebwork/webwork2/wiki/First-Time-Setup ).

The first thing you have to decide before you write your first line of code is where do you want your code to end up. There are (usually) three possibilities, as described at Branching and Release Model:

  • master: Only small important changes (i.e. hotfixes) should be submitted to master. These are fixes to major bugs.
  • release/x.y: This branch is the beta of the upcoming release. Submissions to this branch should either be bugfixing or minor improvements with little risk.
  • develop: This is the main development branch. Most submissions should go here.

After you have decided where you want your changes to end up you should create a feature branch on you laptop as follows:

git checkout -b <my-feature-branch> origin/develop

This feature branch is set up to track, and eventually be merged into origin/develop. (Of course change develop to whichever branch you are targeting.)

Note: If you just want to check out a version of develop to test something use git checkout origin/develop. This creates a "headless" branch of develop for testing purposes. If you decide you want to keep those changes you can use git checkout -b <my-feature-branch> and it will save your changes to a new feature branch.

Double Note: If you decide that you are tracking the wrong branch with your feature you can try to rebase your feature branch onto a different tracking branch using

git rebase --onto <new-tracking-branch> <old-tracking-branch> <feature-branch>

This works by taking the changes you made in the feature branch commits and applying them to the new tracking branch. Depending on your changes there may be conflicts you need to fix and sometimes the process can get quite messy.

In addition to origin which connects to the github.com/openwebwork repository (which you can read from but cannot write to) you should create a personal remote which connects to your github fork of the WeBWorK code. This repository you can write to. See First Time Setup for the commands you must run to make sure that personal is defined when used in the following commands.

Now you are ready to code. The recommended workflow looks something like

  1. git checkout -b <my-feature-branch> origin/develop
  2. code
  3. git commit -a
  4. git pull origin develop
  5. fix merge conflicts, if any, and commit changes
  6. git push personal <my-feature-branch> (this places your changes on your github account so that it can be reviewed, accessed and commented upon)
  7. repeat

When you think your new feature is ready you submit it for consideration by issuing a Pull Request (PR) to the appropriate branch (usually develop) of the openwebwork repository. This brings it to the attention of the maintainers of the WeBWorK code who will review it and if all is well merge it into the central openwebwork repository.

Some things to keep in mind as you develop your new feature.

You should be wary about pulling anything other than the tracking branch (e.g. origin/develop) into your feature branch. Ideally after your code is pulled into openwebwork its network graph should either be a "loop" or a "ladder".

origin/develop ----------------------------o
                           \              /
                            \            /
personal/my-feature-branch   o-----o----o
origin/develop ---------------o--o---------o-o-------------o
                           \          \         \         /
                            \          \         \       /
personal/my-feature-branch   o-----o----o--o------o--o--o

Here the last diagonal line represents the final merge of the feature branch into the target branch.

The most strict version of this policy is that your feature branch is only allowed to pull its tracking branch. It should not have any other branches merged into it and it should not be merged into other branches. This is more restrictive than is absolutely necessary, but it is very safe. If you do decide to merge your branch into something else, or merge something else into it, keep the following in mind:

  • If you merge a branch from origin other than your tracking branch into your feature branch, then your feature branch will not be able to be merged into openwebwork anymore. I.E. If you based your feature branch off origin/develop then you cannot pull origin/master or origin/release/x.y into your feature branch.
  • If you merge another feature branch which is tracking a branch different than your current feature branch, then your feature branch will not be able to be integrated into openwebwork anymore. I.E. If you have feature-a which is tracking origin/develop then you cannot pull feature-b into feature-a if feature-b is tracking origin/master.
  • You can merge two feature branches which are both tracking the same branch in origin, but it makes life more difficult for the person evaluating the pull request, so have a good reason for doing so.

Keeping all of your changes in their own feature branches helps keep different features and different changes separate. You can work on your experimental new student view in one branch, bugfix a previous contribution in another branch, and apply a quick hotfix to master in a third. This does mean your local machine fills up with feature branches, though. You can delete branches that have already been merged with git branch -d <my-feature-branch>.

Testing

Any code you write should be well tested before you submit it. This includes code to the develop branch. Anything that gets merged into develop will make it into master after a year or so. What's more, code in develop doesn't magically get bugfixed. Some polishing does happen but in general the code that is eventually released to the public is very much the same as what was submitted and accepted into develop. Consequently, any code you submit should be well tested and pretty much ready for release. There are four approaches to testing code that deserve to be mentioned.

  • Ad Hoc Testing: This is the most common type of testing and just involves using your code for a while and seeing if anything breaks. This is a good first step but is not sufficient.
  • Black Box Testing: This is where you systematically go through and test the functionality of your feature. Click on everything that can be clicked and make sure it does what it is supposed to do. For very small features or bugfixes this can be sufficient. Depending on the size of the feature this can involve an hour or a day's worth of work.
  • White Box Testing: This is where you test the code itself. First, click the green "Compare, Review, and Create a Pull Request" button on your personal github repository. Use the edit button to select your feature branch and its target branch. This will show you a list of changes between your feature branch and its target. Go through change by change and perform an action in WeBWorK which causes the code changes to be run. Check that the results are what you expect them to be. This level of testing is needed for any sizable feature, or any code which impacts core WeBWorK functionality. For large features this can take a day or two of work.
  • Regression Testing: This is the longest and most thorough type of testing. It involves checking to see that the code you wrote didn't introduce bugs into previously existing code. Some of this is done at the same time as you are doing the Black Box or White Box testing, and for many things full scale regression testing is impractical. However if you are making a really large change, or preparing a release branch to be merged into master then you need to do this level of testing. In order to do regression testing go to the Testing Checklist and start going through the list, one item at a time, adding new items as necessary, and fixing any bugs you come across. Proper regression testing should take several days of work.