2022年6月18日 星期六

快速產生 .net core 測試程式碼覆蓋率報表

enter image description here

昨天,幫客戶介紹 .net core 的單元測試(Unit Test)開發。

其實,單元測試(Unit Test)是個非常簡單的概念,近代開發工具本身也都進化的超級方便,輕輕鬆鬆的就可以建立出單元測試專案的架構。

單元測試(Unit Test)看起來一點都不難。

這話只對了一半,單元測試難的地方並非撰寫單元測試程式碼本身(甚至,單元測試程式碼本來就應該盡可能的簡單,簡單到不該出現邏輯),難的地方是為了實施單元測試前的程式碼重構(如何增加程式碼的可測試性),以及如何在企業內真的推廣和實作。(因為上至主管下至開發人員,總有成千上百個看來非常合理的理由,解釋為何自己現階段無法導入單元測試)

不過,這些困難的問題,我們留到課程裡面再討論。

我們今天先來看一個簡單的,如何在 .net core 產生測試程式碼覆蓋率的報表。

其實,只有三個動作,第一個,請安裝 .net tool:

dotnet tool install -g dotnet-reportgenerator-globaltool

然後
透過 dotnet CLI 跑一次單元測試進行資料蒐集,記得請在 .sln 或 .csproj 所在的目錄下執行:

#收集資訊
dotnet test --collect:"XPlat Code Coverage"

請注意上面的 --collect:“XPlat Code Coverage” 參數,是為了蒐集單元測試涵蓋率資訊,執行完畢之後,會出現底下畫面,請特別注意XML檔案所在位置:
enter image description here

因為我們下一個指令需要該位置資訊。

最後,請執行:

reportgenerator  -reports:"路徑\coverage.cobertura.xml" -targetdir:"report" -reporttypes:Html

嘩啦,單元測試涵蓋率報表出來了(位於report資料夾中,還是HTML格式的),就這樣:
enter image description here

簡單吧~

2022年5月26日 星期四

迭代、敏捷 與 滾動式調整

enter image description here

今天上課的時候,跟同學聊到,最近很流行的一個詞彙 『滾動式修正』(或 滾動式調整)。

不知道你自己對這個詞的定義是什麼? 所謂的『滾動式調整』是不是走一步算一步? 是不是朝令夕改的美化版? 是不是先做再說,後面再看著辦?

儘管很多人不明所以,但『滾動式調整』這個詞彙這幾年仍被許多團隊理所當然地使用著。為何過去從沒聽過,這幾年卻如此盛行? 我自己覺得,和敏捷(Agile)似乎脫不了關係。

敏捷(Agile)存在的意義,是因為我們認知到並承認,現今外在環境的變化實在太快了,快到我們再也沒法像過去一下,先妥善地做完計畫,然後再動手實行。如果堅持如此,將會錯失先機。

此外,更重要的是,倘若沒有先著手實施,試著得到外界真實的反饋,只在辦公室裡籌算,即便覺得計畫得再周密,一但拿到真實世界裡,很可能就會立刻破功。

這兩者都是同樣的前提 --> 這個世界變化得愈來愈快。
這也是敏捷之所以日趨主流的原因。

而敏捷的被認可,或多或少讓『滾動式修正』變得理所當然。然而,真的每一個組織,每一個單位,每一個計劃,都適合滾動式修正嗎?

今天上課談的是DevOps。
我問學員:『如今需求變化快速已不可避免。假設,持續交付 (所謂的持續交付,一般是指一天數次這樣的頻繁上版,最少也是一周數次,不會更低)是必須的,那什麼是持續交付的基礎?』『一家公司、一個團隊,一個專案,能夠毫無準備的就實施頻繁交付(CD-Continuous Delivery)嗎?』

答案是 : 『不能』。

因為,沒有良好準備的頻繁交付,將會帶來災難

頻繁交付的前題是持續整合(CI-Continuous Integration),持續(密集)到什麼程度? 最好應該是一天數次,至少是一周數次,將程式碼頻繁的簽入並且合併至主線(main)。同時在合併前進行程式碼品質掃描、安全性掃描、單元測試。如果這些都沒做到,那請容我這麼說,目前這個團隊(專案)恐怕還不到可以實施頻繁交付(CD-Continuous Delivery)的程度。

所以,持續交付(或謂 頻繁交付,不過這兩者其實有些許不同)的前提,是良好的基礎建設(這邊指的基礎建設是指 CI - Continuous Integration)。

同樣的,若企業想要執行『滾動式修正』,你的團隊和行政體系必須要有足夠良好的體質,這體質指的是 : 快速的執行效率、順暢的溝通管道、卓越的行政系統、高效的組織架構。不僅如此,還要有良好的防呆機制和安全性防護措施(就如同我們在CI的過程中,有著各種自動化檢查和安全性掃描一樣)。

唯有已具備良好體質的團隊,在面對快速迭代、持續修正的計畫與指令時,才能游刃有餘。

否則,我們的『滾動式修正』將帶來災難,大家看到的只會是『滾動』,而沒有『修正』。沒有辦法得到持續修正、持續改善的效果。要記得,並非所有的『滾動』都會帶來價值,就如同並非所有的『頻繁交付』都會為帶來價值一般。

我們真正想要的並不是滾動,而是修正。正如同敏捷想要的並不是迭代,而是持續改善

唯有頻繁修正、持續改善才是價值的來源。而為客戶帶來價值,才是我們真正想要實現的成果。

2022年5月21日 星期六

Azure DevOps in Action - 部署到僅支援FTP的環境

除了採用Azure WebApp作為網站應用程式的運行環境之外,肯定有更多的開發人員,是採用其他的環境作網站的部署。有可能是主機代管,有可能是其他的雲端服務,也有可是地端環境。

那這些環境該如何進行部署呢? 最簡單的方式是透過FTP。

FTP是絕大部分網站肯定都支援的部署方式,也是傳統手動進行網站部署行為的時候,最常見的選擇。

要在Azure DevOps的pipeline當中進行FTP部署相當容易,你可以透過FTP Upload這個內建的task,即可完成上傳動作:
enter image description here
當你把該task加入job中之後,會看到底下設定:
enter image description here
上圖A的部分,是站台的身分驗證方式,你可以選擇為此站台建立一個connection或是直接輸入身帳號密碼,上圖中,我們選擇直接輸入帳密。

而上圖B、C、D三個欄位則是FTP伺服器的URL以及帳號密碼,這應沒什麽疑義。但需要注意的是上圖E,這個欄位需要輸入的是FTP來源檔案位置,也就是Pipeline當中,先前build好的artifacts所在的位置。這個位置從何而來? 由於目前我們展示的是CI Pipeline,因此該位置你應當參考前面Publish Task的結果:
enter image description here
參考上圖A,Buld好的結果預設的輸出位置使用了系統變數『$(build.artifactstagingdirectory)』,因此,我們在FTP Upload的Task中,Root Folder就是設定為『$(build.artifactstagingdirectory)』:
enter image description here
另外,請特別留意Publish Task中的『Zip published projects』選項,它預設是勾選的,你會發現我們將其取消了。原因是,勾選該項目,會讓publish task將發佈的成品壓縮成.zip檔案,但如此一來我們透過FTP送上站台的時候,反倒不能直接運行了。

因此,原本publish的zip選項必須取消。然後,我們再回頭看FTP Uploader task的Root foder,其設定就是先前Publish task的output位置:
enter image description here
最後,別忘了設定你上傳後這些檔案要放在遠端站台的哪一個路徑(上圖F),這個位置可能因為你選擇(或設定)的Web Server的不同而不同,上圖site/wwwroot是因為我們選用的是azure web app,其預設路徑就是site/wwwroot這個位置。

當你運行該Pipeline,會發現FTP Uploader確實可把檔案上傳到伺服器端:
enter image description here
如此一來,就可以順利地透過FTP在Pipeline中發佈網站囉。

備註:
上面的範例雖然是採用CI Pipeline來進行,但若讀者想要使用CD(Release) Pipeline來進行一樣的動作,當然也是可行的。

YT Video:
https://youtu.be/GgmwpaoJo84

參考資料:
Azure DevOps 顧問實戰
https://www.tenlong.com.tw/products/9786263241251?list_name=b-r7-zh_tw

電子書:
https://www.pubu.com.tw/ebook/288713

2022年5月16日 星期一

自動幫用戶開啟RichMenu與鍵盤or語音輸入

LINE在2022/5/13增加了postbackAction的屬性,讓發人員可以藉由送出一個含有postbackAction的訊息(類似底下這樣),來幫用戶來開啟(或關閉)rich menu,甚至可以開啟輸入鍵盤和語音:
enter image description here

上圖 A 的部分,是一個 Buttons Template Message,其中有四個按鈕,其類型都是我們先前介紹過的 postbackAction。

在過去,當用戶點下postbackAction按鈕時,只會讓伺服器端的WebHook收到一則訊息,但LINE 2022/5/13 增加了此功能之後,postbackAction多了兩個重要的屬性,分別是inputOption與fillInText。

inputOption可以是底下的值:

  • closeRichMenu: 關閉 rich menu
  • openRichMenu: 開啟 rich menu
  • openKeyboard: 開啟輸入鍵盤
  • openVoice: 開啟語音輸入

而 fillInText 則是當inputOption為openKeyboard時,開啟的文字輸入鍵盤中的預設文字。

例如,當建立 postbackAction 的程式碼如下:

Actions.Add(new  isRock.LineBot.PostbackAction() 
{
label  =  "開鍵盤",
data  =  "openKeyboard",
displayText  =  "開鍵盤",
fillInText  =  "預設文字",
inputOption  =  "openKeyboard"
});

則用戶點選該選單後,結果如下:
enter image description here

當您建立 postbackAction 的程式碼如下:

Actions.Add(new  isRock.LineBot.PostbackAction() 
{
label  =  "開選單",
data  =  "openRichMenu",
displayText  =  "開選單",
inputOption  =  "openRichMenu"
});

則用戶點選該PostbackAction選項,結果如下:
enter image description here

你還可以透過底下指令,來開啟語音輸入:

Actions.Add(new  isRock.LineBot.PostbackAction() 
{
label  =  "開語音輸入",
data  =  "openVoice",
displayText  =  "開語音輸入",
inputOption  =  "openVoice"
});

執行結果如下:
enter image description here

很有趣吧,這功能可以讓你的LINE Bot與用戶的互動更加的便捷, .net core 的範例程式碼在底下:
https://github.com/isdaviddong/ExLineRichMenuautomaticOpeningAndClosing

你只需要將 LineBotSDK 升級到 2.5.33-beta 以上的版本即可。

2022年5月13日 星期五

Azure DevOps 中的 Release Gate

enter image description here
在使用自動化上版的過程當中,你大概或多或少會想要使用簽核(Approval)的功能。簽核功能讓你可以自動佈署到特定站台(例如正式機)之前,形成一個 “把關” 的功能。

雖然感覺用起來很酷,但坦白說,我們對於上新版程式前的Approval行為,在態度上是不鼓勵的。因為多年下來,並沒有案例顯示,上版前的簽核真能夠減少什麼風險或是降低問題發生的機率。反倒是常常因為Approver卡住流程,造成自動化效率的降低。

如果企業是為了要有人負責,才配置這個Approver,那我們就更不鼓勵了。因為大部分的Approver其實無法在上版前真的做什麼檢查,常常有簽核權限的PM只是回頭問問工程師 : 『可以上正式機了嗎? 可以? 那我就按"同意"了唷』。這樣的橡皮圖章其實讓人很心酸。

事實上,大部分能做該做的檢查,根本早就在(也應該要在)自動化流程中被完成,而非靠人工的檢核。

更好用的機制 - Release Gate

比起Approvals的設定,Release Gate其實是配合自動化部署更好的選擇。

設定的方式類似 Approvals,只需要先將選項設為 Enabled即可啟動(下圖A),接下來就是設定要作為Gate的機制(下圖B):
enter image description here

按下Add之後,你可以選擇要作為Gate的機制:

enter image description here

系統已經內建不少的Gate類型可供選擇,其中比較常用的大概是『Invoke REST API』和『Query work items』。另外『SonarCloud Quality Gate』則是外掛的套件,配合SonarCloud軟體品質掃描用的。

當你設定了Release Gate這個機制,它將會每隔幾分鐘(最少五分鐘)檢查一次你設定的條件,當該條件成立的時候,才會允許Pipeline繼續往下進行。

這個功能可以幫助我們,在自動化的過程中減少不需要的人力介入或簽核,即可自動檢查特定條件是否成立。你也可以撰寫Azure Function,或是使用Invoke REST API方法來呼叫特定API,取得回傳值,以判斷是否可以讓Release Pipeline繼續往下運行。

在高強度(一天數次或一周數次)的頻繁交付過程中,Release Gate比起人工簽核(Approval)更是合作上版前的自動化關卡檢查機制。

來,以後試著放棄橡皮圖章吧。


參考資料:
Azure DevOps 顧問實戰
https://www.tenlong.com.tw/products/9786263241251?list_name=b-r7-zh_tw

2022年4月27日 星期三

Azure DevOps in Action - 建立Linux環境的Build Agent

Azure DevOps也可以輕易地建立在Linux環境上的Build Agent,底下我們將會採用Ubuntu的VM環境來示範這個動作。

首先,我們建議您用Azure上的Ubuntu 20.04虛擬機範本,相關的建立參數如下:
enter image description here
我採用D4s_v3的虛擬機等級,在East Asia資料中心建立該伺服器。同時為了讓我能夠從Windows環境連上該伺服器做後續設定,我選擇了開啟SSH(22) Port。

請牢記你建立時所輸入的帳號密碼。

在虛擬機建立完之後,可以透過PowerShell(我是使用 Windows Terminal)以ssh指令來連上該伺服器,並且輸入密碼:

ssh 帳號@IP

例如:
enter image description here

遠端登入成功之後,即可對該伺服器下達指令。

先整理一下我們登入後要做的事情,分別是:

  1. 安裝 .net core SDK(為了可以進行 dotnet build)
  2. 下載Azure DevOps Agent套件(壓縮檔)
  3. 解壓縮套件
  4. 安裝套件並進行設定(過程中需用到PAT)
  5. 執行Agent

整個動作,可以從Azure DevOps的Orgnization Settings開始:
enter image description here
從Orgnization Settings選單點選Agent Pools,選擇Default(即為Self-Hosted Agent),接著點選New Agent。

在出現的畫面中,請點選Linux,你會看到安裝Linux Build Agent的步驟:
enter image description here
首先,請點選上圖A的部分,複製agent套件的下載位置,在筆者截稿時,該位置為:

https://vstsagentpackage.azureedge.net/agent/2.202.1/vsts-agent-linux-x64-2.202.1.tar.gz

接著,請在powershell以ssh連線的ubuntu環境中,下達底下指令:

mkdir myagent && cd myagent

這會建立一個myagent資料夾,並且進入該資料夾中。

接著,請執行底下指令,來下載agent:

curl -O https://vstsagentpackage.azureedge.net/agent/2.202.1/vsts-agent-linux-x64-2.202.1.tar.gz

其中 curl -O 是下載檔案,而後面的url,請換成您剛才在上圖A中所複製到的最新版URL。

接著,再透過底下指令解壓縮:

tar zxvf vsts-agent-linux-x64-2.202.1.tar.gz

完成後,執行ls指令,會看到類似底下這些內容:
enter image description here
這樣我們待會就可以進行設定了。

但在此之前,我們得先準備好PAT(Personal Access Token),以及為該伺服器準備 .net core sdk環境。

參考 https://docs.microsoft.com/zh-tw/dotnet/core/install/linux-ubuntu 的說明,您可以透過運行底下指令,來安裝 .net core sdk:

wget https://packages.microsoft.com/config/ubuntu/21.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

sudo apt-get update;
sudo apt-get install -y apt-transport-https &&
sudo apt-get update &&
sudo apt-get install -y dotnet-sdk-6.0

過程中可能會需要您輸入密碼,請在powershell中執行上述指令,結果類似底下這樣:
enter image description here
若你需要安裝其它版本的.net core sdk,可以修改上面指令中的版號即可,例如:

sudo apt-get install -y dotnet-sdk-5.0

成功安裝後,我們就要進行最後一個步驟了。

請先準備好PAT,取得PAT的方式如下,請先點選Azure DevOps畫面右上角個人帳號旁邊的小人圖示:
enter image description here
接著在選單中選擇 『Personal access token』,即會出現建立PAT的畫面:
enter image description here
在出現的畫面中選擇建立新的PAT。

PAT是替代你的帳號密碼的令牌,在你指定的有限時間內,出示該令牌就等於具有你所賦予的權限。

建立好了之後,請保留該PAT,它的長像大概是底下這樣:

zs4l6xp7xwhnj7lp8ta7i4q3xhtfasaxs3vp6xxwrj6iger7i63ob2eq

接著,請回到剛才的powershell視窗,在myagent資料夾底下執行:

./config.sh

執行過程中,會需要輸入PAT:
enter image description here
請留意,上圖2中的URL,要輸入的是你的Azure DevOps站台位置,而輸入PAT之前(上圖3),會先要你按一個Enter(請仔細注意上面的英文敘述),然後才是輸入PAT(按下滑鼠右鍵即可貼上)。

後面的幾個選項都按Enter即可,完成後,你會看到Setting Saved.

接著,再執行 ./run.sh ,你會發現,系統已經開始運作,並且在等待jobs了 :
enter image description here
這時候,你就可以使用這個 agent pool來進行build job了。

你可以依照先前我們介紹過的方式,建立一個 .net core 程式的CI Build Pipeline,唯一不同的地方是,這次(下圖1)Agent Pool選擇的是Default(Private) ,其它的設定均不變:
enter image description here
當你運行該Pipeline時,會發現,這個Build Machine比Azure DevOps內建的來的快很多,自然是因為這台VM我們建立時選擇的等級是很高檔的。

沒多久,整個CI Build就順利的完成了:
enter image description here
你也會看到,PowerShell中,Ubuntu的Command Line出現相對應的提示訊息:
enter image description here
表示job被成功的完成了。

如果要停止該agent,可以在命令列按下CTRL+C,如果要移除該agent,只需要下達 ./config.sh remove指令,並輸入PAT即可:
enter image description here
建立一個私有的Linux Build Agent就是這麼簡單。

相關資源:

[書籍]Azure DevOps顧問實戰:
https://www.tenlong.com.tw/products/9786263241251?list_name=b-r7-zh_tw

[課程]敏捷開發專案管理與Azure DevOps實戰
https://www.studyhost.tw/NewCourses/ALM

2022年4月26日 星期二

No hosted parallelism has been purchased or granted.

近期上課時,許多學員在申請好Azure DevOps站台後,使用Build Pipeline時,可能會發現它發生了類似底下這樣的錯誤訊息:
enter image description here
完整的錯誤訊息是:

##[error]No hosted parallelism has been purchased or granted. To request a free parallelism grant, please fill out the following form https://aka.ms/azpipelines-parallelism-request

這段錯誤訊息的起因,是由於2021年3月之後,微軟已經取消了預設的免費pipeline使用,若您要使用免費的pipeline,必須依照上述的訊息,填寫申請表(網址如下):
https://aka.ms/azpipelines-parallelism-request

經過同學測試,如果申請成功,你會收到微軟寄來的信件,告知您已經可以使用。但因為填寫申請表曠日廢時(大概要2-3個工作天),若您不想等待,我們還有一個更簡單(但可能需要點費用)的方法。你可以用登入Azure DevOps相同的帳號,申請一個免費的Azure Trial訂閱,接著將該訂閱綁定於Azure DevOps服務即可:
enter image description here
當成功設定好訂閱(Subscription)連結之後,您必須將Paid parallel jobs設定為1(參考下圖):
enter image description here
設定完成儲存之後,立即可以使用Pipeline

特別注意,每一個 Paid parallel jobs 可能會花費 $40USD唷,請特別留意費用的產生。

熱門文章