Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.42 KB | None | 0 0
  1. # Can edit this file if more servers are required.
  2. $ServerConfigFile = "./servers.json"
  3.  
  4.  
  5. Function Test-Checkout {
  6. param(
  7. [parameter(Mandatory=$true)]
  8. [string]$Branch
  9. )
  10. begin {
  11. }
  12. process {
  13. git checkout $Branch | Out-Null
  14.  
  15. if ($LASTEXITCODE -eq 1) {
  16. throw (Write-Warning "Unable to checkout $Branch. Review the output, resolve any issues and try again.")
  17. }
  18. }
  19. }
  20.  
  21. Function New-GitBranch {
  22. <#
  23. .SYNOPSIS
  24. Creates a new branch from a source branch, switches to it and pushes it to the remote.
  25. .DESCRIPTION
  26. Checks out the source branch and runs a 'git pull' to get the latest commits.
  27. Creates and switches to a branch named with the given parameters and/or their default values.
  28. .NOTES
  29. Assumes that there is a remote set-up on the git repository.
  30. The working directory should be clean before running this command. Commit, statsh or discard
  31. and changes that are outstanding before running this command.
  32. .PARAMETER Path
  33. The path to the local working directory where the sql-code repo resides. If not supplied
  34. assumed to be the current working directory.
  35. .PARAMETER SourceBranch
  36. The branch from which to create the new branch. Defaults to the 'develop' branch.
  37. .PARAMETER Prefix
  38. The prefix to use for the branch. If used, has to be one of: Release, Bugfix, Hotfix, Feature.
  39. .PARAMETER Name
  40. The name of the branch to create. Recommended format is <JIRA_CODE>-<some-descriptive-text-for-branch>.
  41. .EXAMPLE
  42. PS> New-GitBranch -SourceBranch develop -Prefix Bugfix -Name fix-divide-by-zero
  43.  
  44. Creates a new branch named Bugfix/fix-divide-by-zero, sourcing from an updated develop branch,
  45. pushing to the remote, automatically setting up tracking.
  46. #>
  47. [CmdletBinding()]
  48. Param(
  49. [ValidateScript( {Test-Path $_ -PathType "Container"})]
  50. [string]
  51. $Path = "$pwd",
  52.  
  53. [Parameter(mandatory = $true)]
  54. [ValidateSet("develop", "preprod", "master")]
  55. [string]$SourceBranch,
  56.  
  57. [Parameter(mandatory = $false)]
  58. [ValidateSet("release", "feature", "bugfix", "hotfix")]
  59. [string]$Prefix,
  60.  
  61. [Parameter(mandatory = $false)]
  62. [string]$Name = $(Get-Date -Format yyyyMMddHHmmss)
  63. )
  64. begin {
  65. $newBranchName = "$Prefix$(if ($Prefix) {"/"})$Name"
  66.  
  67. if ($Path -ne $pwd) {
  68. Set-Location $Path
  69. }
  70.  
  71. }
  72. process {
  73. try {
  74. #Get latest state of the source branch.
  75. Test-Checkout -Branch $SourceBranch
  76. git pull
  77.  
  78. #Create the new branch, switch to it and push to the remote.
  79. git checkout -b "$newBranchName"
  80. git push -u origin "$newBranchName"
  81.  
  82. $newBranchName
  83. }
  84. catch {
  85. Write-Error "$($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
  86. }
  87. }
  88. }
  89.  
  90. Function Compare-GitBranch {
  91. <#
  92. .SYNOPSIS
  93. Compares any two branches on the current git repository. Returns the files that are different
  94. between the Source and Target.
  95. .DESCRIPTION
  96. .NOTES
  97. Assumes that the branches exist on the remote and thus can be pulled.
  98. .PARAMETER SourceBranch
  99. The comparison branch from which the files will be returned. If not supplied, the current branch
  100. will be used.
  101. .PARAMETER TargetBranch
  102. The branch to compare the SourceBranch against. If not supplied, the 'master' branch will be used.
  103. .EXAMPLE
  104. #>
  105. [CmdletBinding()]
  106. Param(
  107. [Parameter(mandatory = $false)]
  108. [string]$SourceBranch = $(git rev-parse --abbrev-ref HEAD),
  109. [Parameter(mandatory = $false)]
  110. [string]$TargetBranch = "master"
  111. )
  112. process {
  113. try {
  114.  
  115. $startingBranch = $(git rev-parse --abbrev-ref HEAD) | Out-Null
  116.  
  117. #Get latest state of the target branch to compare against
  118. Test-Checkout -Branch $TargetBranch
  119. git pull
  120.  
  121. if ($startingBranch -ne $sourceBranch) {
  122. Test-Checkout -Branch $SourceBranch
  123. }
  124.  
  125. #Now we can compare the list of files that are different between this release and the remote/origin
  126. $filesChanged = git diff --name-status "$TargetBranch..."
  127.  
  128. #To trap the SQL objects we might want to deploy code for later
  129. $objectTypes = "StoredProcedure", "Table", "Trigger", "Function", "View"
  130.  
  131. #Build the diff files
  132. $filesChanged | ForEach-Object {
  133. #Files that were renamed have 3 parts in the string so need to parse a different way. Will sort later
  134. $schemaName = $null
  135. $objectName = $null
  136.  
  137. if ($_ -notlike "R*") {
  138.  
  139. $data = $_ -split "\s", 2
  140. $file = $data[1]
  141.  
  142. $name = Split-Path -Path "$file" -leaf
  143. $objType = $name.split(".")[-2]
  144.  
  145. #Some extra info for SQL objects
  146. if ($objectTypes.Contains($objType)) {
  147. $objectName = ($name.split(".")[-3])
  148. $schemaName = ($name.split(".")[-4])
  149. }
  150. else {
  151. $objType = $null
  152. }
  153.  
  154. New-Object psobject -Property @{
  155. Action = $data[0]
  156. FullName = $file
  157. Name = $name
  158. SchemaName = $schemaName
  159. ObjectName = $objectName
  160. ObjectType = $objType
  161. }
  162. }
  163. }
  164. write-host "done"
  165. }
  166. catch {
  167. Write-Error "$($_.Exception.Message) - LineNumber: $($_.InvocationInfo.ScriptLineNumber)"
  168. }
  169. finally {
  170. git checkout $startingBranch | Out-Null
  171. }
  172. }
  173. }
  174.  
  175. Function Publish-Code {
  176. <#
  177. .SYNOPSIS
  178. Will figure out the changes of a release, collect the sql files and then run the code against the chosen server.
  179. .DESCRIPTION
  180. .NOTES
  181. .PARAMETER TargetServer
  182. The server[s] you want to deploy the code to.
  183. .PARAMETER ReleaseBranch
  184. The branch to compare against master. If no branch supplied, the current branch will be used.
  185. .EXAMPLE
  186. #>
  187. [CmdletBinding()]
  188. Param(
  189. [Parameter(mandatory = $true)]
  190. [ValidateScript({
  191. # build the servers list from config file and check the values supplied by the user exist.
  192. $global:servers = Get-Content -Raw -Path "$serverConfigFile" | ConvertFrom-Json
  193. $_ -in ($servers | Get-Member -MemberType NoteProperty).Name})
  194. ]
  195. [string[]]$TargetServer,
  196.  
  197. [Parameter(mandatory = $false)]
  198. [string]$ReleaseBranch = $(git rev-parse --abbrev-ref HEAD)
  199. )
  200. begin {
  201. $ErrorActionPreference = "stop"
  202. $currentBranch = git rev-parse --abbrev-ref HEAD
  203.  
  204. if ($ReleaseBranch -ne $currentBranch) {
  205. Test-Checkout -Branch $ReleaseBranch
  206. }
  207. }
  208. process {
  209. try {
  210.  
  211. $sortOrder = "Pre Release Scripts", "Schemas", "Tables", "Triggers", "Views", "Synonyms", "StoredProcedures", "Post Release Scripts"
  212.  
  213. $files = Compare-GitBranch |
  214. Select-Object Action, FullName, SchemaName, ObjectName, ObjectType |
  215. Where-Object { $_.Action -eq "A" -or $_.Action -eq "M" } |
  216. Sort-Object { $sortOrder.IndexOf($_.FullName.split("/")[-2])}
  217.  
  218. Write-Host "$($files.length) selected for deployment across $($TargetServer.Length) servers."
  219.  
  220. $TargetServer.foreach({
  221.  
  222. $serverInstanceKey = $_
  223. $serverInstance = $servers.$serverInstanceKey.server
  224. Write-Host "Deploying code to $serverInstanceKey" -ForegroundColor Cyan
  225.  
  226. $contextQuery = @"
  227. DECLARE @BinVar varbinary(128);
  228. SET @BinVar = CAST('$currentBranch' AS varbinary(128));
  229. SET CONTEXT_INFO @BinVar;
  230. "@
  231.  
  232. $files | ForEach-Object {
  233. $qualifedObjName = "$($_.Schema).$($_.ObjectName)"
  234.  
  235. Write-Host "Attempting to deploy $($_.FullName)" -ForegroundColor Cyan
  236.  
  237. $query = (Get-Content -path ($_.FullName)) | Out-String
  238. Write-Debug $query
  239. Invoke-Sqlcmd -query "$contextQuery$query" -ServerInstance $serverInstance `
  240. -QueryTimeout 600 -OutputSqlErrors $true -ErrorAction Continue
  241.  
  242. if ($?) {
  243. Write-host " DEPLOYED: $qualifedObjName" -ForeGroundColor green
  244. $deployStatus = "DEPLOYED"
  245. }
  246. else {
  247. $deployStatus = "FAILED"
  248. }
  249.  
  250. New-Object psobject -Property @{
  251. FullName = ($_.FullName)
  252. ServerInstance = $serverInstanceKey
  253. DeploymentStatus = $deployStatus
  254. }
  255. }
  256. })
  257. }
  258. catch {
  259. Write-Error "$($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
  260. }
  261. }
  262. end {
  263. }
  264. }
  265.  
  266. Export-ModuleMember -Function New-GitBranch
  267. Export-ModuleMember -Function Compare-GitBranch
  268. Export-ModuleMember -Function Publish-Code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement