One of the fundamental requirements in modern applications is the ability to deploy changes to your application in an automated and predictable manner. This is sometimes referred to as continuous integration or continuous deployment. For static applications where the structure and content of an application is embedded into the application itself or stored in configuration files, the deployment process is fairly straightforward and there is a variety of tooling which is available to make this process easier. In contrast, dynamic applications are more complicated and ironically the cleaner separation of concerns between the application and their structure/content actually make the deployment process more challenging.
One of the concepts which has gain popularity in recent years is "Configuration as Code". This concept promotes the management of your configuration resources the same way that you manage your application code ie. as versioned artifacts in a source repository. There are many benefits offered by this approach, and it can be used as a solution for deploying dynamic applications.
A common requirement in Oqtane is the need to identify changes for a specific site in your multi-tenant installation and deploy these changes into another environment. For example you may need to add an additional page to a site... and that page may have a number of modules... and those modules may need to be populated with some initial content. Oqtane includes a powerful administrative interface which allows you to perform all of these tasks interactively... however this requires an administrator to manually make the changes in each environment- which is not automated or predictable from a deployment perspective.
To solve this problem, Oqtane 3.1 introduces a new Site Migration capability. Using a Configuration as Code approach it is now possible to codify the changes you wish to make to a specific site using an approach which is similar to EF Core data migrations. The version-based changes can be compiled into a deployable artifact (ie. an assembly) and included in a Nuget package for deployment (in the /Packages folder). At runtime when the Oqtane framework starts up, it will execute the Site Migrations automatically.
An example of a Site Migration class is outlined below. An attribute is used to identify a site based on it's primary alias name. The attribute also includes a version number to uniquely identify the set of migrations to apply to the site. Note that the version is not related to a specific version of the Oqtane framework, themes, or modules - it is a unique version number associated exclusively to a site in an installation. The Up method can be used to execute any logic which is required for the desired site changes. This could include calling Repository APIs, managing files, modifying configuration artifacts, etc.. The Down method is included for future use and is not required at this point.
using Oqtane.Models;
namespace Oqtane.Infrastructure
{
[SiteMigration("localhost:44357", "01.00.00")]
public class ExampleSiteMigration : ISiteMigration
{
void ISiteMigration.Up(Site site, Alias alias)
{
// execute some version-specific upgrade logic for the site here such as adding pages, modules, content, etc...
}
void ISiteMigration.Down(Site site, Alias alias)
{
// not implemented
}
}
}
This new capability provides first class support for site migrations as part of an automated deployment process. It also creates opportunities for developers to create additional solutions in the future. For example, a developer could create a cpability similar to EF Core migrations which are able to scaffold migration code classes based on the state of a database.
Deployments using Oqtane are very simple and straightforward. The contents of the official Oqtane Upgrade package can be deployed to keep the installation up to date with the latest version of the framework. And all customizations - whether they are modules, themes, site migrations, etc... can be deployed as individual Nuget packages to the /packages folder and will be installed automatically during startup.