This is partly working (read on) implementation of App-config workflow using SCM.

Here is detail a ‘config app’ that uses Git and Angular. GitHub’s used too, but for your production, staging, etc config details you’ll not want to have that in a public repo. I’ll also ignore the ‘all or nothing’ permissions issue for Git branches (mention in the last blog entry).

To deploy it yourself (Mac & Linux only)

  1. Install Ruby 1.9.3 (rvm recommended)
  2. Install Ruby Gems
  3. Install sinatra (via gem)
  4. Install json (via gem)
  5. Install aha via your OS’s package manager or via a ‘convoluted route’: https://github.com/theZiz/aha … and ‘make’ as per the README
  6. Install egrep via your OS’s package manager (most likely installed already)

  7. Fork the GitHub repo - https://github.com/paul-hammant/app-config-app, then clone it to your fine system.

  8. cd to that directory, and launch via ‘ruby appcfg.rb’

  9. visit http://localhost:12345

Screenshots

Yes, I know it needs some styling and usability attention, but here is the starting position:

no pending changes

Here is after I’ve saved a config set to the backend, and clicked “show diffs”:

diffs

Here is after clicked commit (requires a suitable commit message):

commit

App Construction

It is 45 lines of Ruby, and the same for JavaScript. Sinatra on the Ruby side made web serving easy. I’ve used a bunch of command line utilities. Git is one obviously, but ‘aha’ turns the ANSI color output of git diff into HTML. Unix command ‘egrep’ subsets that down to just the lines that have changed (even though that removes a little clarity).

AngularJS figures on the client side. It handles the interop with the back-end(s): diff, commit, push, pull. It also has the nature of the configuration document encoded within it. That could have been abstracted out, but I’m wondering if that ‘spec’ is not better left within the declarative grammar of Angular. As mentioned in the previous blog entry, on different branches, you’d have different stack configurations. In the index.html file, its fine to hard code the environment name. You would maintain divergence of that via ‘strategy-ours’ merge feature of git.

Yet to do

  1. Multiple users to one config app instance will trample on each other’s changes.
  2. I would want to get Jenkins (or your CI tool) to re-launch the Ruby script whenever it changes. Being all-in-one lends itself to that.
  3. In the web-app, there is no notion of a logged in user. As such, all changes will be tied to the person who cloned the original repo. As bad, all your stack’s config is available to guests to that URL. You might not want to have all employees seeing all production config.
  4. Protection against cross site scripting: Any post of JSON content back from anywhere will be accepted. Even though you would not deploy this publicly, you still should move to JSONP for post backs.

If we were to turn this into a robust app, use of Git would have to be via APIs. The same would be true for alternate apps SCM back-ends like Subversion, Perforce or TFS. Command line invocation to a shared working directory is not going to really work.

A video clip

(Added Oct 5th, 2012)

Here’s a video that I added, talking through the implementation: