Changing Change Management with GitHub

A visual showing a person using a computer to construct a complete picture out of some puzzle pieces. The GitHub logo is visi

Let's imagine the simplest web page you can have, a page that simply displays "Hello world!"

How hard would it be to change the "Hello World" in this application to "Hello Friends?" Fairly simple, right? How about adding an input field to the same page? That would be a little more difficult, but still not so bad. Maybe we even want to make it so whatever we type in the input field is what is displayed in the header, so that if I type "Hello All" in the input field, the header will display "Hello All." Again, this is a little more complicated, but nothing we haven't seen before.

Applications change. Over time clients make new requests and features are requested that are non-standard amongst other implementations of the same application. Sometimes these changes are low impact, like changing the text on a particular page. They can also be higher impact, like making adjustments to page flow entirely.

Maybe you want to have some configuration for the logo in your app so that clients can display their company branding. Maybe your application is implemented with modules and you want to be able to toggle some modules on and off for particular clients. Inevitability, some level of configurability is introduced into your application as it grows in complexity.

Configuration Complicates Change

In a previous article we've talked about our approach to implementing applications that are on an extreme end of the code vs configuration scale, leaning towards the configurability side.

The code-configuration scale. On the left side of the scale is code. On the right side of the scale is configuration. Code changes are made in standardized ways that propagate behaviour to all instances of a deployed application. Configuration changes are made in non-standard ways that don't propagate to all instances immediately.
Code vs Configuration Scale
Enabling Contained Customization with FSM & Server-Driven UI
Looking back at early 2021, vaccination rollouts for COVID-19 were continuing to ramp up in Ontario at a very rapid pace, with no slowing in sight. We dive into how we used SDUI and FSMs to solve this, quickly.
SDUIs and FSMs for customizable applications

In short, we use a combination of the SDUI pattern and finite state machines to enable instance level configurability. But we know that there are tradeoffs to this approach.

With this approach, most changes to the application behaviour are no longer made through code and so it can be harder to review changes as part of a change management process. It also complicates the deployment of these changes. Changes made in code can simply be rebuilt and deployed, whereas changes made in configuration files need to be seeded into the correct instances at runtime in order to take effect.

The FSG Stack

We've talked about our usage of finite-state machines and server-driven UIs in the previous article, linked above. The final piece of the puzzle for our stack is GitHub, which we will be using as a service to implement GitOps (FSG = Finite-state machines, Server driven UIs, and Github).

GitOps is a well documented framework for using Git repositories to store configuration, handle changes with merge requests, and reacting to those changes using CI/CD.

As the most popular Git hosting service in the world, GitHub is a reliable and robust choice for implementing a GitOps solution. GitHub exposes a REST API that enables features like reading files from a repository and programmatically committing changes.

We will use GitHub as a source of truth for storing application configurations. The overall flow is as follows:

A sequence diagram detailing how configuration is deployed with our FSG stack. 1. Admin selects an application to get a new configuration for from the Admin UI. 2. The UI makes a request to the server for the new configuration. 3. The server makes a request to Github for the configuration. 4. GitHub responds with the configuration from its source repository. 5. The server responds with the configuration received from GitHub to the Admin user interface. The server includes a diff of the current configuration and the new one. 6. The admin reviews the

Using Github gives us access to a version history of how our configuration files change over time. Configurations deployed to production databases may be mutated or overwritten. Having this history is essential for auditing purposes. It also provides insight into essential metadata about every change to our configuration files. We're able to determine who authored the change (the commit author), why the change was made (the commit message), and when the change was made (the commit time).

GitHub additionally allows us to have access to both the latest revision of our configuration on GitHub, and the currently deployed revision. This allows us to introduce a diff check step in our workflow. The deployer of the new configuration (listed above as "Admin") can then perform a final review of the configuration changes before deploying a new one to a production environment.

Lastly, if we ever need to rollback any deployed changes, the process integrates naturally with the Git workflow we are accustomed to. All we need to do is revert the commit that introduced the problematic change from GitHub. After that we can follow the same deployment steps described in the diagram above to revert the configuration change.

Change Is Hard

There exists a silver bullet for every silver bullet. While no solution is perfect, what we've come to call the FSG stack has worked well for us in mitigating the friction associated with maintaining highly configurable applications.

Written by
Aleksander Bodurri
Team Lead, Development at Verto Health | Angular Team Member
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Verto Blue Team.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.