資料庫與Redgate SQL Toolbelt和Azure DevOps的持續整合
理論與實踐中的資料庫CI
CI背後的理論是,如果我們每天多次將程式碼整合到共享儲存庫中,然後透過執行自動構建和後續測試來驗證每個提交,那麼我們會及早發現並根除問題,並提高軟體的質量。
本文的內容是關於設定管道,使您能夠將CI理論付諸實踐,用於資料庫。當我在2013年釋出關於這個主題的原始文章時,它使用了SVN和Jenkins,並且證明非常受歡迎。這仍然是一條可行的路線,但在我們的行業中,半年是永恆的,其他技術和工具也越來越受歡迎。PowerShell已經成為Microsoft堆疊的主要指令碼語言,而Git是每個人都流行的原始碼控制工具。Jenkins,或者甚至是TeamCity,仍然可以輕鬆地用於CI伺服器,但上個月Azure DevOps取代了Visual Studio Team Services(VSTS),感覺它是撰寫2013年原始帖子新版本的最佳時機。Azure DevOps有免費套餐 任何想要學習本教程的人都可以使用。
因此,本文將使用:
-
Git - 作為源控制系統。
-
Azure DevOps - 託管遠端Git倉庫並自動化資料庫構建
-
Redgate SQL原始碼控制(SoC) - 在本地提交資料庫更改。我們克隆遠端倉庫然後將其連結到SoC,因此我們可以直接從SSMS提交資料庫更改
-
PowerShell - 將提交推送到Azure DevOps上託管的遠端儲存庫
-
Redgate SQL Change Automation(SCA) - 使用PowerShell cmdlet自動執行本地資料庫構建(可選步驟)
-
Azure DevOps的SCA外掛 - 自動化資料庫構建和部署過程
當然,僅僅因為你現在擁有一些CI工具就說你是CI實踐者,就像你購買第一架望遠鏡時聲稱自己是天文學家一樣。這些工具只是必要的第一步。團隊仍然需要採用良好的CI實踐。開發人員需要編寫單元測試,證明每個小的更改都有效。他們必須儘可能多地每天多次提交對共享原始碼控制儲存庫的更改。每次提交都應觸發自動資料庫構建,以確保團隊始終具有可用的資料庫構建過程。每天晚上,團隊應該執行整合測試(本文未涉及),以證明所有單獨的單元一起工作以實現所需的過程。這些CI實踐自然會導致自動部署,
當然,你可以在沒有這些工具的情況下練習CI,但是工具越好,你就能找到更容易和更有價值的CI,就像望遠鏡和天文學一樣。
你需要什麼來開始
本文假定您對SQL Server,Git和PowerShell有基本的瞭解。為了重現這個概念證明,我使用了以下軟體版本:
-
具有管理員訪問許可權的 Windows Server 2016 VM 。您還應該能夠在Windows 10上使用所有類似的結果。
-
SQL Server 2017開發人員版 。你可以在這裡下載。
-
Redgate SQL Toolbelt(2018年10月版) 。您可以在這裡下載它,它提供14天免費試用。特別是,您需要在本地工作站上安裝 SQL Source Control 和 SQL Change Automation 。
-
Git 2.19 。你可以在這裡下載。
-
Azure DevOps帳戶 ,您可以在這裡免費建立一個 帳戶 。
您可以使用該軟體的較舊版本或較新版本,但由於Azure DevOps是託管服務,而且時間是一個複雜的問題,我不會對相容性做出任何承諾。同樣,如果您將來幾個月或幾年閱讀此帖子,您可能會發現Azure DevOps UI已更改:
您還需要一個資料庫來玩。我將使用StackOverflow資料庫,因為它有一個簡單的架構,我知道它的工作原理。對於您的第一次構建,嘗試使用可以單獨構建的簡單內容
localDB
。這不包括
AdventureWorks
,因為
localDB
不支援全文搜尋。此外,現在嘗試避免依賴於其他資料庫的資料庫。
步驟1:建立新的Azure DevOps專案並克隆儲存庫
導航到Azure DevOps中的 Projects 選項卡(在我的例子中,https://dev.azure.com/DLMConsultants/_projects)
為專案指定名稱 ,例如資料庫的名稱。在 版本控制下, 選擇 Git ,然後選擇您的首選 工作項 流程。如果有疑問,預設的工作項流程(敏捷)很好,因為它對本教程沒有任何影響。
將repo克隆到本地工作站 。要執行此操作,請複製Azure DevOps中的HTTPS連結:
現在,開啟PowerShell視窗,導航到您要儲存原始碼的目錄並克隆repo。基本命令如下所示:
git clone https://yourcompany@dev.azure.com/etc
這是我的完整命令視窗:
您現在應該在計算機上有一個本地儲存庫,其中包含一個隱藏的 .git 目錄,您可以在其中新增資料庫原始碼。
第2步:將資料庫連結到源
我們將使用Redgate SQL Source Control,因此請確保已安裝並且您可以在SSMS中訪問您的資料庫。開啟SSMS並右鍵單擊要連結到原始碼管理的開發或測試資料庫。選擇“將 資料庫連結到原始碼管理... ”
Redgate SQL Source Control將在查詢視窗中開啟。選擇“ 連結到我的原始碼管理系統 ”,從支援的原始碼管理系統中選擇“ Git ”,然後貼上到本地原始碼控制儲存庫的路徑中。然後單擊“ 瀏覽 ”和“建立 新資料夾 ”並將“ 狀態 ”目錄新增到源控制元件儲存庫的根目錄,並將資料庫連結到狀態目錄。其原因將在步驟2.1中變得清晰。
成功連結後,請注意 RedGate.ssc 檔案已新增到Git 倉庫 中的“ state ”目錄中。然後轉到Redgate SQL Source Control中的“ Commit ”選項卡,您將看到所有資料庫物件的列表,準備提交給原始碼管理。確保選中所有物件,鍵入提交訊息並單擊 commit :
當SQL Source Control表示所有更改都已提交時,請再次檢視您的git倉庫。您應該看到所有資料庫物件都編寫到各種目錄中。
由於Git是一個分散式原始碼控制系統,因此您只需將這些更改提交到本地倉庫。您尚未將這些檔案推送到Azure DevOps中託管的遠端倉庫。為此,請再次開啟PowerShell終端,導航到git repo的根目錄並執行命令: git push。
您可能會在SQL原始碼管理提交選項卡中看到“ 推送 ”按鈕,但它可能無法正常工作。這是Azure DevOps中託管的Redgate SQL Source Control和Git repos的已知問題。雖然有點令人沮喪,但開啟PowerShell終端並輸入“git push”並不是很麻煩,而且SQL Toolbelt中的其他功能可以彌補它。也就是說,如果破碎的“推送”按鈕讓你煩惱,你可以在這裡新增你的投票。
將原始碼推送到Azure DevOps之後,您應該能夠在Azure DevOps網站的“ 程式碼 ”選項卡下看到它:
步驟2.1:使用SCA和PowerShell編寫資料庫構建指令碼(可選步驟)
我們現在在原始碼控制中有我們的資料庫,所以下一步是設定一個構建過程來檢查我們的原始碼是否“編譯”。透過這個,我的意思是它是可部署的。例如,如果原始檔中存在一些非法的T-SQL語法,'或者如果某些檢視缺少依賴項,可能是因為我重構了一些表,但忘記更新我的檢視,那麼SQL Server將無法執行我的原始碼,我的資料庫構建將失敗。
此步驟是可選的,或者至少使用PowerShell在本地執行它是可選的。另一種方法是“跳過此步驟直接跳到步驟3,開始在Azure DevOps上配置資料庫構建。但是,我喜歡先在本地執行我的構建。它幫助我瞭解幕後發生的事情。它還幫助我瞭解我的第一個構建是否由於我的原始碼或我的Azure DevOps配置而失敗。
在原始碼管理的根目錄中 , 在“ state ”目錄旁邊建立一個名為“ build ” 的新目錄。這解釋了為什麼我沒有在步驟2中將我的資料庫連結到我的Git倉庫的根目錄。將其他相關檔案放在原始碼管理中是有用的,但是你不想將它們放在你的Redgate資料夾中。
使用localdb驗證構建
在構建目錄中建立一個名為“
build.ps1
” 的新檔案,並將以下PowerShell程式碼複製到其中。您可能希望更改引數的預設值
$packageID
以反映資料庫的名稱。現在,您應該保留其他引數。我將很快解釋
$packageVersion,$packagePath
和
$testPath
引數,我將在進一步擴充套件下解釋其他。
PARAM
(
[ string ] $ packageVersion = '0.1' ,
[ string ] $ packageID = 'StackOverflow' ,
[ string ] $ packagePath = 'C:\ packages' ,
[ string ] $ testPath = 'C:\ testResults' ,
[ string ] $ targetServerInstance = 'TARGETSERVERINSTANCE' ,
[ string ] $ targetDatabase = 'TARGETDATABASE'
)
$ errorActionPreference = “停止”
匯入模組 SqlChangeAutomation - ErrorAction silentlycontinue - ErrorVariable + ImportErrors
“*****引數*****
packageVersion 是 $ packageVersion
packageID 是 $ packageID
packagePath 是 $ packagePath
testPath 是 $ testPath
* * * * * * * * * * * * * * * * * * * * * * “|寫入輸出
#在父目錄中搜尋狀態資料夾
$ myDir = Split-Path - Parent $ MyInvocation 。我的命令。路徑
$ scriptsFolder = Join-Path - Path $ myDir - ChildPath '.. \ state'
$ scriptsFolder
如果 (-not (測試的路徑 - PathType 集裝箱 $ scriptsFolder ))
{
寫錯誤 “ 無法找到$ scriptsFolder ”
}
#Using Redgate SCA驗證狀態目錄中的程式碼
嘗試
{
$ validatedScriptsFolder = Invoke-DatabaseBuild $ scriptsFolder #-SQLCompareOptions'NoTransactions'
}
趕上 #
{
$ _ 。例外。資訊
“ $($資料庫。名稱; )無法驗證,因為$($ _ 。異常。訊息)” | Foreach {
寫錯誤 $ _
}
}
<#
#匯出NuGet包
$ databasePackage = New-DatabaseBuildArtifact $ validatedScriptsFolder -PackageId $ packageID -PackageVersion $ packageVersion
Export-DatabaseBuildArtifact $ databasePackage -Path $ packagePath
#執行測試
$ testResultsFile =“$ testPath \ $ packageID.junit。$ packageVersion.xml”
$ results = Invoke-DatabaseTests $ databasePackage
Export-DatabaseTestResults $ results -OutputFile $ testResultsFile
#同步測試資料庫
$ targetDB = New-DatabaseConnection -ServerInstance $ targetServerInstance -Database $ targetDatabase
Test-DatabaseConnection $ targetDB
Sync-DatabaseSchema -Source $ databasePackage -Target $ targetDB
#>
此PowerShell程式碼使用SQL Change Automation在其中建立新資料庫
localDB
並將所有原始碼部署到該資料庫。一旦部署了資料庫,SQL Change Automation就會立即將其刪除,因為它已經達到了目的。如果您每週執行10次構建一週,則不希望有50個測試資料庫。
您應該能夠從PowerShell執行指令碼,如果您願意,可以覆蓋預設引數。
CD 的 根目錄 中 的 源 控制\ 構建
。\ build 。ps1 - packageVersion'0.1 ' - packageID'MyDatabase '
這是完整的命令視窗,來自我的例子:
如果您的構建指令碼有效,那太好了!如果沒有,你可能會發現一些破碎的程式碼,也很棒!通常,這些是程式碼損壞,缺少依賴性,
localDB
未安裝或SQL Server憑據不正確的結果。PowerShell輸出是你的朋友。
使用臨時資料庫驗證構建
您可能會遇到無法部署資料庫的情況
localDB
,例如,它缺少對某些其他資料庫的依賴關係,或者使用
localDB
不支援的SQL Server功能。例如,
AdventureWorks
使用不會部署到的全文搜尋
localDB
。相反,您可以在“temproary”SQL Serve例項上部署到資料庫,該例項設定了資料庫所需的所有功能,依賴項,檔案組等。(請參閱Invoke-DatabaseBuild cmdlet文件中的示例3和4。)
您可以下載一個PowerShell構建指令碼(DBBuildTempServer.ps1),以稍微不同的樣式編寫,以展示可能的方法,以瞭解它是如何工作的。
您應該能夠從PowerShell執行指令碼,如果您願意,可以覆蓋預設引數。
CD 的 根目錄 中 的 源 控制\ 構建
。\ build 。ps1 - packageVersion'0.1 ' - packageID'MyDatabase ' - TempServer'MyServerInstance ' - User_id '' - 密碼 ''
如果您沒有可用於此過程的SQL Server例項,只需
-TemporaryDatabaseServer $TempconnectionString
從SCA
Invoke-DatabaseBuild
命令中刪除它,它將使用
localDB
,如前所述。Phil Factor的文章還提供了許多有關使用PowerShell和SCA的額外資訊。
建立NuGet包
在這個階段,我們所做的就是驗證構建; 換句話說,證明了資料庫將成功構建。完成後,我們可以開始探索其他SCA cmdlet,它們將從經過驗證的構建生成並匯出資料庫構建工件,在其上執行我們的測試套件,然後部署測試的更改,以使目標資料庫與經過驗證和測試的同步資源。
我將在稍後的“ 擴充套件”部分中介紹測試和同步cmdlet ,但是現在您可能希望生成一個NuGet包。NuGet包可以用作構建工件,代表了基於包的部署和持續交付的重要里程碑。您只需在構建指令碼中取消註釋幾行程式碼即可生成NuGet包。
只需在底部註釋塊中的#Export NuGet包下立即取消註釋兩行(例如,將<#幾行移動到下面),並確保預設值為
$packagePath
不在git倉庫中的現有目錄。如果你把它留空,它將在你的git repo的build目錄中建立一個NuGet包,我不推薦。
現在,當您執行成功的構建時,將建立包含原始碼的NuGet包。請注意,如果您嘗試建立兩個具有相同
$packageID
和
$packageVersion
相同
$packagePath
的包,則構建將失敗,因此您需要覆蓋構建號或每次重新執行構建時刪除舊包。
提交對原始碼管理的更改並將其推送到伺服器。
> git add build。PS1
> git commit - m “新增構建指令碼”
> git 推
第3步:使用Azure DevOps自動構建
您現在擁有原始碼管理中的資料庫程式碼,並將其推送到Azure DevOps。如果您按照步驟2.1中的說明進行操作,那麼您還可以在原始碼管理中使用PowerShell指令碼來構建資料庫,並且您知道原始碼是“編譯”的。現在,我們希望每次將新更改推送到原始碼控制時,Azure DevOps都會構建資料庫,以驗證是否可以部署更改並捕獲任何錯誤。
我們將使用Redgate Azure DevOps擴充套件來自動化資料庫構建,因為這不需要您遵循步驟2.1。如果您確實按照步驟2.1而不是使用Redgate外掛,則可能更喜歡使用執行build.ps1檔案的原始PowerShell任務來執行構建指令碼,並根據需要覆蓋預設引數。如果採用該方法,您可能會發現Azure DevOps預定義變數的索引很有用,您可能希望使用$(Build.BuildNumber)或$(Build.BuildID)來建立具有順序版本號的包。
您的自動構建將由“構建代理”執行。如果您已經
localDB
可以單獨構建資料庫,則應該能夠立即使用託管構建代理。否則,您需要在託管的伺服器上配置本地代理,該伺服器可以訪問合適的目標SQL Server例項以執行構建。
在Azure DevOps中,將滑鼠懸停在“ 管道” 選項卡上,然後從下拉選單中選擇“ 構建 ”。
點選 New Pipeline 按鈕,確保選擇了正確的源控制儲存庫和主分支。然後為模板選擇“ 空作業 ”。
將為您建立一個新的管道,其預設名稱(在我的情況下為 StackOverflow-CI )和預設的代理佇列(在我的情況下, 託管VS2017 ,這是Azure DevOps的預設名稱。管道包含一個名為 AgentJob1 的預設作業,雖然如果你選擇它,你可以重新命名它。讓我們稱之為 Build Stack Overflow Database 。
我們可以將 任務 新增到將執行MSBuild或執行PowerShell指令碼等的 代理作業 ,以編譯和測試我們的程式碼。為此,請單擊代理作業旁邊的 + 按鈕。
Redgate SQL Change Automation Azure DevOps擴充套件預設不可用,但如果您在 新增任務 下的 Marketplace 選項卡中搜尋“Redgate”,您將找到它。按照說明新增 SQL Change Automation:Build 擴充套件。
安裝完成後,找到返回構建過程的方法。您可能需要再次點選上面的第2-5點,因為您的新定義可能尚未儲存。這一次,如果您搜尋“Redgate”,您會發現該擴充套件程式無需再次透過Marketplace即可使用,您只需單擊“ 新增”即可 。
將在 Build StackOverflow資料庫 下 建立 構建 任務 ,並警告某些設定需要注意。單擊此構建任務,然後在“ 操作” 下,選擇“ 構建SQL原始碼管理”專案 。然後,在 Database資料夾下 選擇“ Database scripts資料夾是VCS根目錄的子資料夾 ”,在 Subfolder Path下 使用嚮導選擇由SQL Source Control維護的 狀態 目錄(不要選擇Git repo的根目錄) ,如果您按照步驟2.1,還將包含您的構建指令碼!)。
在 Output NuGet Package ID 下,為您的構建工件寫一個名稱。通常,這將是您的資料庫的名稱。
單擊“ 儲存並排隊” 以手動觸發構建。預設設定應該沒問題。您應該看到一個黃色通知,表明構建已排隊。如果單擊該號碼,則會轉到實時構建日誌。
將為您分配託管代理。然後,它將下載SQL Change Automation並
localDB
在雲中自行構建原始碼並報告結果。
請注意,如果您的資料庫不構建在Azure中託管構建代理上的本地資料庫的預設安裝上,則構建將失敗。如果您的資料庫不能構建
localDB
,則需要提供一個單獨的SQL Server例項來執行構建。然後,在
Build StackOverflow Database
構建任務中,將
Temporary伺服器型別
從
SQL LocalDB(推薦)
更改為
SQL Server
,並向伺服器例項提供連線詳細資訊。如果要在本地託管此伺服器例項,則可能需要安裝可以訪問本地伺服器的本地構建代理來執行構建。
構建可能需要幾分鐘。就我而言,使用Stack Overflow和託管構建代理程式,花了大約兩分半鐘。使用更大,更復雜的模式,您可能需要更長時間。
如果構建失敗,請查詢日誌中的錯誤並進行故障排除。常見問題包括缺少依賴項,不正確的憑據,對資料庫的許可權不足,使用不受支援的功能
localDB
以及損壞的T-SQL程式碼。保持堵塞,直到你的構建變綠。如果您跳過步驟2.1並且在構建時遇到問題,請考慮返回並嘗試步驟2.1,因為這是解決原始碼問題的一種更簡單的方法,可以幫助您確定問題是否與原始碼或Azure DevOps配置。
一旦構建為綠色,您需要設定構建觸發器以確保每次將新程式碼推送到Azure DevOps伺服器時構建都會執行。從Azure DevOps中的任何頁面,將滑鼠懸停在頂部的“ 管道” 選項卡上,然後選擇“ 生成” 以導航回您的構建定義。選擇 Build Definition ,然後選擇 Edit 按鈕。
選擇 觸發器 並確保選中 啟用持續整合 ,您就完成了。
如果您已經做到這一點,並且將新程式碼推送到Azure DevOps,那麼它將自動啟動構建並驗證您的程式碼,並且您可以繼續持續整合並快速獲得有關錯誤的反饋。
進一步擴充套件
自動化資料庫構建只是第一步。所有這些都將測試您的原始碼是否可部署。它不會測試您的儲存過程是否按設計執行。它不會自動更新整合資料庫,因此它始終與源控制元件保持同步。它不會將您的程式碼部署到測試,登臺和生產伺服器。
首先,最重要的是,您需要開始編寫將在每次構建時自動執行的資料庫的測試。檢視tSQLt和Redgate SQL Test。
如果使用寫在PowerShell指令碼步驟2.1,並且已安裝資料庫的tSQLt框架,並致力於其原始碼管理,您可以透過下取消註釋行你構建的一部分執行測試 #執行測試 。如果您還沒有將tSQLt框架提交給原始碼控制,那麼這將失敗。您還應確保將 $ testPath 預設引數設定為git repo之外的現有目錄。與包一樣,每次執行構建時都需要覆蓋 $ packageVersion 。
如果您希望構建將更改部署到整合資料庫,請取消註釋#Sync a test database 下的行並適當地設定 $ targetServerInstance 和$ targetDatabase 的預設值。
如果您在Azure DevOps中使用Redgate SQL Change Automation擴充套件,則需要:
-
新增 SQL Change Automation:Build 任務, 操作 設定為“使用tSQLt測試從SQL Source Control專案測試構建工件”。同樣,除非您已經在原始碼管理中使用了tSQLt框架和測試,否則這將無法工作。
-
新增 SQL Change Automation:Build 任務, 操作 設定為“將構建工件從SQL原始碼管理專案同步到目標資料庫”。
-
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2284748/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Azure Terraform(八)利用Azure DevOps 實現Infra資源和.NET CORE Web 應用程式的持續整合、持續部署ORMdevWeb
- Azure DevOps(一)基於 Net6.0 的 WPF 程式如何進行持續整合、持續編譯dev編譯
- 持續整合、持續交付與持續部署
- 持續整合持續部署持續交付_持續整合與持續部署之間的真正區別
- Azure DevOps+Docker+Asp.NET Core 實現CI/CD(二.建立CI持續整合管道)devDockerASP.NET
- CircleCI 與持續整合
- 雲原生下的DevOps與持續交付dev
- 對持續整合、 持續交付、持續部署和持續釋出的介紹
- 這麼強?!Erda MySQL Migrator:持續整合的資料庫版本控制MySql資料庫
- 2019 DevOps 必備面試題——持續整合篇dev面試題
- 雲資料庫SQL Azure的基本限制TX資料庫SQL
- 持續整合、持續部署、持續交付、持續釋出
- Azure Data Factory(三)整合 Azure Devops 實現CI/CDdev
- 微服務容器部署與持續整合微服務
- 資料分析面試|SQL真題持續更新面試SQL
- 持續整合 2.0
- Jenkins持續整合Jenkins
- 持續整合(二)
- 你真的懂持續整合、持續交付、持續部署嗎?!
- SpringBoot+Docker+Git+Jenkins實現簡易的持續整合和持續部署Spring BootDockerGitJenkins
- Azure DevOps(二)Azure Pipeline 整合 SonarQube 維護程式碼質量和安全性dev
- 淺談持續整合(CI)、持續交付(CD)、持續部署(CD)
- 如何將Azure SQL 資料庫還原到本地資料庫例項中SQL資料庫
- openGauss持續聚焦資料庫根技術資料庫
- 淺談持續整合的理解以及實現持續整合,需要做什麼?
- SAP開源的持續整合-持續交付的解決方案
- 3分鐘瞭解清楚持續整合、持續交付、持續部署
- Jenkins持續整合配置Jenkins
- 小程式的持續整合方案
- 使用ArgoCD和Liquibase在有資料庫的Kubernetes中實現持續交付 - PiotrGoUI資料庫
- 持續整合、持續交付和持續部署有什麼區別?0基礎學習linux技能Linux
- 【Azure DevOps系列】什麼是Azure DevOpsdev
- .net持續整合sonarqube篇之 sonarqube與jenkins整合(命令模式)Jenkins模式
- Azure DevOps (二) 實現Git倉庫和釘釘的聯動devGit
- PowerDesigner下PDM自動化資料庫物理設計版本持續整合解決方案資料庫
- 國產資料庫考試資料彙總(持續更新)資料庫
- Oracle資料庫 11.2.0.4 EMON程式持續消耗CPUOracle資料庫
- gitlab和jenkins做持續整合構建教程GitlabJenkins