zoukankan      html  css  js  c++  java
  • 企业级工作流解决方案(十四)--集成Abp和ng-alain--自动化脚本

      对于.net方向,做过自动化的,应该没有人不熟悉msbuild吧,非常强大的代码编译工具,.net平台的编译工作都是交给他来完成的,包括.net core的命令,本质上都是调用msbuild来执行的

      对于发布到window平台,linux平台,或者用jenkins管理,核心基础还是绕不开msbuild

      Msbuild目录结构

      msbuild.bat为引导脚本,效果就是让用户选择启动哪个编译脚本,集成到jinkens的话,可以在jinkens里面选择,代码如下:

    @echo off
    
    echo "欢迎使用东宸科技自动化脚本"
    echo "1.生成租户Sql脚本"
    echo "2.初始化数据库Sql脚本"
    echo "3.生成租户MySql脚本"
    echo "4.初始化数据库MySql脚本"
    echo "5.生成QA初始化Sql数据库"
    echo "6.生成QA Sql租户"
    echo "--------------------------"
    echo "51.生成QA工作流服务"
    echo "52.生成QA工作流管理工具"
    echo "53.生成QA管理服务"
    echo "54.生成QA Ng-Alain服务"
    
    set /p selected=请选择:
    
    IF "%selected%"=="1" Sql-New-Tenant.bat & goto end
    IF "%selected%"=="2" Sql-New-Database.bat & goto end
    IF "%selected%"=="3" MySql-New-Tenant.bat & goto end
    IF "%selected%"=="4" MySql-New-Database.bat & goto end
    IF "%selected%"=="5" QA-New-Database.bat & goto end
    IF "%selected%"=="6" QA-New-TenantExe.bat & goto end
    IF "%selected%"=="51" QA-Workflow-ServiceHost.bat & goto end
    IF "%selected%"=="52" QA-Workflow-WorkflowManagement.bat & goto end
    IF "%selected%"=="53" QA-Sprite-SpriteService.bat & goto end
    IF "%selected%"=="54" QA-Sprite-Portal.bat & goto end
    
    echo "自动化脚本已完成!"
    
    :end
    @echo on

      00_MsBuild文件夹下其他文件为具体启动编辑脚本,主要是设置不同编译环境的参数以及第一个执行的编译target目标,比如Sql-New-Tenant.bat,代码如下:

    @echo off
    
    set /p tenantName=请输入英文标识名称:
    set /p tenantDisplayName=请输入租户中文名称:
    set /p tenantAdminUserName=请输入租户管理员UserName:
    
    set /p yes="确认租户信息【英文标识名称:%tenantName%,租户中文名称:%tenantDisplayName%,租户管理员UserName:%tenantAdminUserName%】,是否继续(y/n):"
    
    if not "%yes%"=="y" (
        echo 生成租户脚本已取消
        goto end
    )
    
    cd /d %~dp0msbuild
    if not exist .outputlogSqlsql-new-tenant mkdir .outputlogSqlsql-new-tenant
    cmd /c "build.bat /l:FileLogger,Microsoft.Build.Engine;logfile=.outputlogSqlsql-new-tenantsql-new-tenant.log /target:Sql-New-Tenant /property:TenancyName=%tenantName% /property:TenancyDisplayName=%tenantDisplayName% /property:AdminUserName=%tenantAdminUserName%"
    
    @if %errorlevel% NEQ 0 (pause) else (if "%1%" NEQ "--batch" pause)
    
    :end
    @echo on

      msbuild文件夹里面的内容,就是正真的编译逻辑。

      build.bat为msbuild执行路径

      My.proj为编译总架构,定义了一系列参数,包括输入输出目录、模版路径、引用的编译依赖的第三方库dll路径,还有就是加载所有项目的target,以及定义公共的一些帮助task,代码如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
      <!-- GENERAL -->
      <Target Name="Echo">
        <Message Text="Hello from $(MSBuildProjectDirectory)" />
      </Target>
    
      <PropertyGroup>
        <RootFolder>$(MSBuildProjectDirectory)....</RootFolder>
        <ReleaseFolder >$(MSBuildProjectDirectory)output$(Environment)</ReleaseFolder>
        <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
        <Platform Condition="'$(Platform)' == ''">Any CPU</Platform>
        <Platform Condition="'$(Platform)' == 'MCD'">Any CPU</Platform>
        <Environment Condition="'$(Environment)' == ''">DEV</Environment>
        <VisualStudioVersion Condition="Exists('$(MSBuildExtensionsPath)MicrosoftVisualStudiov12.0WebMicrosoft.Web.Publishing.Tasks.dll')">12.0</VisualStudioVersion>
        <VisualStudioVersion Condition="Exists('$(MSBuildExtensionsPath)MicrosoftVisualStudiov14.0WebMicrosoft.Web.Publishing.Tasks.dll')">14.0</VisualStudioVersion>
        <ExtensionTasksPath>$(MSBuildProjectDirectory)lib</ExtensionTasksPath>
        <TemplatesPath>$(MSBuildProjectDirectory)	emplate</TemplatesPath>
        <OfflineCmd>echo 1</OfflineCmd>
      </PropertyGroup>
    
      <!--工作流服务-->
      <Import Project="Workflow-ServiceHost.targets" />
      
      <!--工作流管理工具-->
      <Import Project="Workflow-WorkflowManagement.targets" />
      
      <!--.net core框架服务-->
      <Import Project="Sprite-SpriteService.targets" />
      
      <!--ng-alain Portal服务-->
      <Import Project="Sprite-Portal.targets" />
      
      <!--Sql Server新增租户脚本-->
      <Import Project="Sql-New-Tenant.targets" />
      
      <!--Sql Server新增数据库脚本-->
      <Import Project="Sql-New-Database.targets" />
      
      <!--Sql Server新增数据库表-->
      <Import Project="Sql-New-DatabaseExe.targets" />
      
      <!--Sql Server新增租户脚本-->
      <Import Project="Sql-New-TenantExe.targets" />
      
        <!--MySql新增租户脚本-->
      <Import Project="MySql-New-Tenant.targets" />
      
      <!--MySql新增数据库脚本-->
      <Import Project="MySql-New-Database.targets" />
    
      <!--Transform support-->
      <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)MicrosoftVisualStudiov$(VisualStudioVersion)WebMicrosoft.Web.Publishing.Tasks.dll" />
    
      <Target Name="Build-Web">
        <Message Text="Start building everything" />
        <Message Text="VisualStudioVersion:$(VisualStudioVersion)"/>
      </Target>
    
        <UsingTask TaskName="MSBuildReplaceFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)Microsoft.Build.Tasks.v4.0.dll">
            <ParameterGroup>
                <TemplateFileFullName ParameterType="System.String" Required="true" />
                <DestinationFileFullName ParameterType="System.String" Required="true" />
                <ReplaceTags ParameterType="System.String" Required="true" />
                <ReplaceValues ParameterType="System.String" Required="true" />
            </ParameterGroup>
            <Task>
                <Reference Include="System.Core" />
                <Using Namespace="System" />
                <Using Namespace="System.IO" />
                <Using Namespace="System.Net" />
                <Using Namespace="System.Linq" />
                <Using Namespace="Microsoft.Build.Framework" />
                <Using Namespace="Microsoft.Build.Utilities" />
                <Code Type="Fragment" Language="cs">
                    <![CDATA[
                        string strContent = File.ReadAllText(TemplateFileFullName, System.Text.Encoding.UTF8);
    
                        var strReplaceTags = ReplaceTags.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        var strReplaceValues = ReplaceValues.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        for(int i=0;i< strReplaceTags.Length;i++)
                        {
                        strContent = strContent.Replace(strReplaceTags[i], strReplaceValues[i]);
                        }
    
                        File.WriteAllText(DestinationFileFullName, strContent, System.Text.Encoding.UTF8);
    
                        return true;
                ]]>
                </Code>
            </Task>
        </UsingTask>
    </Project>

      新增租户编译脚本Sql-New-Tenant.targets和MySql-New-Tenant.targets,这个稍微简单一些,输入租户名称、租户显示名称、租户超级管理员名称,脚本读取模版文件,替换模版文件里面定义的内容标识,输出sql或者mysql脚本,脚本如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
      <Target Name="MySql-New-Tenant" DependsOnTargets="Build-Web">
        <PropertyGroup>
          <ReleaseWebHost>$(ReleaseFolder)mysqlmysql-new-tenant</ReleaseWebHost>
        </PropertyGroup>
        
        <!--Lets delete the old deployed files-->
        <RemoveDir Directories="$(ReleaseWebHost)" />
        <MakeDir Directories="$(ReleaseWebHost)" />
        
        <MSBuildReplaceFile ReplaceTags="#TenancyName#;#Name#;#AdminUser#" 
            ReplaceValues="$(TenancyName);$(TenancyDisplayName);$(AdminUserName)" 
            DestinationFileFullName="$(ReleaseWebHost)sql-new-tenant_mysql.sql" 
            TemplateFileFullName="$(TemplatesPath)mysql-new-tenant.sql.template">
        </MSBuildReplaceFile>
      </Target>
    </Project>

      初始化数据库脚本Sql-New-Tenant.targets和MySql-New-Database.targets,主要用.net frameworkcore的migrations实现dotnet ef migrations script,代码如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
      <Target Name="MySql-New-Database" DependsOnTargets="Build-Web">
        <PropertyGroup>
          <SpriteProjectRoot>$(RootFolder)1_FrameworkCK.Sprite.MigrationToolMysql</SpriteProjectRoot>
          <WorkflowProjectRoot>$(RootFolder)3_WorkflowCK.Workflow.MigrationToolMysql</WorkflowProjectRoot>
          <ReleaseWebHost>$(ReleaseFolder)mysqlmysql-new-database</ReleaseWebHost>
        </PropertyGroup>
        
        <!--Lets delete the old files-->
        <RemoveDir Directories="$(ReleaseWebHost)" />
        <MakeDir Directories="$(ReleaseWebHost)" />
        
        <PropertyGroup>
          <CmdSprite>
            dotnet ef migrations script --output "$(ReleaseWebHost)authcenterscript_mysql.sql" -c AuthCenterDbContext
            dotnet ef migrations script --output "$(ReleaseWebHost)commonscript_mysql.sql" -c CommonDbContext
            dotnet ef migrations script --output "$(ReleaseWebHost)oaservicescript_mysql.sql" -c OAServiceDbContext
          </CmdSprite>
          <CmdWorkflow>
            dotnet ef migrations script --output "$(ReleaseWebHost)workflow_mysql.sql" -c WorkflowDbContext
          </CmdWorkflow>
        </PropertyGroup>
        <Exec WorkingDirectory="$(SpriteProjectRoot)" Command="$(CmdSprite)" StdOutEncoding="UTF-8" StdErrEncoding="UTF-8" />
        <Exec WorkingDirectory="$(WorkflowProjectRoot)" Command="$(CmdWorkflow)" StdOutEncoding="UTF-8" StdErrEncoding="UTF-8" />
      </Target>
    </Project>

      流程引擎服务编译Workflow-ServiceHost.targets,核心思想:msbuild编译项目,根据不同的环境变量,替换默认配置文件内容,删除其他配置文件,配置文件严格按照标准格式来定义,如Web.config、Web.QA.config,如果编译传递的是QA环境变量,则用Web.QA.config内容替换Web.config指定内容,代码如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
      <Target Name="Workflow-ServiceHost-BuildSolution" DependsOnTargets="Build-Web">
        <PropertyGroup>
          <WebProjectRoot>$(RootFolder)3_WorkflowCK.Workflow.ServiceHost</WebProjectRoot>
          <WebProjectPathOfWebHost>$(WebProjectRoot)CK.Workflow.ServiceHost.csproj</WebProjectPathOfWebHost>
          <ReleaseWebHost>$(ReleaseFolder)workflow-servicehost</ReleaseWebHost>
          <WebPackageName>workflow-servicehost.zip</WebPackageName>
        </PropertyGroup>
        
        <!--Lets delete the old deployed files-->
        <RemoveDir Directories="$(ReleaseWebHost)" />
        <MakeDir Directories="$(ReleaseWebHost)" />
    
        <!--publish web host-->
        <MSBuild Projects="$(WebProjectPathOfWebHost)"
          Targets="ResolveReferences;Compile;_CopyWebApplication"
          Properties="
              Configuration=$(Configuration);
              WebProjectOutputDir=$(ReleaseWebHost);
              OutDir=$(ReleaseWebHost)in" />
              
        <!--Transform ConfigurationAppSettingsApp.config-->
        <TransformXml Condition="Exists('$(WebProjectRoot)ConfigurationAppSettingsApp.$(Environment).config')"
                      Source="$(WebProjectRoot)ConfigurationAppSettingsApp.config"
                      Transform="$(WebProjectRoot)ConfigurationAppSettingsApp.$(Environment).config"
                      Destination="$(ReleaseWebHost)ConfigurationAppSettingsApp.config" />
                      
        <!--Transform log4net.config-->
        <TransformXml Condition="Exists('$(WebProjectRoot)log4net.$(Environment).config')"
                      Source="$(WebProjectRoot)log4net.config"
                      Transform="$(WebProjectRoot)log4net.$(Environment).config"
                      Destination="$(ReleaseWebHost)log4net.config" />
                      
        <!--Transform ConfigurationModelsWorkflowForm.xml-->
        <TransformXml Condition="Exists('$(WebProjectRoot)ConfigurationModelsWorkflowForm.$(Environment).xml')"
                      Source="$(WebProjectRoot)ConfigurationModelsWorkflowForm.xml"
                      Transform="$(WebProjectRoot)ConfigurationModelsWorkflowForm.$(Environment).xml"
                      Destination="$(ReleaseWebHost)ConfigurationModelsWorkflowForm.xml" />
                      
        <!--Transform ConfigurationXmlConfigCoreConfiguration.xml-->
        <TransformXml Condition="Exists('$(WebProjectRoot)ConfigurationXmlConfigCoreConfiguration.$(Environment).xml')"
                      Source="$(WebProjectRoot)ConfigurationXmlConfigCoreConfiguration.xml"
                      Transform="$(WebProjectRoot)ConfigurationXmlConfigCoreConfiguration.$(Environment).xml"
                      Destination="$(ReleaseWebHost)ConfigurationXmlConfigCoreConfiguration.xml" />
                      
        <!--Transform ConfigurationXmlConfigSocketClientConfiguration.xml-->
        <TransformXml Condition="Exists('$(WebProjectRoot)ConfigurationXmlConfigSocketClientConfiguration.$(Environment).xml')"
                      Source="$(WebProjectRoot)ConfigurationXmlConfigSocketClientConfiguration.xml"
                      Transform="$(WebProjectRoot)ConfigurationXmlConfigSocketClientConfiguration.$(Environment).xml"
                      Destination="$(ReleaseWebHost)ConfigurationXmlConfigSocketClientConfiguration.xml" />
                      
        <!--Transform ConfigurationXmlConfigSocketServiceConfiguration.xml-->
        <TransformXml Condition="Exists('$(WebProjectRoot)ConfigurationXmlConfigSocketServiceConfiguration.$(Environment).xml')"
                      Source="$(WebProjectRoot)ConfigurationXmlConfigSocketServiceConfiguration.xml"
                      Transform="$(WebProjectRoot)ConfigurationXmlConfigSocketServiceConfiguration.$(Environment).xml"
                      Destination="$(ReleaseWebHost)ConfigurationXmlConfigSocketServiceConfiguration.xml" />
      </Target>
      
      <Target Name="Workflow-ServiceHost" DependsOnTargets="Workflow-ServiceHost-BuildSolution">
        <!--delete some config files-->
        <Delete Files="$(ReleaseWebHost)ConfigurationAppSettingsApp.QA.config;"/>    
        <Delete Files="$(ReleaseWebHost)log4net.QA.config;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationModelsWorkflowForm.QA.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigCoreConfiguration.QA.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigSocketClientConfiguration.QA.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigSocketServiceConfiguration.QA.xml;"/>
        
        <Delete Files="$(ReleaseWebHost)ConfigurationAppSettingsApp.PRD.config;"/>    
        <Delete Files="$(ReleaseWebHost)log4net.PRD.config;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationModelsWorkflowForm.PRD.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigCoreConfiguration.PRD.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigSocketClientConfiguration.PRD.xml;"/>    
        <Delete Files="$(ReleaseWebHost)ConfigurationXmlConfigSocketServiceConfiguration.PRD.xml;"/>
      </Target>
    </Project>

      其他项目的编译也是参照这样的方式实现

      补充说明:对于发布到IIS,可以通过webdeploy实现,也是用脚本,把编译后的代码推送到IIS服务器,对于linux可以推送到docker容器,还有其他方式,比如把代码发送到git服务器,调用客户端接口,让客户端从git上拉取代码到本地等等。

  • 相关阅读:
    jvm
    深度学习 机器学习
    中小规模机器学习的问题
    threading.Condition()
    实现 TensorFlow 架构的规模性和灵活性
    随机条件场
    使用TensorFlow Serving优化TensorFlow模型
    PDB、PD、PMP、RTB哪个更好?为品牌主解锁程序化购买的选择技巧
    bisecting k-means
    内核futex的BUG导致程序hang死问题排查
  • 原文地址:https://www.cnblogs.com/spritekuang/p/10820589.html
Copyright © 2011-2022 走看看