6

I host with AWS which means I cant use environment variables to control my production and staging deployments. I am therefore forced to use separate branches for deployment, and am wondering if there is a best practice approach towards their maintenance?

If I merge changes into my production branch, the commit that contains my production settings will get lost in the branches history, making it more difficult to tweak those settings.

However I have read that you shouldn't use rebase in this situation as it will make it more difficult to roll back changes.

pingu
  • 8,719
  • 12
  • 50
  • 84
  • 1
    Why would environment variables and branches be the only ways to differentiate between different environments? Can't you e.g. pass a startup option to the service to select which configuration file to use? – Magnus Bäck Oct 30 '14 at 15:47
  • Thanks for the reply Magnus, with AWS Elastic Beanstalk, I do not know of a way of doing this. – pingu Oct 30 '14 at 15:53
  • @pingu It is not entirely clear from your question which file is getting overwritten in which branch(es). Could you list a diagram of some sort (text would suffice). – Tim Biegeleisen Nov 02 '14 at 11:07

4 Answers4

7

I also faced many challenges to implement git in my latest project. After too much googling I found this blog and it is really a nice way of maintaining git branch model.

A successful Git branching model enter image description here The central repo holds two main branches with an infinite lifetime:

  • master
  • develop

The master branch at origin should be familiar to every Git user. Parallel to the master branch, another branch exists called develop.

We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state.

We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where any automatic nightly builds are built from.

Supporting branches

The different types of branches we may use are:

  • Feature branches
  • Release branches
  • Hotfix branches

Feature branches : Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release.

May branch off from: develop

Must merge back into: develop

Branch naming convention: anything except master, develop, release-, or hotfix-

Release branches : Release branches support preparation of a new production release. They allow for last-minute dotting of i’s and crossing t’s.

May branch off from: develop

Must merge back into: develop and master

Branch naming convention: release-*

Hotfix branches : Hotfix branches are very much like release branches in that they are also meant to prepare for a new production release, albeit unplanned. They arise from the necessity to act immediately upon an undesired state of a live production version.

May branch off from: master

Must merge back into: develop and master

Branch naming convention: hotfix-*

You can find more details about this Git branching model from the blog. The commands used for the branching model also listed in the blog. Check the blog for more details. I successfully implemented the branching model in my project with some changes from the model mentioned in the blog. Git is a powerful and flexible tool,and this is just one way of using Git.

Damodaran
  • 10,882
  • 10
  • 60
  • 81
  • @Damodaran- Thanks for the detailed reply. If I where to apply this model to my specific problem, I imagine that my production specific setting would live on the release branch, however you say of release branches "Must merge back into: develop and master", this would not be desirable for production only settings. – pingu Nov 02 '14 at 10:25
  • No. I will make it clear, for example if you have a feature forgotpassword in one branch. After completing the task, the developer raise a pull request, and you will merge it with develop branch and test it. If any bugs,you will ask the developer to do that in the branch and after completing you merge the branch to develop. Once the feature is ready to release,you create a release branch and merge all the set features( different branches) need to go to live to that branch and release it. The beauty of Git branch model is you can create your own model that suites your requirement. – Damodaran Nov 02 '14 at 10:32
  • I think I must not be explaining myself very well. I have a production branch that is the same as my master branch apart from it contains production deployment settings. These setting are never intended to be merged back into master. – pingu Nov 02 '14 at 21:03
4

There are a few links below that share some opinions on methodologies and the reasoning behind why you should choose rebase or merge.

  • Merge is ideal for committing code to a shared branch among a team. Since Rebase rewrites the history of the commits, context of related commits (like feature branching) is lost since the commits become linear based on the timestamps.
  • Rebase can be ideal for pulling code into your working branch before committing back to a shared branch. The linear results and historical changing can lead to more successful merging of the commits.

See:

Jason W
  • 13,026
  • 3
  • 31
  • 62
3

You could version two settings files (one for dev and one for prod)

Then you could leave to an "elasticbeanstalk/hook" script to write the actual settting file for you after a "git aws.push".

You can see an example of a similar issue in "How to get Elastic Beanstalk nginx-backed proxy server to auto-redirect from HTTP to HTTPS?", about a Node app (which might not be your exact case), where a .ebextensions/config file will write a /opt/elasticbeanstalk/hooks/configdeploy/enact/myscript.sh.

That last script is a hook which can run on deployment, and could update the actual config file of your environment.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks for your reply, I am bit confused however, when you perform "git aws.push" how do you specify your environment so the correct hook can run? – pingu Nov 02 '14 at 10:27
  • with eb push, I suppose: https://forums.aws.amazon.com/ann.jspa?annID=1772 and http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-reference-branch-environment.html – VonC Nov 02 '14 at 10:44
  • but that doesn't specify your environment. – pingu Nov 02 '14 at 20:45
  • Yoiu can associate your environment to your branch – VonC Nov 02 '14 at 20:45
3

On master, version both settings files (settings_master and settings_prod) and a symlink settings -> settings_master. Now, branch prod off master (or merge master into prod if it already exists), and, in prod, modify only the symlink settings to point to settings_prod.

Commit this change to prod.

Now do all development on master, and as long as you don't modify the symlink itself (changing either of the settings files is fine), you will be able to merge master into prod as often as you like without affecting the target of settings. Your application should retrieve its configuration from settings.

This will result in a commit history that looks like this:

... -o---o---o---o  master
      \       \   \
...  --o-------o---o  prod

The diff from master to prod after each merge of master into prod will always be exactly:

--- a/settings
+++ b/settings
@@ -1 +1 @@
-settings_master
\ No newline at end of file
+settings_prod
\ No newline at end of file
Thomas Foster
  • 301
  • 1
  • 4