Couple of things to note here:

The Backend API will be a stateless service accessible from the web.

will be a stateless service accessible from the web. The Database will be stateful and in this example let’s say that it’s Elasticsearch.

It is not important to know about the business use case here, except that this system will have to be delivered in quick iterations to production.

I guess the first question is where are we going to run our applications?

Kubernetes

Kubernetes is an open source system for managing containerized applications across multiple hosts; providing basic mechanisms for deployment, maintenance, and scaling of applications.

Source: https://github.com/kubernetes/kubernetes

This sounds like a good solution to run our applications without the need to care about the underlying hardware. Kubernetes gives us this abstraction where developers can just build containers of their applications and give them to a Kubernetes cluster which will take care of running them wherever there is compute power available.

We are not going to deep dive in how Kubernetes works here but it’s important as a developer to understand some high level concepts which are well documented on https://kubernetes.io/docs/concepts/.

Ok now you might wonder how are we going to deploy on Kubernetes?

Orkestra

Orkestra is an Open Source Continuous Integration / Continuous Deployment server as a library running on Kubernetes.

It leverages Kubernetes concepts such as Jobs or Secrets, and configuration as code in Scala to take the most of compile time type safety and compatibility with Scala or Java libraries.

Source: https://orkestra.tech

This sounds like what we’d like for our use case. The key features we are interested in being:

We are functional developers convinced by its advantages over unsafe Yaml, Python or Groovy code. So it’s perfect here since the configuration is in Scala .

developers convinced by its advantages over unsafe Yaml, Python or Groovy code. So it’s perfect here since the configuration is in . It’s extendable with Scala/Java libraries.

with Scala/Java libraries. It runs on Kubernetes , so we can reduce operational management by using a managed Kubernetes cluster such as GKE or EKS. Plus we can reuse the compute power left on a cluster for DevOps tasks.

, so we can reduce operational management by using a managed Kubernetes cluster such as GKE or EKS. Plus we can reuse the compute power left on a cluster for DevOps tasks. It’s Highly Available , not that we are looking into 100% up time for an internal tool, but it let’s operational maintenance possible without impacting the usage of the tool during working hours.

, not that we are looking into 100% up time for an internal tool, but it let’s operational maintenance possible without impacting the usage of the tool during working hours. It’s Fully scalable, so we can run many jobs in parallel if the underlying Kubernetes cluster is large enough.

Continuous Integration

Continuous Integration is fairly easy and there is a tones of tools out there to do it like Travis, CircleCI, GitLabCI, Jenkins and many more.

All we want is probably for each pull requests execute a full compilation, the tests, some linter (like Scalafix, Scalafmt) and maybe check that the Contributor License Agreement has been signed. In any case it should be a matter of few commands.

Of course Orkestra can run those checks on pull requests. Let’s have a look at the code. Remember that at anytime you can get more documentation about Orkestra on https://orkestra.tech.

We first need to define a job that executes the checks:

This is the first time we define a job so let’s take a moment to understand what’s going on here step by step:

We define a board that will represent the UI. There is different types of boards but we will be using a JoabBoard here.

• In the JoabBoard we define the signature of the function this job will be executing, here GitRef => Unit .

• We need to give a unique ID and a nice name for the display.

• Lastly we give the UI elements for the parameters form. Here only a Input[GitRef] with a nice name for the display.

that will represent the UI. There is different types of boards but we will be using a here. • In the we define the signature of the function this job will be executing, here . • We need to give a unique ID and a nice name for the display. • Lastly we give the UI elements for the parameters form. Here only a with a nice name for the display. Then we define a job that will be responsible for executing the workload.

• A Job needs to reference the JobBoard so we pass it.

• Now the interesting stuff starts! We pass the function that will be executed when a PR is updated.

• Because this is DevOps we will be dealing often with files and directories. To do so in a referentially transparent way we have a context object of type Directory that knows in which directory we are and this is what workDir is about. Of course we don’t want to pass this parameter everywhere, so we make it implicit.

• gitRef is the parameter value given by the user through the parameter form in the board.

• Github.statusUpdated is an helper function that will let know Github when the test started and if it fails or not. It also takes care of checking out the git ref for you and moving into the Git directory.

• Lastly we execute a shell command where we run the tests.

Now that we have the job defined we need to create the Orkestra server, register the job to it and configure the GitHub Pull Request hooks:

We create the Orkestra server by just extending OrkestraServer , which forces us to implement board (the UI) and jobs (the triggerable jobs).

, which forces us to implement (the UI) and jobs (the triggerable jobs). board will be a Folder of just the PullRequestChecks board for now.

will be a Folder of just the PullRequestChecks board for now. jobs will contain only the PullRequestChecks job.

will contain only the job. Then we need to configure the Pull Requests Github hooks.

Alright, let’s have a look at the UI and see how beautiful it is: