I've seen it asked a couple of times in #gitlab
on freenode about upgrading GitLab and what is a good method or recommended method. While GitLab HQ does not recommend a specific workflow for their upgrades I am here to introduce you to my work flow. Feel free to use it or adapt it to your own style. Please note I wrote the majority of this around GitLab 6.0 but GitLab 6.2 is currently released. This will likely apply to any future GitLab release if they stick to the same model of releasing via SCM.
If you'd like to follow other stuff I write about randomly I have a LinuxQuestions.org blog under the user sag47 or you can look at my recent posts on LinuxQuestions.org by doing an advanced search and search by user name. I try to make them all informative.
A GitLab major version is released on the 22nd of each month. Each release has it's own upgrade notes normally which should be reviewed. I recommend offsetting your upgrade by half a month so that stable release upgrade bugs can be ironed out by the community. Regular downtime should be scheduled monthly for this upgrade maintenance to avoid having to upgrade several versions consecutively. GitLab normally publishes each release with a issue milestone.
I have a few iron clad rules for distributed workflow which I tend to follow. Some of it comes from the gitflow branching model and some of it has come from my own personal experiences. I have tailored these rules to apply to GitLab management. Realistically following these rules would work with any upstream vendor providing software via distributed SCM.
- Never develop in a branch in a forked repository that exists in the upstream parent repository. Without following this rule it will be very hard to update the parent repository branches. This includes integrating parent branch changes into your own development.
- This rule is more naming convention than anything following rule 1. Whenever you're using a stable version of GitLab be sure to fork off of the stable branch into
X-X-stable-yourorganization
. This will ensure that your production stable branch stays the same and allows you to test integrating changes in the GitLab stable branches. If you have multiple instances then perhaps name the organization after the domain name of the server. - When upgrading fork off of your organization stable branch into an update "Integration" branch. Integrate the changes from the branch you wish to upgrade to. Upon successful integration you can merge the integrated branch back into your organization stable branch.
- For major updates the integration branch being forked will be named
X-X-stable-yourorganization
from your current stable production branch. However, this new branch will be a new version and it is good to keep around your old stable production branch as well. When updating major versions it's good to utilize a recursive merge to avoid conflicts and migrate your customizations to the new version. For minor updates a regular merge is usually good enough without merge conflicts. - Follow the recommended upgrade procedures provided by GitLab. These are located in the
docs/upgrade
folder of the repository.
I'll give you an example for how I manage my stable branches in gitlab. All commands I'm running under the system user git
unless otherwise specified. Log into git user using sudo -i -u git
.
When I cloned gitlab and set it up. First I cloned the repository, checked out the 6-0-stable branch and then branched off of that with my own branch.
git clone https://github.com/gitlabhq/gitlabhq.git gitlab
Now the cloned repo is in a gitlab
directory with the path of /home/git/gitlab
.
cd gitlab
git ls-remote | grep heads
ls-remote
is used to list the remote branches of the origin
remote. Alternatively you can specify the remote...
git ls-remote origin | grep heads
Now let's get to the point. Comments start with #
.
git checkout 6-0-stable
#now working in the 6-0-stable branch.
git checkout -b 6-0-stable-drexel
#now working in the 6-0-stable-drexel-branch forked from the 6-0-stable branch
git branch -v
You can use git branch -v
to show branch names as well as sha1 commit id's for what commit the brances are at. If you notice 6-0-stable
and 6-0-stable-drexel
branches have the same commit ID because they're related. Also note that when you git branch -v
the branch with a *
next to it is your current working branch.
Now I set up my gitlab from the 6-0-stable-drexel
branch. From now on upgrading and integrating will be much easier. You can test upgrades before integrating them into your production stable 6-0-stable-drexel
branch.
The scenario will be upgrading from 6.0 to the latest 6.0 version (i.e. to 6.0.1 or to 6.0.2). First create a backup of your gitlab with the backup rake command (in my case rather than that I take a virtual machine snapshot).
Note: If you're taking a VM snapshot then it is best to shut down GitLab before the snapshot so that users don't try to commit work either during or after the snapshot. Since I contributed my Apache httpd config (rather than nginx) my users see a friendly "Deploy in progress" message.
In any case, before you start your upgrade or working with the new branches be sure to shut down your GitLab service /etc/init.d/gitlab stop
. Comments start with #
.
#Currently working in the 6-0-stable-drexel branch
git checkout 6-0-stable
git pull origin 6-0-stable
#Currently working in the 6-0-stable branch
Your 6-0-stable
branch is now up to the latest version. Test starting the server is optional but I'll include it. Go ahead and start your gitlab server. Test and see if it works (i.e. log into it). If it works then stop your server and integrate the upgraded changes by merging the 6-0-stable
branch into the 6-0-stable-drexel
branch.
#Current working in the 6-0-stable branch
git checkout 6-0-stable-drexel
#Currently working in the 6-0-stable-drexel branch
git merge 6-0-stable
That's basically my workflow for upgrading minor versions of GitLab.
Major upgrades are a little more tricky. Especially if you customized some of the GitLab source code for your own purposes and you want to preserve those changes in the new major version of GitLab (at least preserve customizations as much as possible). Major versions of GitLab sometimes include drastic changes such as prerequisites being modified (i.e. a new version of Ruby or puma instead of Unicorn or visa versa). Major upgrades tend to also have database upgrades which tend to make reverting back to your previous configuration very hard. This is where backing up your gitlab and following the instructions in docs/upgrade
extremely important.
This is where VM snapshots come in most handy because you don't have to worry about resetting up all of your prerequisites if you snapshot it. If you have a physical host and you used LVM for your system partitions then LVM supports snapshotting the filesystem. You can snapshot it and revert the system back using the snapshot if need be. In any case, for this example I'm only going to assume the following for brevity...
- No prerequisites change
- There may or may not be database schema upgrades (I won't cover rolling back the database)
- You have integrated your own customizations into the GitLab source which would be difficult to fully rewrite in the new version.
- We're going to pretend to upgrade from 6.0 to 6.1.
Let's get on with the workflow. First thing to do is check out an integration branch.
#Currently working in 6-0-stable-drexel branch
git checkout -b 6-1-stable-drexel-integrate
#Currently working in 6-1-stable-drexel-integrate branch
Now if you try to simply merge the 6-1-stable
branch into your integration branch then you're going to get a lot of merge conflicts even with something as simple as the VERSION
file having two different version numbers in it (I kid you not). Luckily, git merge
has this really cool feature called merge strategies. We can use merge strategies to tell git to automatically determine what to do in the case of merge conflicts. For my merge strategy all I need is the recursive
theirs
strategy. If you need it there's other more complicated strategies but I won't cover them here. So let's get on with it.
#Currently working in the 6-1-stable-drexel-integrate
#Using options from git help merge
git merge -s recursive -X theirs 6-1-stable
Now walk through all of your customizations and verify that they successfully migrated. If they weren't (which tends to happen when files are renamed or the code is moved into a different file) then you'll have to manually rewrite your changes into the new location of the code (or decide to discard it if GitLab HQ fixed it for you). Assuming everything went fine you then need to follow the doc/update/6.0-6.1.md
file. Be sure to not skip any steps and back up where appropriate.
Assuming you've finished upgrading and you've migrated all of your changes. Also assuming you successfully started the GitLab service and was able to use the new version it's time to create (or rename) your new stable branch!
#Currently working in the 6-1-stable-drexel-integrate
git branch -m 6-1-stable-drexel
And that's it! It's my general workflow for handling major upgrades in GitLab.