ケーキは、アーティファクトをプッシュするNuGetパッケージを使用AzureDevops

序文

みなさん、こんにちは、時間にコードを提出してから公開する方法を考えるI最近、自動化されたパッケージNuGet AzureDevOpsではArtifacts、プロセス中にピットの多くを踏んでなく、回り道をたくさん取るので、この記事では、私の結果を探ることであると私問題のいくつかは他の人に仕上げに遭遇しました。

私の最後の記事にCI/CD記事「Gitlab CIを使用して/ CD IISに発行サイトを自動化するには」の形で実装されたスクリプトを使用している、そこで庭の友人は、次のコメントで使用することができますケーキ(C#のメイクを)ツールを達成するためにどの機能、これはスクリプトを持っていないでしょう。ケーキは、変換するためにそれを使用する時間を持つことになります。

全体的なアイデア:

  1. 最初の導入の下でCakeAzureDevops Pipelines/Artifactsどのように使用します

  2. そして、AzureDevopsパイプラインを設定

  3. AzureDevops成果物を作成する(NuGetサーバー)

  4. AzureDevops構成PAT(パーソナルアクセストークン)と、所望のパイプライン変数(変数)

  5. NuGetパッケージのコードをプッシュケーキのパッキングが増加し、。

  6. 最後の実行結果を見ます

ツールとバージョンを使用します。

DOTNETコア2.2

ケーキ0.33.0

PowerShellの、NuGet、するCredentialProvider

AzureDevopsパイプライン和AzureDevopsアーティファクト

入門

  • ケーキスタンドC# Make、それはC#のDSLに基づいて、自動化されたクロスプラットフォームのビルドシステムである、ので、あなたは、構築されたスクリプトの私たちの以前の使用に置き換えるためにおなじみのC#言語を使用することができます。私たちは、非常に簡単にコンパイルされたコードを使用するファイルやフォルダをコピーし、そしてもちろん、あなたも私たちのコードは問題ありませんことを確認するために、ユニットテストを実行することができ、我々はそれが非常に重要な位置を占めてNuGetアーティファクトを解放するために、この時間を持つことができます。

  • 以前はVSTSとして知られているAzureDevops、それはレポを提供し、パイプライン、ボード、テスト計画、成果物:
    • レポは、ソースコード管理コードのためのGitリポジトリを提供し、あなたはGitHubの上で直接あなたのストレージを導入することができます。
    • パイプラインは、継続的インテグレーションと配信のアプリケーションをサポートするためのサービスを構築し、公開提供(CI / CD)
    • ボードアジャイル等計画と追跡、コードの欠陥管理にかんばんとスクラムアプローチの使用をサポートするツールのセットを提供し、同様のツールテンセントがありTAPD、アリの雲の効果、Huawei社のクラウドDevCloud等が。
    • 試験計画は手動/探索的試験および継続的なテストを含むテストアプリケーションのさまざまなツールを提供します
    • アーティファクトは、公共および民間のソースからのチームは、Mavenの、NPMとNuGetパッケージを共有することができます。
      情報、進捗状況や動向を共有するように構成チームのダッシュボードとカスタマイズ可能なウィジェットなどのコラボレーションツール、;情報を共有するために建てウィキ;設定可能な通知。
  • するCredentialProviderは、認証が必要なときに我々が押しNuGet、単にNuGetプログラムにそれを置く、資格情報プロバイダです。

ケーキのインストールと使用

私はGitHubの上に掲載している場合:https://github.com/WuMortal/CakePushNuGet.Example

インストール:ここで私はDOTNETコアプレゼンテーションを使用しています、ケーキは、.NET Frameworkの、モノをサポートしています。まず、このコマンドによってケーキ、DOTNETツールをインストールする必要があります。

dotnet tool install --global cake.tool --version 0.33.0

正常にインストールは、次のプロンプトが表示されます。

ケーキのインストール

ケーキは、使用することは非常にシンプルですが、また、C#の構文は、理解することは非常に簡単であるべきと考えています。

ここではまず、我々はそれが我々が実行しようとしているタスク(タスク)の名前で保存されたターゲット変数を定義します。あなたは、タスクのコードブロックの数の定義に見ることができ、「ミッション」実行されるべき具体的な必要性がある、最初のタスクは、実際には、コアコードの行依存削減プロジェクトである次にDotNetCoreRestore(solution);、2番目のタスクは、プロジェクトを構築することです、あなたがする必要があります第三タスクが一緒に最初の二つのタスクを統合し、実際にあることに注意してください。また、第二の使命できる.IsDependentOn ("Restore")最初のタスクの呼び出しは、当然のことながら、var target = Argument ("target", "Demo");変更する必要がvar target = Argument ("target", "Build");あり、これは個人的な好みに依存します。

ケーキのインストール

var rootPath = "../";   //根目录
var srcPath = rootPath + "src/";    
var solution = srcPath + "Wigor.CakePushNuGet.Example.sln";   //解决方案文件
//需要执行的目标任务
var target = Argument ("target", "Demo");

Task ("Restore")
  .Description ("还原项目依赖")
  .Does (() => {
    //Restore
    Information ("开始执行还原项目依赖任务");
    DotNetCoreRestore (solution);
  });

Task ("Build")
  .Description ("编译项目")
  .Does (() => {
    Information ("开始执行编译生成项目任务");
    //Build
    DotNetCoreBuild (solution, new DotNetCoreBuildSettings {
        NoRestore = true,   //不执行还原,上一步已经还原过了
        Configuration = "Release"
    });
  });

// 执行的任务
Task ("Demo")
  .IsDependentOn ("Restore")    //1. 执行上面的 Restore 任务
  .IsDependentOn ("Build")      //2. 需要执行 上面的 Build 任务
  .Does (() => {
    Information ("所有任务完成");
  });

//运行目标任务 Demo
RunTarget (target);

次のように我々はそれを実行しようとすることができます良いケーキを書き込んだ後、ここに私のケーキパスの構築/ build.cakeは、我々は状況に応じて変更することができますされ、コマンドは次のとおりです。

dotnet cake build/build.cake -verbosity=diagnostic

ケーキの実行

ここでは、ケーキが正常に実行され、私たちはそれぞれのタスクを実行する結果と情報がコンソールに表示されて見ることができます。

ケーキの実行

ここで私たちは、公式ウェブサイトにアクセスするためのマルチユースな方法でそれについて、それを理解するためにケーキを少しやっていると信じて:https://cakebuild.net/

AzureDevopsパイプライン使用

首先你需要一个 Microsoft 账号或者 GitHub 账号,登录地址为:https://dev.azure.com,登录之后你需要创建一个项目,这里我已经创建好一个项目了,首先我们点击 Pipelines 选择 Builds,之后会出现如下界面,点击 New Pipeline。然后跟着我下面图片的步骤一步一步来就行。

AzureDevopsパイプライン使用

如果你的仓储就在 AzureDevops上那么直接选 Azure Repos Git 就行。

AzureDevopsパイプライン使用

这里你的账号是 GitHub 授权登录的话会先跳转到授权界面可能会跳转多次,同意即可。

AzureDevopsパイプライン使用
AzureDevopsパイプライン使用

删除我选中的代码,因为我不打算用 AzureDevops Pipelines 的脚本来执行本次操作,它做的只是提供我们 cake 运行的环境。

AzureDevopsパイプライン使用

更换为如下脚本,PowerShell.exe -file ./cake.ps1 是指使用 PowerShell 运行我们的 cake.ps1 文件,关于 cake.ps1 文件后面会介绍,这里我们先这样写,接着点击 Save and run

AzureDevopsパイプライン使用

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- script: PowerShell.exe -file ./cake.ps1
  displayName: 'Push NuGet Package'

可以看到问们管道的运行出现了错误,那是因为我们上面在运行了 cake.ps1 这个脚本,但是我们现在还没有创建这个脚本。

AzureDevopsパイプライン使用

回到我们的项目中,将 AzureDevops Pipelines 创建的 azure-pipelines.yml 文件 pull 到我们本地。

AzureDevopsパイプライン使用

接着我们编写我们下面缺少的 cake.ps1 文件,它做的事情就是将我们之前手动在 cmd 中运行的命令放入了一个 PowerShell 脚本文件中,Linux 平台的话就编写一个 shell 脚本。

AzureDevopsパイプライン使用

# Install cake.tool
dotnet tool install --global cake.tool --version 0.33.0

# 输出将要执行的命命令
Write-Host "dotnet cake build\build.cake -verbosity=diagnostic" -ForegroundColor GREEN

dotnet cake build\build.cake -verbosity=diagnostic

尝试项目根目录下运行这个脚本,在 cmd 中执行 powershell .\cake.ps1,下面报了一个错。
AzureDevopsパイプライン使用

我们只需要以管理员身份运行 PowerShell 然后执行 set-ExecutionPolicy RemoteSigned 即可

AzureDevopsパイプライン使用

AzureDevopsパイプライン使用

然后再次运行 powershell .\cake.ps1 或者命令,可以看到正确的输出了

AzureDevopsパイプライン使用

OK,这次我们推送(git push)下代码,在到 AzureDevops Pipelines 看看我们执行结果。
AzureDevopsパイプライン使用

点进去可以看到整个执行的过程,如果报错了也可以从这里看到出错的信息

AzureDevopsパイプライン使用

如果是 powershell 报错 AzureDevops Pipelines 是不会显示执行失败的,如果没得到你想要的结果你就需要点开认真的分析你的脚本了。

AzureDevops Artifacts 使用

前面已经讲过了如果使用 cake 和 在 AzureDevops Pipelines 下执行 cake。下面我们需要创建一个 NuGet Repository,这里我使用 AzureDevops 提供的 Artifacts。

成果物を使用しAzureDevops
成果物を使用しAzureDevops
成果物を使用しAzureDevops

这里面会用的就是 package source URL 和下面命令中的 -ApiKey 中的 AzureDevOps,还有这里我们需要将 NuGet + Credentials Provider 下载到我们的本地,如果你的运行环境是 Linux 或其他可以在 microsoft/artifacts-credprovider 的 GitHub 上获取对应平台的这两个包, 点击查看 GitHub 地址

创建 PAT (Personal Access Tokens)

上面说过了我们推送 NuGet 包到 Artifacts 时候是需要为两个参数提供指的的 -UserName 和 -Password,这里的 UserName 我们可以随意填,但是 Password 填的的是我们创建的 PAT。

パーソナル・アクセストークンの使用
個人的なアクセストークンの使用

这是选择我们 PAT 所拥有的权限,需要点击 Show all scopes 找到 Packaging 勾选 Red,wirte,& manage

個人的なアクセストークンの使用

我们可以看到我们的 PAT ,需要注意的是这个 token 只会出现一次,你需要将它保存好,如果忘记了,那么可以点击 Regenerate 重新获取 token。

個人的なアクセストークンの使用

AzureDevops Pipelines 添加变量

上一篇文章 中我说过了为什么需要变量,这里就不重复了,有兴趣的可以看看。下面开始添加我们需要的变量。

変数を追加します
追加の変数

我们需要添加的变量有四个,分别是 NUGET_REPOSITORY_API_URLNUGET_REPOSITORY_API_KEYUSERNAMEPASSWORD

  • NUGET_REPOSITORY_API_URL:就是我们在创建 AzureDevops Artifacts 后出现的 package source URL

  • NUGET_REPOSITORY_API_KEY:就是那个 -ApiKey 参数的值 AzureDevOps

  • USERNAME:这个上面说过了可以随便填。

  • PASSWORD:这个就是之前创建的 PAT。

点击保存(Save & queue)或者 Ctrl + s 保存。

変数を追加します

添加 NuGet.Tool.cake 和 NuGet.exe、Credentials Provider

这里为已经封装过了的工具类包含了打包和推送方法,地址:NuGet.Tool.cake

using System;
using System.Collections.Generic;
using System.Linq;
using Cake.Common.Tools.DotNetCore;
using Cake.Common.Tools.DotNetCore.Pack;
using Cake.Common.Tools.NuGet;
using Cake.Common.Tools.NuGet.List;
using Cake.Core;
using NuGet.Packaging;

public class NuGetTool {
    public ICakeContext CakeContext { get; }

    public string RepositoryApiUrl { get; }

    public string RepositoryApiKey { get; }

    public string UserName { get; set; }

    public string Password { get; set; }

    private NuGetListSettings ListSettings => new NuGetListSettings {
        AllVersions = true,
        Source = new string[] { this.RepositoryApiUrl }
    };

    private DotNetCorePackSettings BuildPackSettings (string packOutputDirectory) => new DotNetCorePackSettings {
        Configuration = "Release",
        OutputDirectory = packOutputDirectory,
        IncludeSource = true,
        IncludeSymbols = true,
        NoBuild = false
    };

    private NuGetTool (ICakeContext cakeContext) {
        CakeContext = cakeContext;
        RepositoryApiUrl = cakeContext.Environment.GetEnvironmentVariable ("NUGET_REPOSITORY_API_URL");
        RepositoryApiKey = cakeContext.Environment.GetEnvironmentVariable ("NUGET_REPOSITORY_API_KEY");
        UserName = cakeContext.Environment.GetEnvironmentVariable ("USERNAME");
        Password = cakeContext.Environment.GetEnvironmentVariable ("PASSWORD");
        CakeContext.Information ($"获取所需参数成功:{RepositoryApiUrl}");
    }

    public static NuGetTool FromCakeContext (ICakeContext cakeContext) {
        return new NuGetTool (cakeContext);
    }

    public void Pack (List<string> projectFilePaths, string packOutputDirectory) {
        projectFilePaths.ForEach (_ => CakeContext.DotNetCorePack (_, BuildPackSettings (packOutputDirectory)));
    }

    public void Push (List<string> packageFilePaths) {

        foreach (var packageFilePath in packageFilePaths) {
            CakeContext.NuGetAddSource (
                "wigor",
                this.RepositoryApiUrl,
                new NuGetSourcesSettings {
                    UserName = this.UserName,
                    Password = this.Password
                });

            CakeContext.NuGetPush (packageFilePath, new NuGetPushSettings {
                Source = "wigor",
                ApiKey = this.RepositoryApiKey
            });

        }

    }
}

在项目的 build/ 下创建 nuget.tool.cake 文件(build/nuget.tool.cake) 拷贝上面的代码。

这里参考了最开始提到的园友的项目,非常感谢它的贡献,GitHub 地址如下:cake.example

在创建 AzureDevops Artifacts 的时候那不是提供了 NuGet + Credentials Provider 的下载地址嘛,现在把它解压到我们项目的 build\tool\ 下。再次说明这里我是 Windows 环境,如果你的运行环境是 Linux 或其他可以在 microsoft/artifacts-credprovider 的 GitHub 上获取对应平台的这两个包, 点击查看 GitHub 地址

NuGet.exe、資格情報プロバイダ

修改 cake.ps1 和 build.cake 文件

修改 cake.ps1,只是增加了 NuGet.exe 的环境变量,因为不加到时候 cake 会找不到 NuGet.exe,或许还有其他办法这里就先这么干,如果各位还有更方便的方法可以在下面留言,感谢!

# 执行的文件
[string]$SCRIPT = 'build/build.cake'

[string]$CAKE_VERSION = '0.33.0'

# 配置 NuGet 环境变量
$NUGET_EXE = "build/tool/NuGet.exe"
$NUGET_DIRECTORY = Get-ChildItem -Path $NUGET_EXE
$NUGET_DIRECTORY_NAME=$NUGET_DIRECTORY.DirectoryName
$ENV:Path += ";$NUGET_DIRECTORY_NAME"

# Install cake.tool
dotnet tool install --global cake.tool --version $CAKE_VERSION

# 参数:显需要执行cake 执行信息
[string]$CAKE_ARGS = "-verbosity=diagnostic"

# 输出将要执行的命命令
Write-Host "dotnet cake $SCRIPT $CAKE_ARGS $ARGS" -ForegroundColor GREEN

dotnet cake $SCRIPT $CAKE_ARGS $ARGS

修改 build.cake 文件,看着是多了很多东西其实就多了两个 Task (任务) 分别是: pack(打包)push(推送包),这里需要大家需要修改的就是 solutionproject 两个变量,将其修改为自己的解决方案名称和需要打包的项目名称。

#reference "NuGet.Packaging"

#load nuget.tool.cake

var target = Argument ("target", "PushPack");

var rootPath = "../";
var srcPath = rootPath + "src/";
var solution = srcPath + "Wigor.CakePushNuGet.Example.sln";
var project = GetFiles (srcPath + "Wigor.CakePushNuGet.HelloWorld/*.csproj");
var nugetPakcageDirectory = $"{srcPath}nugetPackage/";

var nugetTool = NuGetTool.FromCakeContext (Context);

Task ("Restore")
  .Description ("还原项目依赖")
  .Does (() => {
    //Restore
    Information ("开始执行还原项目依赖任务");
    DotNetCoreRestore (solution);
  });

Task ("Build")
  .Description ("编译项目")
  .Does (() => {
    Information ("开始执行编译生成项目任务");
    //Build
    DotNetCoreBuild (solution, new DotNetCoreBuildSettings {
        NoRestore = true,
        Configuration = "Release"
    });
  });

Task ("UnitTest")
  .Description ("单元测试")
  .Does (() => {
    Information ("开始执行单元测试任务");
    
    DotNetCoreTest(solution);
  });

Task ("Pack")
  .Description ("Nuget 打包")
  .Does (() => {
    Information ("开始执行打包任务");

    // 确保目录存在
    EnsureDirectoryExists (nugetPakcageDirectory);

    var packageFilePaths = project.Select (_ => _.FullPath).ToList ();

    nugetTool.Pack (packageFilePaths, nugetPakcageDirectory);
  });

Task ("Push")
  .Description ("Nuget 发布")
  .Does (() => {
    Information ("开始执行 Nuget 包发布任务");
    var packageFilePaths = GetFiles ($"{nugetPakcageDirectory}*.symbols.nupkg").Select (_ => _.FullPath).ToList ();

    nugetTool.Push(packageFilePaths);
  });

Task ("PushPack")
  .Description ("发布 Nuget 包")
  .IsDependentOn ("Restore")
  .IsDependentOn ("Build")
  .IsDependentOn ("Pack")
  .IsDependentOn ("Push")
  .Does (() => {
    Information ("所有任务完成");
  });

RunTarget (target);

最后我们推送修改后的代码,查看执行结果看看 NuGet 包是否发布到 AzureDevops Artifacts 上。

結果

至此已经实现了 使用 Cake 推送 NuGet 包到 AzureDevops 的 Artifacts 上,你如果不熟悉 AzureDevops Pipelines 你也可以用其他的 CI/CD 工具来执行。

补充

在整个尝试过程中肯定会出现一些问题,不要着急认真分析,看看 AzureDevops Pipelines 上给出的提示,也可以现在本机跑一下看看是否正常。出现问题第一步查看错误信息,看看有没有错误信息(基本都有),然后根据错误信息去分析是我们的那个地方出错了,顺序是 cake.ps1 --> build.cake --> nuget.tool.cake,然后是所需的 PAT 的权限是否勾选,AzureDevops Pipelines 变量是否配置并且是 URL、Key 什么的都是正确,再然后就是 百度、Google。最后你可以在评论区留言(分享你碰到的问题以及解决方法)。

相关文献

在这里感谢各位的贡献!

《[Cake] 0. C#Make自动化构建-简介》

《2. dotnet 全局工具 cake》

《基于cake-build的dotnet自动化发布》

「ケーキを使用したAzureのアーティファクトにAzureのパイプラインからパッケージをプッシュ "

AzureDevopsパイプライン変数関連文書

「ミートアズールDevOpsチーム」
参照プロジェクト:CakePushNuGet.Example

参考プロジェクト:cake.example

おすすめ

転載: www.cnblogs.com/AMortal/p/11100669.html