将单个代码库部署到多个客户端

Deploy Single Code Base To Multiple Clients

我公司有一个应用程序存储库,我们希望将其部署到多个客户端。每个客户端都有不同的应用程序配置值 (appsettings.json),并且此设置可能会随着客户端的不同而改变。这就是为什么我们为每个客户端创建不同的 git 分支以执行 CICD。每个客户端服务器(本地)中有多个 TeamCity 服务器,它们正在侦听其 git 分支以获取更改。我们担心这些客户数量会增长。 git 分支的数量也会增加,我们不希望这种情况发生。

注意:每个客户端都有自己的暂存和生产环境。所以我们创建了分支名称为“clientA-staging”、“clientA-production”、“clientB-staging”、“clientB-production”。我们这样做的另一个原因是,如果客户端配置发生变化。我们只想将此更改仅部署到该客户端。

我们有什么方法可以改进它吗?我们想要实现的是:-

  1. 将暂存和生产 git 分支的数量减少并保持为仅两个分支。
  2. 仅当特定客户端发生配置更改时才部署到特定客户端。

我们遇到了与您面临的相同问题,每个客户一个分支机构,但随着我们的客户群开始增长,事实证明这真的很痛苦。 我们最终做的是为所有客户(dev、staging、prod)创建一个分支,并创建一个 appsettings.json 层次结构:

appsettings.json                * config for all customers
  appsettings.Development.json  * config for all customers, for dev environment
  appsettings.Production.json   * config for all customers, for prod environment
  appsettings.client.json       * dummy file, just to have a proper hierarchy in VS
     appsettings.client.Customer1.json
        appsettings.client.Customer1.Development.json
        appsettings.client.Customer1.Production.json
     appsettings.client.Customer2.json
        appsettings.client.Customer2.Development.json
        appsettings.client.Customer2.Production.json

为了为每个客户加载正确的应用程序设置,我们使用了一个名为 ASPNETCORE_CustomerName 的环境变量(任何以 ASPNETCORE_ 为前缀的变量都将作为环境变量被默认的虚拟主机构建器加载)我们在构建 Web 主机时阅读的内容(在 Program.cs 中):

public static class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        return Host
            .CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
                {
                    var env = hostingContext.HostingEnvironment;

                    // read the customer name from the env variable
                    // (note that the ASPNETCORE_ prefix is removed)
                    var customer = hostingContext.Configuration.GetValue<string>("CustomerName");

                    // only add our custom hierarchy, 
                    // the default json files are already loaded
                    config
                        .AddJsonFile($"appsettings.client.{customer}.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.client.{customer}.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                        .AddEnvironmentVariables()
                        ;
                })
                .UseStaticWebAssets()
                .UseStartup<Startup>();
            });
    }
}

最后,我们为每个客户提供了一个 CI/CD 管道,并且每个客户的 Web 应用程序都有自己的 ASPNETCORE_CustomerName 通过 Azure 门户设置的变量。

我已经通过在 TeamCity 中设置评论过滤器(git 提交消息)设法解决了这个问题。通过使用例如“[clientA]”配置过滤器,仅当 git 评论与过滤器匹配时才会触发部署。在这种情况下,它只会部署到客户端 A。