Workflow

Permanent / Semi-permanent Branches

The only permanent branch is the master. Master is always stable and always supported. Bugfixes and releases merge to this branch.

There will also be long-running feature branches. These branches will be created when a feature becomes stable and doesn't have an active release branch to go into. They will be deleted after a certain period of time after the merge to the proper release branch.

The release branch will be deleted after a certain period of time after the merge to the master

Temporary branches

A number of temporary branches are used. Each feature/bug should be contained on its own branch. Every feature or bugfix branch should be cut directly off of master. Each temporary branch lives till the moment when the release branch it was merged to is merged to the master.

General Workflow

The issue possible workflow pathes are: * new -> ready -> new * new -> ready -> merged

States: * new - The issue (feature or bug) was created, or returned for additional work. * ready - The pull request for the issue is made. The contributor is sure that it is ready to be merged to qcubed codebase. * merged - The pull request was tested and approved by core contributor. it is merged to the own branch on the qcubed repository.

There are two issues involved in the bugfix or feature lifecycle: * the original proposal or bug report issue, and * the pull request issue.

Note that the pull request issue is autogenerated for each pull request and is just a one possible solution for the original issue. That is what the original issue is for - it is used to describe the proposal or the problem, while the pull request's issue is used to describe the specific way this pull request implements to solve the original issue. In other words, the original issue answers the question "What is going wrong?", or "What should be enhanced, and why?", but the pull request's issue answers the question "How it was implemented and why this solution was choosed, if there where alternatives?"

The general rule is to name the pull request issue after the name of the original issue it solves. It saves time to figure out what this request is for. Also, the second rule is to reference the original issue number with a # sign in the pull request's message body, e.g. "This pull request implements the feature #NNN". It helps to navigate to the original issue from the pull request, since the link is autogenerated in this case, and a "reference" comment is generated in the original issue.

Features

Features should begin as a conversation. An enhancement issue is opened against the right available release milestone, and requirements can be hashed out there.

A branch will be cut off of master by the developer assigned to the feature named feature-{feature name or issue number} or, simply, f-{feature name or issue number}. Note that the branch for the feature should not be made in the qcubed repository directly, it should be created in the developer's own fork.

If the feature is being worked on by more than one developer, second developer should fork the repository of the first one, and send pull requests against it.

Feature branch developers need to keep a close eye on master and merge in any bugfixes that are accepted. This ensures a minimal number of surprises once the feature is merged into an upstream branch.

Once the feature is ready to be tested, the pull request is made against the qcubed repository. Make sure that qcubed repository contains the feature with the same name you want to pull in. See the section called "Features that require a new branch" below for more info.

The qcubed maintainer tests the pull request and, if test has passed, merges the pull request to the proper feature branch into the qcubed repository. The original issue this feature was inspired off should be closed with a comment like this: "The feature is implemented in the pull request #NNN". If test has failed, maintaner closes the pull request with an appropriate comment message.

Naming Conventions

Bugs

Bug fixes are handled slightly different from features. A bugfix branch is created from an issue. A branch should be cut off of master by the developer with a name in a format bug-{issue number} or, simply, b-{issue number}. Everything else is the same as in a feature case.

The one important difference: after the pull request for a bugfix is accepted, the resulting 'bug-{issue number}' branch in the qcubed repository is merged into master immediately. This is good because users can pull bugfixes as they become stable and merge into their existing instance of qcubed. This also makes it easy for the core contributors because they can easily merge bugfixes into their feature branches and we shouldn't have to worry about merging bugfixes for a release.

Naming Conventions

Releases

When enough features are stable, a release branch named rc-{x.y.z} is cut off of master. The stable features are merged into this release branch and tested together. Once they pass testing, the branch is tagged {x.y.z}. This tag is an annotated tag. This means that it's a tag that doesn't just get deleted - it stays for long term. It is then merged back into master and thus made available for stable download.

The rc-{x.y.z} branch should be removed after a certain period of time after the {x.y.z} release is adopted.

Naming Conventions

Community contributions

We encourage everyone that wants to contribute to do so. Anyone can fork the framework and submit pull requests to a feature branch or bugfix branch. These requests will be reviewed by core contributors and (if up to [[standards|Standards]]) applied as features or bugfixes accordingly. If you would like to contribute to QCubed, the following steps will help ensure that your contribution is included in the next release:

  1. Fork the framework repo. Clone your fork to your local machine with the command git clone git@github.com:myUserName/framework.git. Note that a clone only pulls the master branch initially. This clone automatically sets up a "remote" for your github fork called "origin" (hence the git push origin branchname command).

  2. Set up your "upstream" remote. Since we're on distributed version control, we can have multiple remote repositories at once. This is key to using github (and git in general). You can name this remote anything you want, but convention dictates naming this "upstream". Do this with the following command: git remote add upstream https://github.com/qcubed/framework.git.

  3. Notice that to clone your fork you used git@github.com:qcubed..., but to set your upstream you used https://github.com/qcubed... This is because the "upstream" is read-only. Even if you have write access to qcubed/framework, I highly recommend using the https:// protocol to avoid accidentally pushing to the upstream framework.

  4. Check for an existing feature branch to work on and pull it locally. If you would like to do this in the terminal as well, you can with: git branch -a. Doing this will list all branches locally as well as all remote branches in the format remoteName/branchName. Pull feature branches from "upstream":

  5. Make sure you're on master locally git checkout master (you can find out what branch you're on at any time by typing git branch into the terminal.) and create the branch: git checkout -b branchname (following the conventions outlined above). If it says you already have that branch, don't panic, just take off the -b and try again (-b means "create this as a fresh branch off of the branch that I'm currently on).

  6. Pull the branch from your fork: git pull upstream branchname (where "branchname" is the name of the branch you are pulling). This will bring your local branch totally up-to-date with everyone else.

  7. Write some code Please make sure your code is documented and follows the [[standards|Standards]]. When you are finished writing:

  8. Make your local commit as usual (Recording Changes to the Repository).
  9. Push updates to your fork as necessary git push origin branchname
  10. You need to make sure you're still in sync with the upstream repo before submitting a pull request. Do this with: git pull upstream branchname where branchname is the name of the branch you're on.
  11. You also need to make sure your branch has any bugfixes that may have gone into master since your branch was cut. Do this by:
  12. switch to master: git checkout master
  13. pull master from "upstream": git pull upstream master
  14. upload any changes to your fork on github: git push origin master
  15. switch back to your feature branch: git checkout branchname
  16. merge in master: git pull origin master
  17. Push your code to your origin repository (your fork): git push origin branchname where branchname is the name of the branch you're on.

  18. Create a pull request. Make sure you make your pull request to the proper branch. If you're contributing to a feature branch, make sure your pull request is going to the same feature branch on qcubed/framework. Same idea for bugfixes. Pull requests made to the wrong branch may still be merged in, but repeated pull requests to the wrong branch from the same user will be rejected with a request to resubmit to the correct branch.

If there is no feature branch or bugfix branch for your code, just request one! Open an issue on the proper repo and attach an 'enhancement' tag for a feature or a 'bug' tag for a bugfix and describe the changes you're proposing. One of the core contributors will quickly review your request and make you a branch asap.

Merging a merge request

As a core contributor, you may have to handle merge requests from time to time. There are 2 main types of merge requests we will receive - features (or bugs) that require a new branch and features that already have a feature branch. We will cover instructions for both methods here.

Prepare a Core Contributor's working copy

Even if you are a Core Contributor, it is a must to not mix things. You should have two working copies installed: the first one is for ordinal work on your own features or bug-fixes - it's setup is covered in a section of "Community contributions", and the second one for doing merges to the main qcubed repository. These two must be separated to not having the write access to the main qcubed repository from the working copy of your own fork.

In order to prepare the second working copy for merges, do the following: clone the qcubed repo to your local machine with the command git clone git@github.com:qcubed/framework.git. Note that a clone only pulls the master branch initially. This clone automatically sets up a "remote" for the main qcubed repository named "origin" (hence the git push origin branchname command).

That is all. Now you can use this main working copy to do the merging.

Features that require a new branch

For features that don't have an existing branch (usually these features will be requested to merge into master. It is very important that you never merge anything directly into master), follow these steps:

Now the main qcubed repository has the branch named branchname. Contributors can use it to target their pull requests to.

Features with an existing feature branch

Features that have an existing branch are easy to merge. After reviewing the change locally and making sure the request is set to go to the correct branch, you should be able to just click the big green "auto-merge" button. If that button is not green or has a warning and the request is going to the correct branch, you need to investigate why git is telling you there may be a conflict. If you're not sure what to do, open an issue and ask. Do not merge features into the repo if you aren't sure that they're getting merged correctly.

Do the merge/review changes

We assume here that the pull request already has a branch on the main qcubed repository. If not, follow the section named "Features that require a new branch" above.

In order to review changes provided in the pull request, follow these steps:

More to come