【问题标题】:Deploy Single Code Base To Multiple Clients将单个代码库部署到多个客户端
【发布时间】:2021-06-24 19:26:32
【问题描述】:

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

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

有什么方法可以改善这一点吗?我们想要实现的是:-

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

【问题讨论】:

  • 如果客户端配置发生变化是什么意思?您是否正在为此更改代码?
  • 是的。代码的变化。再具体一点。在 appsettings.json
  • 这样的话事情就复杂了。就像在您进行此更改之前,其他客户端可能有其他一些更改或新开发,因此当您实际应用此修复时,您不能对主分支执行此操作,除非您的所有客户端都准备好接受该更改。似乎您拥有一种产品,而不是为客户的特定场景定制它。这会成为代码长期运行的问题和开销,但您也必须看到业务方面。
  • 我知道你的意思。这就是为什么我们试图纠正我们的错误。你有什么建议吗?

标签: git asp.net-core teamcity cicd


【解决方案1】:

我们遇到了与您相同的问题,每个客户只有一个分支机构,但随着我们的客户群开始增长,这确实很痛苦。 我们最终做的是为所有客户(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 门户设置的变量。

【讨论】:

  • 很酷,但是您如何处理 CICD 管道?为所有客户端提供一个分支,这不是将部署到所有客户端吗?
  • 它确实会部署所有客户,但我们不认为新部署是一项成本高昂的操作,所以我们不介意。或者,您可以将路径过滤器添加到 CI/CD 触发器,仅在修改特定文件时触发(例如,对于 Azure yaml:docs.microsoft.com/en-us/azure/devops/pipelines/repos/…)。
  • 我明白了..也许没有直接的解决方案。
【解决方案2】:

我已经通过在 TeamCity 中设置评论过滤器(git commit message)来解决这个问题。通过使用例如“[clientA]”配置过滤器,部署只会在 git cmets 匹配过滤器时触发。在这种情况下,它只会部署到客户端 A。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 2014-03-14
    相关资源
    最近更新 更多