UnuBroパッケージのビルドと展開を自動化する


今日早く、仲間のumbracoパッケージdevgetting versioned deployments working in Azure DevOps そして、共有の精神で、私は私が同じ問題を解決するために私のアプローチを概説すると思いました.

問題


パッケージDEVsとして、あなたは本当に、それが展開するのが速いとして、可能な限り展開を準備する少しの時間として費やされたいです、あなたが速く変化をプッシュする必要があるとき、それは問題のより少ないです.
これを達成するための最良の方法は、ビルドと生成を生成するツールとスクリプトを使用して、自動化を介してです.
パッケージ付きVendr , 私たちのアプローチは、長年にわたって開発されていますが、今日私たちは私たちのための手段は、Nightly/不安定なビルドを解放する私たちのコードのリポジトリに変更をコミットする(私たちは定期的に開発者とこれを共有するので、彼らはすぐにコード修正を確認することができます)をリリースし、リリースを押すと、私たちのためにマージに問題がある良い良いセットアップがありますmain 支店とタグ付けは、バージョン番号と合併.

ヌークビルド


物事を自動化する最初のステップは、ビルドスクリプトを設定することです.私が学んだようになった私のための1つの要件は、長年にわたってビルドスクリプトをローカルで動かす能力を持っていることです.
以前はMSBuildを使用していましたが、これはXMLベースであるので、実際には非常に面倒ですし、多くの試行錯誤を行います.最近、我々は優れたツールを使用し始めたNUKE Build これは、Cに基づいてビルドスクリプトを使用することができますCは、私たちのビルドスクリプトを使用することができます.
私はそれを使用する方法の詳細のトンには入らないが、基本的には、コマンドを介してグローバルビルドツールをインストールする
dotnet tool install Nuke.GlobalTool --global
そして、nuke :setup プロジェクトを初期化します.これでウィザードを使用してソリューションをビルドプロジェクトを設定できます.

これが実行されると、ビルドプロジェクトがソリューションに追加され、フォルダーとスクリプトファイルの数がソリューションに追加されます.

Visual Studioでは、新しい_build プロジェクトはあなたの解決策に加え、そしてBuild.cs このプロジェクトのビルドスクリプトです.

Nukeは既にあなたのためのビルドスクリプトをつかんでいますが、基本的なスクリプトとして以下を使用できます.
using Nuke.Common;
using Nuke.Common.CI;
using Nuke.Common.Execution;
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.GitVersion;
using Nuke.Common.Utilities.Collections;
using static Nuke.Common.IO.FileSystemTasks;
using static Nuke.Common.IO.PathConstruction;
using static Nuke.Common.Tools.DotNet.DotNetTasks;

[CheckBuildProjectConfigurations]
[ShutdownDotNetAfterServerBuild]
class Build : NukeBuild
{
    public static int Main () => Execute<Build>(x => x.Pack);

    [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
    readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;

    [Solution] 
    readonly Solution Solution;

    [GitVersion(Framework = "net5.0")] 
    readonly GitVersion GitVersion;

    AbsolutePath SourceDirectory => RootDirectory / "src";
    AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts";

    // =================================================
    // Clean
    // =================================================

    Target Clean => _ => _
        .Executes(() =>
        {
            SourceDirectory.GlobDirectories("**/bin", "**/obj").ForEach(DeleteDirectory);
            EnsureCleanDirectory(ArtifactsDirectory);
        });

    // =================================================
    // Compile
    // =================================================

    Target Restore => _ => _
        .DependsOn(Clean)
        .Executes(() =>
        {
            DotNetRestore(s => s
                .SetProjectFile(Solution));
        });

    Target Compile => _ => _
        .DependsOn(Restore)
        .Executes(() =>
        {
            DotNetBuild(s => s
                .SetProjectFile(Solution)
                .SetConfiguration(Configuration)
                .SetAssemblyVersion(GitVersion.AssemblySemVer)
                .SetFileVersion(GitVersion.AssemblySemFileVer)
                .SetInformationalVersion(GitVersion.InformationalVersion)
                .EnableNoRestore());
        });

    // =================================================
    // Pack
    // =================================================

    Target Pack => _ => _
        .DependsOn(Compile)
        .Produces(ArtifactsDirectory)
        .Executes(() =>
        {
            DotNetPack(c => c
                .SetProject(Solution)
                .SetConfiguration(Configuration)
                .SetVersion(GitVersion.NuGetVersionV2)
                .SetOutputDirectory(ArtifactsDirectory)
                .SetNoBuild(true));
        });

}

ここで多くのことが起こっていますが、最終的には「ターゲット」の数を定義しています.定義したタスクは以下の通りです.

  • clean -ビルドアーティファクトディレクトリ(パッケージファイルが生成される場所)を消去します.

  • 復元-ソリューションnugetパッケージを復元します

  • コンパイル-リリースモードでソリューションをコンパイルします

  • pack - nugetパッケージを生成する
  • このスクリプトは、新しいスクリプトを使用していると仮定します.NET SDKスタイルプロジェクトとソリューションは、gitリポジトリにコミットされます
    このビルドスクリプトを使用して、プロジェクトのルートディレクトリでコマンドを実行できますbuild pack を起動するPack ターゲット.

    ビルドスクリプトが実行されると、生成されたNugetパッケージをartifacts ディレクトリ.

    不具合


    このようなビルドスクリプトを自動化するとき、最大の痛みの一つであり、彼のビルドセットアップでは、ペイン・ネイサンが生成したアーティファクトのバージョン番号を管理しています.使用については、我々はツールと呼ばれる使用を見つけるGitVersion 神が送る.
    GitVersionは、あなたのGITリポジトリに見て、生成するために次のバージョン番号を決定するために多くの規則を使用するツールです.それはかなり強力なツールです、そして、1つのブログ柱で非常に多くを通り抜けるので、私はちょうどあなたにGitVersion website 複雑さの詳細を調べるために.
    しかし、私たちの目的のために、私たちは、我々がdevブランチにコミットするときはいつでも、それが最後にビルド番号が付いているアルファビルドを生成することを知っていることができますv1.2.0 メインブランチでは、フルリリースビルドを作成します.また、非常に存在v1.2.0 タグは、その時点からdevブランチバージョンをインクリメントするので、常にバージョン番号を正しいビルド順序で保持します.
    Nukeビルドについての良いことはGitVersionは最初のクラスの市民であり、したがって、最小限のセットアップが動作するようにする必要があります.
    上のビルドスクリプトでは、いくつかの場所で使用されている“gitVersion”という用語を見ることができます.非常に上で、我々は定義しますGitVersion 変数は、基本的にはNukeにGitVersionを使用します.Compile and Pack 複数の定義されたプロパティにアクセスし、コンパイルされたアセンブリバージョンのようなものを設定します.GitVersion.AssemblySemVer ) そして、生成されたNUGETパッケージのバージョンGitVersion.NuGetVersionV2 ).
    これらのバージョン番号のすべてが自動的に生成され、それが特定のユースケースのために必要な形式で私たちのために我々はちょうどバージョン番号を設定するプロパティを使用し、我々が行われます.

    紺碧の悪魔


    上の例では、ローカルでビルドするパッケージをビルドする能力があります.テストのために便利ですか、誰かのビルドを作成する必要がありますが、手動でビルドを実行する必要はありませんAzure DevOps 遊びに出る.
    Azure devopsはたくさんの事柄(実際には私たちのプライベートGit reposをホストするために使用しています)ですが、自動展開に最も興味を持っているのはazureパイプラインです.Azureパイプラインは基本的に、特定の基準が満たされたときに自動的に発生するGitリポジトリとトリガビルドを監視することができるビルドサーバです.
    Azure PipelineはAzureポータルを通して構成されることができますazure-pipelines.yml プロジェクトのルートでファイルします.
    Vendrでは、我々の支払いプロバイダーのために、我々はこのような何かを持ちます.
    trigger:
      branches:
        include: 
          - dev
          - hotfix/*
          - release/*
      tags:
        include:
          - v*
    
    variables:
      - group: 'vendr'
      - name: 'vmImageName'
        value: 'vs2017-win2016'
      - name: 'nuGetOrgServiceCreds'
        value: 'NuGet.org (Vendr)'
    
    stages:
    
      - stage: build
        displayName: Build
        dependsOn: [  ]
        pool:
          vmImage: $(vmImageName)
        jobs:
    
          - job: build
            displayName: 'Build'
            dependsOn: [ ]
            steps:
              - task: CmdLine@2
                inputs:
                  script: './build.cmd Pack'
              - task: PublishBuildArtifacts@1
                inputs:
                  pathToPublish: './artifacts'
                  artifactName: artifacts
    
      - stage: deploy
        displayName: Deploy
        condition: succeeded()
        dependsOn: [ build ]
    
        jobs:
          - deployment: deploy
            displayName: Deploy
            environment: 'development'
            pool:
              vmImage: $(vmImageName)
    
            strategy:
              runOnce:
                deploy:
                  steps:
    
                    # Unstable Deploy
                    - task: NuGetCommand@2
                      displayName: 'Deploy to unstable feed'
                      inputs:
                        command: 'push'
                        packagesToPush: '$(Pipeline.Workspace)/artifacts/**/*.nupkg;!$(Pipeline.Workspace)/artifacts/**/*.snupkg'
                        nuGetFeedType: 'internal'
                        publishVstsFeed: '{project_name}/{feed_name}'
    
                    # Realease Deploy
                    - task: NuGetCommand@2
                      displayName: 'Deploy to NuGet.org'
                      condition: and(succeeded(), startsWith(variables['build.sourceBranch'], 'refs/tags/v'))
                      inputs:
                        command: push
                        nuGetFeedType: external
                        packagesToPush: '$(Pipeline.Workspace)/artifacts/**/*.nupkg;!$(Pipeline.Workspace)/artifacts/**/*.snupkg'
                        publishFeedCredentials: '$(nuGetOrgServiceCreds)'
    
    再び、ここに掘るための運賃ビットがありますが、最終的にこのスクリプトは、Gitリポジトリ内のどの変更がビルドをトリガーし、いくつかの変数を設定してインポートしてからビルドプロセスに移動するように設定しています.
    ビルドステップでは、以前に定義したビルドスクリプトをトリガーし、生成されたアーティファクトをazureパイプラインアーティファクトとして発行します(これは他のビルドステップに対してのみ有効になります).
    展開ステップでは、NUGETパッケージファイルを不安定なNuGetフィードに公開します(これもAzure devopsを使用している別のことです).もしビルドがgitタグの形式で起動されている場合vX.X.X それから、我々はNuGetパッケージも公開しますnuget.org .
    このスクリプトがあなたの倉庫に定義されて、コミットされて、Azure Devopsで、あなたはあなたの倉庫にそれを指し示すためにAzure Pipeline Setupazure-pipelines.yml リポジトリを監視し、ビルドスクリプトを実行し、変更が行われたときにあなたの資産を公開します.

    結論


    私はここで多くの情報を要約しようとしましたので、おそらくさらに多くを調べる必要があるかもしれませんが、私は私が十分に物事が一緒に働いている方法を見て、このように物事を行うの利点を与えることを願っています.