0

I have multiple CHEF cookbooks that I deploy. Each one is versioned according to semantic versioning.

My production environment is using cookbook 0.1.1
My stage environment is using cookbook 0.2.0

Version 2.0 has a large change that I can't deploy into production yet. A bug was found that needs to be hotfixed in 0.1.x. How would I create and deploy cookbook 0.1.2 to production, without merging in the big change in cookbook 2.0 into production?

Using git-flow. New releases are created off of the develop branch. Then merged back into develop and tested. After tests it is then merged to master, given a git tag and automatically deployed to the chef server.

    0.1.1              0.2.0
   /      \           /      \
o-o--------o-o---X---o--------o-o-------- develop
 \            \                  \
  o------------o------------------o------ master

When a cookbook is released, the release branch is deleted.

I assume I need to checkout X and then create cookbook 0.1.2. However I find when I try and merge the cookbook 0.1.2 into the develop branch, the metadata.rb and CHANGELOG.md have merge conflicts (Y). While I could rebase before the 0.2.0 cookbook was released, that would change my entire history.

                         _________________
                        /                 \
     0.1.1         0.1.2     0.2.0         \
   /      \       /         /      \        \
o-o--------o-o---X---------o--------o-o------Y-- develop
 \            \                        \
  o------------o------------------------o------- master

Whats the best way to deploy a older cookbook?

I know similar questions on backporting git commits have been asked on SO, but none of them cover how to handle the inevitable merge conflicts. Should I just accept that there will be conflicts and resolve them by hand?

Update

To clarify, I already have a strategy for using different cookbook in different environments using an environments.json file and version pinning.

Community
  • 1
  • 1
spuder
  • 17,437
  • 19
  • 87
  • 153

2 Answers2

4

So two unrelated questions in here:

First is how to manage maintenance branches under git-flow. I don't love their structure but I think the mostly official way is to make a new branch from the existing tag, make the changes, tag the maintenance release, and then merge that branch to master.

Second, is how to do release management in Chef. Generally this is done with Chef environments. Each environment can have a set of constraints about which versions of each cookbook are allowed in that environment. You would set the constraint on production to ~> 0.1.0 so the maintenance release is allowed but not the new minor version. That said, in keeping with SemVer (and related) you should use major versions to indicate compat breaks.

coderanger
  • 52,400
  • 4
  • 52
  • 75
  • Have only limited knowledge of git-flow, but that there's the concept of [support branches](https://groups.google.com/forum/#!topic/gitflow-users/I9sErOSzYzE). But it seems to be not widely understood. – StephenKing Nov 17 '15 at 09:36
  • git "support branches" do perfectly describe my problem. Since chef cookbooks are automatically deployed from the master branch with jenkins, It looks like the support branch will need to be merged into master (with conflicts). Unless I want to manually upload the cookbook. – spuder Nov 17 '15 at 17:19
1

Git flow "support branches" as suggested by @StephenKing are the answer to the git problem, and part of the solution to the chef deployment problem.

What I ended up doing:

Making a new git branch called "support/1.0"

Apply my hotfix to that branch, then change the metadata.rb and CHANGELOG.md to v0.1.2 and add a git tag.

I then merged that branch into master, skipping over develop (Z). The meatadata.rb and CHANGELOG.md had conflicts which I resolved manually. Jenkins then uploaded the 0.1.2 cookbook to the chef server.

Delete the "support/1.0" branch.

                       v0.1.2_________________
                      /                       \
     0.1.1       support/1.0      0.2.0        \
   /      \     /                /     \        \
o-o--------o---X----------------o-------o--------\-- develop
 \          \                            \        \
  o----------o----------------------------o--------Z- master

Pros to this approach:

  • No long living support branch
  • Still have cookbook in version control with git tag
  • Didn't have to rebase history

Cons

  • Master branch will continue to show old version until next release

Develop metadata.rb = "0.2.0"
Master metadata.rb = "0.1.2"

When version 0.2.1 is released, the metadata.rb in both branches will show the correct latest version. Until then this potentially could confuse people to think that 0.1.2 is the latest cookbook.

spuder
  • 17,437
  • 19
  • 87
  • 153