Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Although there are many similar questions here regarding using GIT for maintaining different versions, none seem to answer my specific case.

I'm OK with how to use GIT to do my development, using different branches to do hot fixes, versioning etc.

However, I am making a commercial application that needs to track various modules and configurations for DIFFERENT clients. And I do NOT wish the client to have access to a module or code they haven't paid for. Yet I would like to use GIT to deploy on their server, or to be able to deploy directly on the client server using ssh/rsync, or even on my server in a unique directory, then zip up the source files using a standard process.

Let me give you an example:

Client A:

  • Deploy basic application
  • Deploy Module A (e.g. forum) only
  • Deploy Client A specific theme with Client A specific logo

Client B:

  • Deploy basic application
  • Deploy Module A (e.g. forum)
  • Deploy Module B (e.g. faq system)
  • Deploy Client B specific theme with Client B specific logo

Development Server:

  • Contains basic application
  • Contains Module A (e.g. forum)
  • Contains Module B (e.g. faq system)
  • Contains Client A and Client B themes with all logos
  • Contains Development Notes which must NOT be visible to client
  • Contains build files used with Phing - these must NOT be available to clients

It's very important to understand that GIT on the development server contains proprietary data for Client A and Client B. Therefore Client A must never see my development notes, my Phing build files, Module B (faq system) or code/data/images for Client B.

I do not need to keep variations of a module or the basic application for individual clients. Everything is standard across the system, and it's only the deployment configuration/variation for each client which is unique.

I am happy to use GIT Submodules to keep some parts separate, if that helps.

Note that all my code is in PHP and I am happy to deploy solutions using PHP, Perl, Python or scripting, but I don't want to use Java on the destination server. Ideally I would like to avoid Ruby solutions, if possible. I have access to SSH on the client server and can use rsync over SSH as well, but I need to be able to execute a script on the client server to clean caches etc after an update.

My development machine is Windows - yes, unfortunate, but true. If I cannot achieve what I need on Windows then I will run CentOS/Fedora in VMWare.

This is not a multi-server deployment requiring simultaneous updating across a server farm, although it would be nice to be able push out updates of the application to all the various clients on a schedule or using a single command/procedure rather than having to do it manually for each one. I would also need to be able to push client specific updates to individual clients as and when required (for instance HTML or logo updates).

So, can I use GIT for deployment, or at least track the various configurations using branches? Or is it simply going to be too messy?

Can I hide Client B from Client A, including in commit history, in a particular branch, to make sure someone proficient with GIT at the client's organization cannot retrieve code they mustn't see (and this is a contractual requirement of the project)? If so, how do I do this in GIT?

If not, how can I best manage a build process that allows me to deploy client specific configurations? Note that initially I will be managing around 20 different clients, and this might grow to 100 or more different configurations as each one will include their own HTML and logos, and a variation based on a potentially unique selection of 15-20 modules.

I am happy to maintain a hundred different XML configuration files if that's what it takes. I am aware of Capistrano, but from reading about it, it doesn't seem that suitable for my specific case. If you feel otherwise, please do feel free to state so.

share|improve this question
2  
I can't claim to be authoritative on this, but GIT sounds like the wrong tool for the job here - you'll probably be able to get something working, but this sounds more like a job for a build scripting tool. –  Baqueta Jan 17 '13 at 12:55
2  
I would agree with @Baqueta that Git is probably the wrong tool for this. I would solve this problem using some kind of plugin-based architecture and a deployment tool to choose the appropriate plugins. The whole idea of clients dealing with repositories is rather scary - they should deal with binaries, resources (images, style sheets, etc.) and configuration options. –  Thomas Owens Jan 17 '13 at 12:59
    
Thanks for the initial feedback. I should possibly have mentioned that I will either do all deployments on behalf of clients, or send them a ZIP file with the source they are entitled to. So they won't be dealing with GIT. My main usage for GIT is version control for internal development, hence my question whether GIT would in some shape or form be usable. I can also use a staging server, therefore I can check out any branch as needed on my own staging server, and create configurations from that, which then are deployed to clients. –  Svein E Jan 17 '13 at 13:05
    
Also, I am happy to use a script building tool of some kind - in which case my question is: what kind of tool would work well in this scenario? –  Svein E Jan 17 '13 at 13:10
add comment

1 Answer

up vote 3 down vote accepted

This is not a Git-specific answer, but it should work regardless of the VCS system you use.

I would start with several different repositories

  • One for each client, containing the client-specific files and a configuration file stating which options the client has purchased
  • One or more repositories with the development code

Then I would use a make_release script (written in your favourite scripting language) that does the following:

  1. Given the name of the client, checkout that client's repository to a temporary location
  2. Based on the purchased options, checkout or copy (from an existing checkout) the application and modules to the same location
  3. Remove all files/directories that are not relevant for the client (especially those that contain data meant for the VCS system)
  4. Package the release in a convenient format (e.g. zip or tar.gz)

Then deployment should be as simple as copying the release to the client's server, unpacking it and running whatever scripts that are needed to finish the installation/upgrade.

share|improve this answer
    
Thanks for the response. I've investigated further, done some testing, and your answer is close, so I'm accepting it. The difference is that I will have a single repository; each client has a dedicated directory within, and your suggested "mark_release" script will be a Phing script. The config for Phing will be automatically generated from a DB table and I can simply specify a particular client or "all". Funny, I've been using Phing for ages for project components and never once thought about it being used for this purpose :) –  Svein E Jan 21 '13 at 15:11
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.