-
Notifications
You must be signed in to change notification settings - Fork 7
Coding workflow
The proposed workflow is here to liberate developers from fear of making changes!
- Not just the master branch
- From master to develop
- Need a feature?
- But what if there is a conflict?
- Would you like to help in developing/testing some other feature?
- Ready for a release?
- But what if the release has a bug?
The complexity and the number of current and future features require a more robust approach to managing code versioning. Currently a central server model is used where all changes are made to a single master
branch. In order to better control platform changes to avoid incompatibilities and broken state, a more comprehensive workflow is introduced, which is based on gitflow. The referenced tutorial should be used to get familiarised with the gitflow workflow.
This post provides more of a step-by-step instruction on how to apply the gitflow to the platform development, listing the relevant git commands for each of the steps.
Instead of coding against the master
branch, each new feature or even a change to an existing feature should have its own branch. All of such branches should be short-lived copies of the develop
branch that would integrate all
features and fixes over the development life cycle. The feature
branches are short-lived simply because they get merged into the develop
branch once corresponding features are completed, and then get deleted in order not to pollute the code tree.
There are some other branches, which will be introduced in this post as we've need them.
Originally any repository has only a single branch -- the master
branch. The same is true for TG repo, and all existing changes to the platform as of this writing are present on the master
branch.
Once the gitflow workflow is adopted, there should be no direct commits to the master
branch. Instead, it would only receive new commits by getting merged with either some hotfix
or release-x.x
branches.
Branch develop
gets created as a copy of branch master
and is used to accumulate all future changes. But, this also does not happen by committing changes to develop
directly.
Thus far, we know that branch develop
is a copy of master
, which is illustrated in ASCII art below.
master ---------------->
\
develop -------------------->
Before starting the development of any new feature and assuming that the TG project is already cloned, one should make the develop
branch to be the tracking branch for development (i.e. the current one) by executing the following commands:
git pull
git checkout -b develop origin/develop
The above command need to be executed the very first time where there was no branch develop
checkout before. In case it was, simply switch to it and pull
changes:
git checkout develop
git pull
Next, it is needed to create a new feature
branch that would accumulate all relevant changes for a specific feature. It is important to understand that a feature
branch should exist no only locally, but shared with other developer by pushing it to the central repository. This makes it possible for several developers to work on the same feature. Also, there should be as many feature
branches as necessary at the same time. These branches should be named uniquely, of course. It is strongly suggested that each feature be specified in a separate issue (could be an umbrella issue for smaller tasks), and thus a corresponding branch should be named Issue-#?
.
For example, the following command creates a new feature
branch to cover changes for issue #30:
git checkout -b Issue-#30 develop
The token develop at the end of the command indicates that a newly created branch is branched out from branch develop
, but this is still a local branch. The following command should be used in order to push it to the central repository:
git push -u origin Issue-#30
After the above changes, the code tree would look something like the ASCII art below:
master ----------->
\
develop ---------->
\
Issue-#30 -->
Once a feature branch is created and pushed to the central repository, several developers may start working on a corresponding feature if needed. The drill with a future branch is the same as before with the master
branch -- do your changes, commit them and push to the central repository to share your changes with everyone who is concerned with that specific feature. No one else would be effected by these changes simply because they exists on a separate, specially designated branch.
master ----------->
\
develop ---------->
\
Issue-#30 --*---*-*->
Commit all changes, push to the central repository and make a pull request. The pull request is a feature of github where the author basically request others to review and comment on the implemented changes. At this stage it's a good time for other developers to review changes, and even checkout the relevant feature branch to test the feature (refer the section below).
There would be a need to specify the base
and compare
branches upon creation of the pull request. In order correctly create a pull request for merging of a new feature, the value for base
should be the develop
branch, and the value for compare
should be the name of the relevant feature branch (Issue-#30
in case of our example).
Once the future is accepted by others, the corresponding branch needs to be merged into the develop
branch (NOT the master branch!). This can be done by either using github pull request's merge feature (preferred) or by executing the relevant command line commands:
git checkout develop
git pull
git pull origin Issue-#30
git push
The result should be like in the diagram below:
master ----------->
\
develop ------------*---*-*->
\
Issue-#30 --*---*-*->
Once the merge is done, the feature branch should be deleted in order not to pollute to code tree or to be accidentally used for further development. There would be two branches with name Issue-#30
-- one local and one in the central repository (the origin). Deleting local branch does not effect the remote branch and the other way around. Therefore, both branches need to be deleted explicitly.
git branch --delete Issue-#30
git push origin --delete Issue-#30
Please note that origin branch can also be deleted via a github interface -- a feature provided as part of the merged pull request.
The deletion of the merged feature branch leads to a cleaner code tree and prevents accidental use of discontinued branches:
master ----------->
\
develop ------------*---*-*->
There could be a situation where the merge would not be possible due to conflicting changes in the feature branch and the develop
branch. For example, some feature branched was merged into develop
earlier, and the feature branch that you would like to merge conflicts with some of those changes.
No worries as there is nothing different to the conflict resolution process comparing to the ordinary centralised workflow with a single master
branch.
In order to make things concrete, let's consider that there is a problem merging feature branch Issue-#39
due to conflicting changes. Resolving the conflict takes the following steps.
-
Switch to the
develop
branch and synch it with the origin by pulling the changes in.git checkout develop git pull
-
Try merging automatically branch
develop
with branchIssue-#39
.git merge --no-ff Issue-#39
The
--no-ff
flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature.In case the conflict could not be resolved automatically, git would report something like this:
Auto-merging platform-dao/pom.xml CONFLICT (content): Merge conflict in platform-dao/pom.xml Automatic merge failed; fix conflicts and then commit the result.
Running
git status
would reveal conflicting files than need to be edited manually. Make the necessary changes, commit and push them.git add . git commit -m "#39 Resolved conflict to merge Issue-#39." git push
Github recognised the case where a conflict resolution is associated with a pull request and marks such pull request as merged and closed.
Assuming that there is already a feature
branch like Issue-#30
from the above example, which is pushed to the central repository, anyone can checkout that branch for code review or even to contribute some changes. Switching between branches locally is simple, but requires some discipline from a developer. There are several possible use cases.
-
You have finished all the current work, all changes pushed to the central repository and merged with branch
develop
, and you can help with some other feature that is being develop on its own branch.This is an easy case -- simply checkout a corresponding branch from origin (central repository) and start coding as usual (commands are discussed below).
-
Your're developing some feature (work in progress), but need to switch to help with the development of some other feature.
This is a tricky situation, which has two possible options.
-
You may commit all your changes to the current branch, and even push it to the origin (not required strictly speaking, but preferable). Then, checkout the branch of the feature that needs your input, and start working on it as per usual -- modify, commit, push to that branch. Once completed, checkout the branch of the feature you were working originally.
This approach is fine, but has one annoyance -- during the development of your current feature, your Eclipse workspace would have multiple files open and positioned specifically, some debug session may be in progress etc. All of that would be lost upon switching to a different branch! Hence, an alternative approach could be more preferable.
-
Instead of switching to a different branch in you current workspace, simply clone the project repository into a different workspace, checkout a new branch you need to help with there, and make all the changes in an isolated manner without touching your current workspace setup. That additional workspace could be specifically preserved for such "need some help" occasions that is not directly related to your primary development responsibilities.
-
Alright, now we can discuss how to get an existing feature branch that was created by someone else into your local repository copy.
As usual make sure that the local copy is up to date:
git pull
Then create (yes -- create) a local copy of the required feature branch from origin:
git checkout -b Issue-#10 origin/Issue-#10
The above command creates a local branch (flag -b) with the same name as the required remote branch, and associates it with the remote branch -- branch origin/Issue-#10
in this case.
This needs to be done just once, and the branch becomes the current one. The rest as usual -- make changes, commit, push (to share your changes with others).
At some stage there would be a number of features merged into the develop
branch worth releasing to the client. The release process might take some times (hours or even days), and it is necessary to make sure that the release would include only the currently present in the develop
branch features, and would not be mixed up with some of the futures develop after the release features are agreed upon, but before the actual release takes place.
In order to achieve this, a new release
branch needs to be created as a copy of the current develop
branch. This ways all future changes to the develop
branch would not effect the release at all and the develop
branch get cleared for incorporation of future features!
The release
branch may include the version of the product to be released in order to make this information more evident during the release preparation.
For example:
git checkout -b release-1.2 develop
And don't forget to push the release
branch to the origin in case some other developers need to be involved or if you're going to continue working on it from some other computer:
git push -u origin release-1.2
The following diagram outlines the discussed situation.
master ----------->
\ release ----->
\ /
develop ------------*---*-*---*--*---*------*---*-->
The release
branch belongs to short lived branches like feature
branches, which should be deleted immediately after being merged with the master
branch and potentially even the develop
branch.
Changes to branch release
should be relatively minor -- minor correction to the code and documentation that might be required to polish the application before releasing it. Making changes to the release
branch is no different as to any feature branch.
Once all changes are completed and the actual release should take place, the release
branch should be merged with the master
branch via a separate pull request, and the with the develop
branch also via yet another pull request, but only if required.
The merge with the develop
branch should be performed carefully, if at all, as the release would contain an updated release related project version. So, make sure that after the merge, the project version on the develop
branch is update to the next SNAPSHOT!
The merge commit with the master
branch should be tagged, indicating the release version number. Afterwards, the release
branch needs to be deleted like any feature branch that is completed.
master -------------------------------------------->
/
\ release -----*-->
\ / \
develop ------------*---*-*---*--*---*------*---*-->
The tag in git represents an immutable object, which is by nature is very similar to a branch, but cannot be changed (i.e. no commits can be taken out or put into it), and, thus, represent a proper way of marking release changes. So, after the merge of the release
branch with master
, checkout master
, pull changes from the central repository (that would be the merge changes if the merge was performed via github), and then tag it.
git tag -a 1.2 -m "Release 1.2."
The tag is created locally and needs to be pushed to the central repository:
git push --tags
1.2
master -------------*---*-*---*--*---*-------------*-|->
\
develop ------------*---*-*---*--*---*------*---*--*--->
Then fix it! This should be done on a new branch hotfix
that should be created based on the master
branch. Once all changes to hotfix
are committed and pushed, make a pull request to merge that branch with master
, and most likely develop
to promote fixes into the main development branch.
Then, perform the next release and tag the master
branch with appropriate tag. Branch hotfix
should be deleted afterwards as any other completed feature
branch.
Please note that the only difference with the hotfix
branch comparing to other short lived branches is that get created as a copy of the master
rather than develop
branch. But, similarly to the release
branch it gets merged with both master
and develop
branches.
Per aspera ad astra
- Web UI Design and Web API
- Safe Communication and User Authentication
- Gitworkflow
- JavaScript: Testing with Maven
- Java Application Profiling
-
TG Development Guidelines
- TLS and HAProxy for development
- TG Development Checklist
- Entities and their validation
- Entity Properties
- Entity Type Enhancement
- EQL
- Tooltip How To
- All about Matchers
- All about Fetch Models
- Streaming data
- Synthetic entities
- Activatable entities
- Jasper Reports
- Opening Compound Master from another Compound Master
- Window management test plan
- Multi Time Zone Environment
- GraphQL Web API
- Guice
- Maven
- Full Text Search
- Deployment recipes
- Application Configuration
- JRebel Installation and Integration
- Compile-time mechanisms
- Work in progress