從Visual Studio發布NuGet Package的好幫手-NuGet Packager
2 |
最近在寫共用元件,打算放在公司的NuGet私服供同事下載安裝,換版時還可自動更新,大大降低管理成本。講到製作NuGet Packet,NuGet Package Explorer雖然方便,但畢竟是GUI工具,我希望修改元件並測試OK後,直接在Visual Studio專案按個鍵就自動上傳到NuGet伺服器。經過評估,找到一個好用套件-NuGet Packager。
我習慣修改元件後先手動丟上測試環境,測試一陣子沒問題再發布到NuGet伺服器,不要每次建置就發布,因此不適合將發布程序做成Build Task或寫成建置事件。NuGet Packager的做法是提供NuGet Package專屬專案,專案依據Package規格做好content、lib、tools、src目錄, 當需要額外加入Script、工具、內容檔案就放入對應的資料夾,檔案還能納入版控;實務上Package打包檔案的來源也可能來自其他專案項目或編譯結果,此時可在Package.nuspec使用相對路徑,編譯時直接由來源取得最新結果,不需要手動複製及同步,十分方便。(詳見隨後範例)
由於是獨立專案,我們可自由決定發布時機,而NuGet Packager採取的規則是:使用Debug模式編譯只產生.nupkg檔案,在Release模式則會編譯並上傳NuGet伺服器。
以下用簡單範例介紹NuGet Packager的使用方式。
首先,在Extensions and Updates搜尋"nuget packager"並安裝:
安裝之後,Visual Studio會多出一種專案型別-NuGet Packager:
在解決方案中新增一個NuGet Packager專案,專案的目錄結構如下:
content、lib、src、tools都是NuGet用來擺放不同用途檔案的資料夾,而tools裡也先預備好init.ps1、install.ps1、uninstall.ps1等安裝及解除安裝腳本範本。(如果不知道檔案該怎麼擺,可先用NuGet Package Explorer操作再觀察檔案結構)
下一步是編輯Package.nuspec:
<?xml version="1.0"?>
<package >
<metadata>
<id>MagicApiClient</id>
<version>1.0.0</version>
<title>MagicApiClient</title>
<authors>Jeffrey</authors>
<owners></owners>
<description>某個魔法API的客戶端元件</description>
<releaseNotes>
</releaseNotes>
<summary>簡化魔法API呼叫邏輯的神祕元件</summary>
<language>en-US</language>
<projectUrl>http://blog.darkthread.net</projectUrl>
<iconUrl>httq://some-server//Icons/magic.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<licenseUrl>http://opensource.org/licenses/Apache-2.0</licenseUrl>
<copyright>Copyright 2016</copyright>
<dependencies>
</dependencies>
<references></references>
<tags></tags>
</metadata>
<files>
<file src="lib\" target="lib" />
<file src="..\MagiApiClient\bin\Debug\MagicApiClient.*" target="lib"></file>
<file src="tools\" target="tools" />
<file src="content\" target="content" />
</files>
</package>
需要修改的欄位包含id、version、title、description、summary、projectUrl、iconUrl,另外範本預設會將放在lib、tools、content下的所有檔案打包。前面提到.nuspec可以設成直接抓取來自其他專案的內容,在以上範例我加了一個<file src="..\MagiApiClient\bin\Debug\MagicApiClient.*" target="lib"></file>,將MagicApiClient專案的bin\Debug\MagicApiClient.dll、MagicApiClient.pdb、MagicApiClient.xml打包裝入lib,如此其他專案引用時會有Intellisense提示函式、參數說明,出錯時還會顯示程式碼位置。
改完Package.nuspec,用Debug模式編譯,相關檔案就會打包成MagicApiClient.1.0.0.nupkg放在NuGet.Packager專案根目錄,已可手動上傳至NuGet Server,手動上傳方式可以參考之前的介紹。
手動上傳有點遜,當然要做到點幾下滑鼠就自動上傳才酷,有幾個步驟:
- 編輯NuGet.Packager專案的nuget.config檔案,將私服加入packageSources
- 如果你的NuGet私服有設API Key(建議要設,以免阿貓阿狗亂傳蓋檔或被惡意人士下毒),要先設定上傳時使用的API Key。有兩種做法:
第一種是使用nuget.exe,透過nuget.exe setApiKey my-api-key -Source httq://intranet-server/NuGetServer/nuget 指定特定伺服器所用的API Key。設定後,NuGet會將API Key加密儲存在目前帳號的%appdata%\NuGet\NgGet.config,之後由該帳號上傳至該NuGet Server就會自動引用。
另一種做法是將API Key寫入NuGet.Packager專案的nuget.config,由於NuGet採取加密後儲存,要先用nuget setApiKey設定,再從%appdata%\NuGet\NuGet.config抄apiKeys設定。不過,NuGet config檔加密時用的是使用者專屬加密金鑰,故無法在多開發者間共享API Key設定。
修改後的nuget.config如下例:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<apikeys>
<add key="httq://intranet-server/NuGetServer/nuget" value="AQAAANC…34uA==" />
</apikeys>
<packageSources>
<add key="Private NuGet source" value="httq://intranet-server/NuGetServer/nuget" />
</packageSources>
</configuration>
接者改用Relase模式編譯專案,MagicApiClient.1.0.0.nupkg就會自動上傳到NuGet伺服器囉~ 整個NuGet Package打包上傳的程序是不是變得簡單多了呢?NuGet Packager萬歲!
註:若NuGet Package已存在於NuGet Server,上傳的版號必須比現存版號高,否則會發生Package已存在無法覆寫的錯誤。
Comments
# by 余小章
Hi,黑大 有沒有考慮用TFS Build vNext https://dotblogs.com.tw/yc421206/2016/04/27/tfs2015_build_vnext_release_deploy_internal_nuget_server
# by Jeffrey
to 余小章,公司TFS環境升級速度跟不上,TFS Build vNext暫時派不上用場,殘念。