The architecture, for the most part, is setup just like CRM.
There is a main repository, martha-ci/martha
. This is a ZF2 application. This contains routes, controllers, forms, etc. So far, it's pretty simple. There's a dashboard with nothing on it. There's a projects controller which allows you to view and create projects, and a build controller which allows you to kickoff new builds or view the status of a build.
There is another repository called martha-ci/core
, which contains the domain, persistence, and other library code. This library is the bulk of all the martha code that isn't front-end ZF2.
There is also a martha-ci/scm
repository, which I was intending to be a library of various adapters for different SCM systems. This is what would be used to do anything Git related.
There is a repository called martha-ci/command
, which is some stupid command library I wrote up to model system calls as PHP objects.
There is a repository called martha-ci/github-api
, which is an API client for the GitHub API. I didn't really like any I found, so I started writing my own.
Finally, there is a repository called martha-ci/plugin-github
, which is a Martha plugin for interacting with GitHub.
I want to build a decent plugin system. Basically, people can create Plugins, have a Plugin.php class (think of Module.php in ZF2), and they add events and hooks for various pre-determined things.
The end-user would install these plugins simply by adding the line in their composer.json
file for the plugin.
I started building a GitHub plugin which acts as (1) a RemoteProjectProvider, which is something that allows you to build projects from a remote source (ie, GitHub), as well as (2) ties into GitHub's hooks API to create a open pull_request hook so that Martha gets notified everytime someone opens a Pull Request, and (3) injects its own route so that when GitHub sends a notification, there's a custom plugin route that handles it and kicks off a build for the project in the payload.
(3) is one I haven't exactly figured out yet. I want the plugin to be able to set up its own routes, so these routes will have to be defind by the plugin and injected into the existing routes.
What I do not want is for these plugins to define their own Zend controllers. I want the plugins to be entirely implementation/technology unaware. There should be a generic controller that all these Plugin-defined routes map to, and then that controller should determine which callback is associated with that route and call it.
So setting up a route from a plugin should be something like:
$this->getPluginManager()->addHttpRoute(
'/build/github-hook',
[$this, 'onGitHubWebHook']
);
The route would always be a Literal
, and when we inject it into the ZF2 routes, we'll provide the rest of the information (controller, etc). The controller that handles these custom routes should be able to look up based on URL (/build/github-hook
) and execute the callback.
I had the build process working at one point. I'm not sure if it still is. A project should have a build.yml
file in the base of the source, which, like a .travis.yml
file, defines the build steps to take.
I started a queue system so that when you click Build
, or a GitHub hook comes in, all it does is add it to a builds
table, then tells the Queue to see if it is available to build it. This way, we can limit the number of builds running at once. There should also be a cron that runs once a minute or so and tells the Queue to run any available jobs.
The output of the build is logged and shown on the build page. For the first release, this was all I care about. Eventually, I'd like plugins to be able to define decorators, and in your build.yml
file, you can define plugins to use on an artifact file, like clover.xml
, such that when the build is loaded in the browser, the plugin can render data for clover.xml
.
I wouldn't worry about that for now. As long as we have build output on the screen, and the GitHub Plugin can report back build status on a commit, we should be good for now (for our purposes at USS).