【把玩Azure DevOps】Day9 CI/CD从这里:编译专案与上传成品

前面的文章都是在介绍Pipeline介面、范本内容,这一篇终於要真正进入正题,将Repo中的ConsoleApp透过Pipeline来编译,并且将编译完成的成品放到Pipeline的成品库(Artifacts,但是这个并不是Project左边选单的Artifacts)。

首先将Yaml档案中steps底下的内容删除:

https://ithelp.ithome.com.tw/upload/images/20210921/200339610AT43teJ5s.png

接着从右边的Task清单(没看到请按Show assistant)中选择「.Net Core」这个Task,之後会出现这个Task的属性编辑画面,如果属性旁边有个圈圈包起来的i字母,代表点击之後可以得到一些提示资讯(嗯,好像玩游戏):

https://ithelp.ithome.com.tw/upload/images/20210921/20033961vw3X7R17Ar.png

https://ithelp.ithome.com.tw/upload/images/20210921/20033961Y2Lv7CGHGr.png

在Command的部份维持build这个选项,底下的Path to project(s)的部份刚好被截图挡住了,提示内容中提到可以用「 ** / *.csproj」来代表所有子资料夹底下的c#专案档( *.csproj),不过这里并不打算这麽做,因为我只想要Build Console app专案,所以输入ConsoleApp/ *.csproj。

下面的Arguments则是输入-o $(Build.BinariesDirectory),代表Build完的档案要输出到$(Build.BinariesDirectory)所代表的位置,下一个Task会使用到它。

输入完之後,在按下Add按钮之前,有一个重点…就是左边的Yaml内容的游标所在位置,因为当按下Add的时候,它会从游标所在位置插入内容,所以请务必确认是在所要插入内容的位置(这里的范例就是最後一行的最前面,这里就不另外截图了,可以自己试试看)。

加入了.Net Core task之後,Pipeline执行到这个Task会利用dotnet cli执行build指令编译Console app专案,但是我希望在Pipeline执行完之後可以将Build出来的档案压缩成zip,所以我再点击了「Archive files」这个Task,属性的编辑内容如下图:

https://ithelp.ithome.com.tw/upload/images/20210921/200339615mbjYi3ZZH.png

https://ithelp.ithome.com.tw/upload/images/20210921/20033961NtcHQ36RVb.png

Root folder or file to archive属性中的内容是$(Build.BinariesDirectory),这是一个系统内建的变数,代表的是build的输出目录,在Azure DevOps中有许多预先定义的变数(官方文件:英文/中文),设定Pipeline的时候会时常用到不同的预先定义的变数,善用它们和不同的Task就可以组合出不同的Pipeline。

Prepend root folder name to archive paths的选项则是代表要不要包含上面所设定的资料夹,也就是$(Build.BinariesDirectory)这个资料夹,视需求决定是否勾选,这边我将它取消勾选

Archive type选项预设是zip,也可以选择其它的选项,包含有zip、7z、tar、wim。zip还是最容易使用的格式,所以使用预设值即可。

Archive file to create属性设定的是压缩档要存放的位置和档名,预设值是$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip, $(Build.ArtifactStagingDirectory) 是预设存放成品(Artifact)的资料夹, $(Build.BuildId) 则是这个Pipeline执行的识别码(这里的例子是1,2,3,4,…),之後的文章范例会改用别的,这里先使用预设值。(这里的Task属性都是使用预设值)

确认没问题之後同样按下底下的Add将Task的设定加入左边的Yaml编辑区。

Build的Task有了,压缩的Task也有了,但是并不代表这样在Pipeline执行完之後就可以取得压缩的zip档案了,Pipeline可没有那麽聪明!所以我们还需要再加上把zip档案上传的Task,就是Publish build artifacts task:

https://ithelp.ithome.com.tw/upload/images/20210921/20033961wn4DaS51bW.png

在Task清单中寻找这个Publish build artifacts的时候会看到许多和它很像的其它Task,其中有一个叫做Publish Pipeline Artifacts的Task:

https://ithelp.ithome.com.tw/upload/images/20210921/20033961mxDFhLtc9i.png

这两个实在是很像,也很容易搞混,所以我决定把这两个Task都加进来,然後执行之後看一下结果的差异。

首先来看看Publish build artifacts task的属性编辑画面:

https://ithelp.ithome.com.tw/upload/images/20210921/20033961U1MzibPJUG.png

上图中除了Artifact name不是预设值(drop)之外,其它的都是预设值。Artifact publish location的选项除了Azure Pipelines可以选之外,还可以选择A file share,不过这个选项是给Self-hosted agent使用的,因为设定的位置必须是agent可以存取的位置,云端的agent应该没有其它可以存取的位置。

下面的是Publish Pipeline Artifacts task的属性编辑画面:

https://ithelp.ithome.com.tw/upload/images/20210921/200339610pveDUJ5Hq.png

看看,除了使用的变数不同之外,还真的是一模一样。Artifact name和Artifact publish location都相同,很容易理解,那第一个选项有不同的意义吗?点击小i的提示来看看好了:

https://ithelp.ithome.com.tw/upload/images/20210921/20033961vicT3RLV54.png

惨了…从这里实在看不出来有什麽差异,怎麽办呢?

上面那几个Task在按下Add的时候,有没有注意到它的旁边有个About this task的字样?大部份的Task都会有这个About this task连结,可以点击之後开启Task的相关说明页面(通常官方的Task都有,但是第三方制作的也可能没有)。

https://ithelp.ithome.com.tw/upload/images/20210921/20033961mFOeRGHqdI.png

点击Publish build artifacts task的About this task会连到这个页面,但是如果点击Publish Pipeline Artifacts task的About this task会跳出一个错误连结的页面,不过因为Publish Pipeline Artifacts这个Task也是官方制作提供的,所以从Publish build artifacts task连结到的页面中,可以看到左边的项目就有Publish Pipeline Artifact可以选择,所以Publish Pipeline Artifacts task的说明页面应该是这个连结

https://ithelp.ithome.com.tw/upload/images/20210921/20033961fGWmf8burL.png

从官方的说明页面中找到了答案:

Note
This task is deprecated. If you’re using Team Foundation Server 2017 or newer, we recommend that you use the Pipeline Artifacts task instead.

也就是说Publish build artifacts task是旧的,官方建议TFS2017之後的版本改用Publish Pipeline Artifacts task,难怪两个Task看起来根本一模一样。

其实从这里是要带出一个观念,就是碰到问题或不了解的东西不要轻易的举白旗投降,花一些时间寻找问题点或答案就可以继续下去。同样的,虽然在这一系列的文章中可能无法完全的介绍到每一个细节,自己摸索尝试也可能会碰到一些不同的问题,但是官方的文件其实很详细的说明了各种资讯,只是通常大家都很懒得去看XD。

写到这里岔开话题聊一下碰到问题轻易投降这部份…我曾经碰过一个开发者光是看到Exception吐出的那一长串Stack资讯就直接投降的,看都不太看就直接把讯息贴给我,问我该怎麽解决?殊不知只要花个5-10秒看一下内容,再思考个3-5秒,问题点的答案马上就出现了…

话题还是再转回来最终完成的yaml内容吧!

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- master

pool:
  vmImage: ubuntu-latest

steps:
- task: DotNetCoreCLI@2
  inputs:
    command: 'build'
    projects: 'ConsoleApp/*.csproj'
    arguments: '-o $(Build.BinariesDirectory)'
- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(Build.BinariesDirectory)'
    includeRootFolder: true
    archiveType: 'zip'
    archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
    replaceExistingArchive: true
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'BuildOutputFiles'
    publishLocation: 'Container'
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)'
    artifact: 'ArtifactFiles'
    publishLocation: 'pipeline'

执行之後从下图红框中可以看到有2个published,可以对比一下前一篇Starter范本执行的结果,一个是0 published,这个则是2 published。

https://ithelp.ithome.com.tw/upload/images/20210921/20033961gR0oEPbPo1.png

点击2 published之後就可以进入此次Pipeline执行结果的成品库(Artifacts),每次Pipeline执行都可以将执行时产生的档案放到那一次执行的成品库,每次执行的成品库都是独立的,这个在之後的Release部份也会使用到。

https://ithelp.ithome.com.tw/upload/images/20210921/20033961wWtBqHWpjS.png

从上图加上Task属性的编辑画面对照就可以很容易理解之间的关系了,Task中设定的Artifact name指的就是成品库(或资料夹概念)的名称,可以将Pipeline产生的档案分门别类的放在不同的Artifact名称底下,例如:Executable programs、Sql scripts、Config files,後续建置的Release pipeline或是比较进阶的Build pipeline不同的stage可以下载各别Artifact内的档案,不需要全部的档案都下载。

在上图的ArtifactFiles底下有很多的资料夹与档案,像是TestResults、a、b、s等资料夹,这是因为Publish Pipeline Artifacts第一个属性设定的是$(Pipeline.Workspace),也就是把Pipeline中相关的档案与资料夹都上传上来了,也就是说 $(Pipeline.Workspace) 是Pipeline执行的根目录,它与Agent.BuildDirectory是相同的内容。

a、b、s虽然只有一个字母,但是其实很好理解,分别代表Artifacts、Binaries、Sources,也就是ArtifactStagingDirectory、BinariesDirectory、SourcesDirectory的意思,在Build底下有这几个变数可用(请参考预定义变数),在之後的文章介绍到Self-hosted Agent的时候也可以看得到相关的目录结构。


<<:  【从零开始的Swift开发心路历程-Day9】打造美观的App版面!UI属性篇

>>:  DAY6-EXCEL统计分析:计算连续型机率

[Day26] Click and Drag to Scroll

[Day26] Click and Drag to Scroll 需要用到的技巧与练习目标 mous...

Material UI in React [Day 22] Data Display (part 2) 分隔线 & 列表

今天会接续昨天未讲解的部分往下... Divider 其实他就是分隔线而已,跟 hr tag 是差不...

初学者跪着学JavaScript Day16 : 阵列Array 迭代的小小秘密

一日客语:中文:早安 客语:anˋzoˋ安走 前提:在学习Array.methods时会想知道他是如...

# JS杂食-06--小实作-1: Star Calculator

参考资料1:MDN — the Mozilla Developer Network 参考资料2:0...

[第18天]理财达人Mx. Ada-证券扣款帐户银行余额资讯

前言 本文说明查询证券扣款帐户银行余额资讯。 程序实作 程序 # 扣款帐户余额资讯 balance ...