Automatically host pull requests

Deploying Solidus sites was initially a manual process, developers simply used the [modulus CLI][modulus-cli]. But providing the necessary credentials, keeping those credentials secure, keeping the CLI up-to-date, avoiding accidental deployments to the wrong target project, etc. proved challenging, especially when dealing with third-party contract developers.

Switching to a CI solution (initially Travis, now Circle) for deployment solved these challenges and provides a good platform for future additions such as tests, code linting, etc. Configuration files committed in site repositories helps make what goes live consistent and accommodate more complicated steps such as fingerprinting. Deployments generally run smoothly, barring availability issues with various services we’re dependent upon.  


### Communication

The remaining challenges have largely been related to communication and Git workflow. Git and GitHub in particular were a huge reason behind the development of and switch to Solidus. Version control, code review (to some extent), Markdown rendering and wikis for documentation, free desktop apps, etc. have all helped to solve various problems we’ve always had and we now take advantage of nearly everything GitHub continues to add. There are many takes on Git workflow out there, but I believe the "[GitHub Flow][github-flow] is most appropriate for us in that it was [designed for continuous deployment][continuous]. The problem is that we’re generally missing a key component: the pull request.


### Review Branches

The challenge with incorporating pull requests into our process has largely been because they were designed to facilitate code review. While a great practice, it’s rarely practical for this to happen in day-to-day production. I’ve argued for it to at least be used for big refactors and redesigns, but the reality is approval usually comes from non-developers: managers and clients. Looking at a diff however doesn’t work here, they need to _see_ the changes.

To accommodate this I’ve designated a `review` branch / environment for each site, which developers can merge changes into for staging & presentation. This works like so:

 - In addition to master, any changes pushed to review are deployed
 
 - Deploys go to a dedicated Modulus project that is always running
 
 - That project has a `clientname`.review.sparkart.com domain for easy access
 
The problem is now that we can create any number of branches on a site, flow gets tricky, leading to problems like this:

 - Some branches are put on hold as priorities change. Since changes are merged into the review branch it’s use as a staging environment can get murky. Force pushing can help keep things representative of what may go live, but this is advanced functionality and dangerous to promote.

 - Merging to review constantly to show progress can get tiresome, so some developers have resorted to working _directly_ in the review branch. This is dangerous however if anyone did something like force push in the above scenario. I haven’t explicitly warned against doing this, but had wanted to tread `review` as another `master` essentially.
 
 - My encouragement to use pull requests (especially to trigger deployments) started to result in pull requests being opened to merge changes from feature branches into review.
 
 - Abandoned / stale branches
 

### Hosted Pull Requests
 
Site versions in Clique Tools addressed these problems with a dedicated preview URL for every version, though it lacked merges between versions. We can have it all however if we can figure out how to automatically host pull requests. This would give us:

 - Client-friendly review URL for every branch in development

 - [Merge Button&trade;][github-merge] for one-click deploy by the account manager whenever they’re ready with [confidence inspiring CI feedback][github-status]
 
 - One-click branch deletion to help avoid abandoned branches

 - Opportunity to discuss changes with great Markdown support and easy screenshot uploads
 
 - Ideally, faster time-to-merge avoiding stale branches and the need to deal with merging, rebasing, conflicts, etc.

Generally pull requests would be opened against master, but they could target a staging branch for big redesigns, such as what’s happening with Young Money here: https://github.com/SparkartGroupInc/youngmoney.com/pulls?state=closed

One example of pull request hosting in the wild is [Prune.io][prune], but it’s still in beta and we don’t have an invite. It’s also not necessarily appropriate for our situation.


### Pull Requests Hosted by Modulus

I set out to build this capability on top of Circle and Modulus recently, and got as far as what I’ve committed here, currently doing this:

 - Checks the [Modulus API][modulus-api] for a project named after the branch. Note that this API is not public, I got the documentation when we were reviewing [Curvature][modulus-curvature] which we’re still planning on using ultimately. It’s public though insofar as the CLI is dependent upon it using the `api.onmodulus.net` domain.

 - Creates a project named after the branch if one doesn’t already exist
 
 - Deploy to the newly created project and see what what *.onmodulus.net domain is provisioned afterwards
 
 - Prefix pull request description with the *.onmodulus.net domain
 
 - If a matching project is found, deploy to it and skip other steps

### To-do

 - [x] **Convert to CLI binary.** While not totally necessary this would make for cleaner [CI configuration files][circle-config].
 
 - [x] **Automatically create a project for any new pull request.** This is implemented but still need to be hooked up to CircleCI for triggering at the right time.

I’ve documented my other plans as issues as they’re not necessary for getting this out there.


[continuous]: http://scottchacon.com/2011/08/31/github-flow.html
[prune]: http://prune.io
[circle-webhooks]: https://circleci.com/docs/configuration#notify
[circle-config]: https://circleci.com/docs/configuration
[modulus-cli]: https://github.com/onmodulus/modulus-cli
[modulus-api]: https://gist.github.com/InconceivableDuck/d8cd771e0615948e31ea
[modulus-curvature]: http://enterprise.modulus.io
[github-merge]: https://github.com/blog/1469-redesigned-merge-button
[github-flow]: https://guides.github.com/introduction/flow
[github-status]: https://github.com/blog/1227-commit-status-api