Deploy Database Project with MSBuild with CommandLine Parameters fails - deployment

I am failing to deploy Database project using command line parameters with msbuild. I would like to:
use publish xml profile
define connection string as command line parameter
but this seems to be impossible for no reason. There is for sure some simple catch I am missing. I tried following variants:
msbuild /t:SqlDeploy /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj
deploys database
values in test.pubhlish.xml are ignored
msbuild /t:Build /t:Deploy /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj
deploys database
values in test.pubhlish.xml are ignored
msbuild /t:Build /t:Publish /p:SqlPublishProfilePath="test.publish.xml" /p:TargetConnectionString="Data Source=..." Database.sqlproj
fails with error: Deploy Error : The connection string is not valid
values in test.publish.xml file are used (when test.publish.xml contains TargetConnectionString, database is deployed correctly)
In all 3 cases I am using exactly the same ConnectionString, so it is not a typo or error in the connection string. I need to use the 3rd variant, but this just fails.. What am I missing?

Related

How to deploy the Sql files to Dedicated Server with Azure Devops Pipeline CI/CD

I am working on Azure DevOps CI CD Pipelines. The project's Backend is Dotnet Core, Frontend is Angular 8 and for Database, we used Entity Framework code-first approach. I was able to add Front and back end in pipelines. Now I am stuck with database deployment. since I was also unable to find any dedicated article.
The project is consists of Multi Context and Multi-Project. Reference folder structure
At local we usually run this command to generate migration and it works fine.
Add-Migration -Context ABCCompanyContext AddCompanyTable
Now, in Pipeline i have added the following command which I get from stackoverflow it self. but it didn't work. But from the error. it seems like I am really close
Pipeline Command
dotnet tool install --global dotnet-ef dotnet ef migrations script -i
-o $(Build.ArtifactStagingDirectory)\Migrations\migrate.sql --project **/ABC.Company.Data.csproj --startup-project **/ABC.Company.Api.csproj -i -o $(Build.ArtifactStagingDirectory)\Migrations\migrate.sql
Error Log
2020-12-24T06:49:27.0265041Z ========================== Starting
Command Output ===========================
2020-12-24T06:49:27.0688206Z ##[command]"C:\windows\system32\cmd.exe"
/D /E:ON /V:OFF /S /C "CALL
"D:\a_temp\f3a33029-4f61-404f-9b64-c73c5296123a.cmd""
2020-12-24T06:49:32.9358440Z You can invoke the tool using the
following command: dotnet-ef 2020-12-24T06:49:32.9359182Z Tool
'dotnet-ef' (version '5.0.1') was successfully installed.
2020-12-24T06:49:38.4701578Z System.IO.IOException: The filename,
directory name, or volume label syntax is incorrect. :
'D:\a\1\s*\obj' 2020-12-24T06:49:38.4702878Z at
System.IO.FileSystem.CreateDirectory(String fullPath, Byte[]
securityDescriptor) 2020-12-24T06:49:38.4703503Z at
System.IO.Directory.CreateDirectory(String path)
2020-12-24T06:49:38.4704199Z at
Microsoft.EntityFrameworkCore.Tools.Project.FromFile(String file,
String buildExtensionsDir, String framework, String configuration,
String runtime) 2020-12-24T06:49:38.4705029Z at
Microsoft.EntityFrameworkCore.Tools.RootCommand.Execute(String[] _)
2020-12-24T06:49:38.4705729Z at
Microsoft.EntityFrameworkCore.Tools.Commands.CommandBase.<>c__DisplayClass0_0.b__0(String[]
args) 2020-12-24T06:49:38.4706399Z at
Microsoft.DotNet.Cli.CommandLine.CommandLineApplication.Execute(String[]
args) 2020-12-24T06:49:38.4707003Z at
Microsoft.EntityFrameworkCore.Tools.Program.Main(String[] args)
2020-12-24T06:49:38.4707626Z The filename, directory name, or volume
label syntax is incorrect. : 'D:\a\1\s*\obj'
2020-12-24T06:49:38.6646502Z ##[error]Cmd.exe exited with code '1'.
2020-12-24T06:49:38.7627325Z ##[section]Finishing: Build EfCore
Migrations
The error message,
System.IO.IOException: The filename, directory name, or volume label syntax is incorrect. : 'D:\a\1\s\*\obj'
The path string contains the character '*'. Normally this character is not available in file name and folder name.
As the introduction from the docs about .NET Core CLI, the values of the options '--project' and '--startup-project' are the relative paths to the project folders.
According to my test, in the 'dotnet ef' command, it seems does not support wildcard patterns.
When I use wildcard patterns to set the path values, it always return the same error message.
System.IO.IOException: The filename, directory name, or volume label syntax is incorrect. : 'D:\a\1\s\**\obj'
However, when I directly provide the complete relative paths instead of using wildcard patterns, the error disappears.
So, I recommend you directly use the complete relative paths to the project folders.

MSDeploy reporting "could not find file" when using setParamFile

I'm using MSDeploy as part of a custom task in TFS2017 (Update 1) but I can't get the setParamFile option to work. It throws one of two errors. If I specify no path, it says "could not find file" (see trace below). If I specify the path to the file on the build machine, it says invalid path.
I'm sure it's something incredibly simply but it's got me beat and Google is, for once, not being my friend! Any help is greatly appreciated.
I have provided the log unaltered as all this is only on internal servers. Without the setParamFile parameter, it deploys fine without updating the variable connection strings I'm trying to update, obviously.
2017-04-15T22:41:13.5065833Z Executing the powershell script: D:\BuildAgent\tasks\MSDeployPackageMultiSync\1.1.16\MSDeployPackageSync.ps1
2017-04-15T22:41:13.6472111Z packageFile= Find-Files -SearchPattern D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.zip
2017-04-15T22:41:13.6472111Z packageFile= D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.zip
2017-04-15T22:41:13.6784674Z DCA_API.SetParameters.xml
2017-04-15T22:41:13.7097114Z Package= D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.zip
2017-04-15T22:41:13.7097114Z ParamFile= -setParamFile:'DCA_API.SetParameters.xml'
2017-04-15T22:41:13.7097114Z DestinationProvider= auto
2017-04-15T22:41:13.7097114Z DestinationComputer= prerelweb3,prerelweb4
2017-04-15T22:41:13.7097114Z Username=
2017-04-15T22:41:13.7097114Z AdditionalArguments=
2017-04-15T22:41:13.7253453Z Deploying package to prerelweb3,prerelweb4
2017-04-15T22:41:13.7253453Z Deploying to prerelweb3
2017-04-15T22:41:13.7253453Z "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:package='D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.zip' -setParamFile:'DCA_API.SetParameters.xml' -dest:auto,computerName='prerelweb3',userName='',password='',authType='ntlm',includeAcls='False' -setParam:name='IIS Web Application Name',value='WebServices (Secure)\FormsAdmin' -setParam:kind=DestinationVirtualDirectory,scope='WebServices (Secure)\\FormsAdmin',value='e:\cabi_sites\WebServices_Secure\FormsAdmin' -allowUntrusted
**2017-04-15T22:41:14.1315861Z ##[error]System.Management.Automation.RemoteException: Error: Could not find file ''DCA_API.SetParameters.xml''.**
2017-04-15T22:41:14.1315861Z ##[error]System.Management.Automation.RemoteException: Error count: 1.
2017-04-15T22:41:14.1315861Z Deployment to prerelweb3 complete
2017-04-15T22:41:14.1315861Z Deploying to prerelweb4
2017-04-15T22:41:14.1315861Z "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:package='D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.zip' -setParamFile:'DCA_API.SetParameters.xml' -dest:auto,computerName='prerelweb4',userName='',password='',authType='ntlm',includeAcls='False' -setParam:name='IIS Web Application Name',value='WebServices (Secure)\FormsAdmin' -setParam:kind=DestinationVirtualDirectory,scope='WebServices (Secure)\\FormsAdmin',value='e:\cabi_sites\WebServices_Secure\FormsAdmin' -allowUntrusted
**2017-04-15T22:41:14.4909648Z ##[error]System.Management.Automation.RemoteException: Error: Could not find file ''DCA_API.SetParameters.xml''.**
2017-04-15T22:41:14.4909648Z ##[error]System.Management.Automation.RemoteException: Error count: 1.
2017-04-15T22:41:14.4909648Z Deployment to prerelweb4 complete
I assume that you are using this task: MSDeployAllTheThings. According to the logs, you are using it from Release. So you need to make sure that the "DCA_API.SetParameters.xml" file is published to artifact drop during the build and is also downloaded correctly during release. And then, you need to enter the absolute path in the Additional Arguments so that the task can find the file. For your scenario, if the "DCA_API.SetParameters.xml" file is placed in the same folder with "DCA_API.zip" file, you need to use this:
-setParamFile:"D:\BuildAgent\_work\194fdc7b9\Data Collection App - Release\drop\_PublishedWebsites\Cabi.FormsAdmin.Api_Package\DCA_API.SetParameters.xml"
I tried with absolute path at my side and didn't see any issue with it.

msdeploy via powershell and psake fails

So I'm trying to use powershell and psake for my build and deployment. I've tried without any success to call the following psake task.
Exec { msdeploy.exe "-verb:sync"
"-source:package="D:\path-to-package\zip-file-name.zip"
"-dest:auto,computername=http://my-server-name-here:8090/MsDeployAgentService2/" -setparam:Name="IIS Web Application Name,Value=iis-web-app-name-here" "-allowUntrusted" }
So in an effort to get things moving I removed the offending setparam:Name="IIS Web Application Name,Value=iis-web-app-name-here". It worked but took the IIS Web Application Name parameter from the ..SetParameters.xml as expected.
<setParameter name="IIS Web Application Name" value="Default Web Site/project.name_deploy" />
There's clearly something wrong with the syntax of setparam:Name="IIS Web Application Name,Value=iis-web-app-name-here" but I've tried a dozen (or more) variations including
-setparam:"IIS Web Application Name=iis-web-app-name-here" > omitting the name,value
-setparam:"IIS` Web` Application` Name=iis-web-app-name-here" > using back ticks
I really can't work out what I'm doing wrong and may have to resort back to using an msbuild file to get things moving.
The error I receive is : > all arguments must begin with -
I believe you need to quote the parameters as follows:
setparam:Name="IIS Web Application Name",Value="iis-web-app-name-here"
Note the additional quotes before the comma and after the equals sign following Value.

Why Msbuild task failed to deploy database, but Exec work fine

I'm trying to deploy database project ( dbproj format, not new SSDT sqlproj ) inside automated build server processing. I found the following:
When I'm calling deploy with Exec task in my Msbuild script - everything working fine:
<Exec Command="$(MSBuildPath)\MSBuild.exe $(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj
/t:Deploy
/p:OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\
/p:TargetDatabase=$(DeployDatabaseName)
/p:TargetConnectionString=$(DeployDatabaseConnectionString)" />
But when I try to repeat this with Msbuild task - it behaves differently:
<MSBuild Projects="$(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj"
Targets="Deploy"
Properties="Configuration=$(BuildConfiguration);
TargetDatabase=$(DeployDatabaseName);
TargetConnectionString="$(DeployDatabaseConnectionString)";
OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\;
" />
Msbuild task broke on semicolons in DeployDatabaseConnectionString:
<DeployDatabaseConnectionString>Data Source=$(DeployDatabaseServer);Integrated Security=True;Pooling=False</DeployDatabaseConnectionString>
It will report something like this:
The name "Integrated Security" contains an invalid character " ".
But if I replace semicolons with percent encoding value - %3B - it will broke inside SqlDeployTask:
error MSB4018: The "SqlDeployTask" task failed unexpectedly.
What is the proper way to pass TargetConnectionString to Deploy target of SqlProject ?
PS: I Could live with exec task fine, but make a call to msbuild.exe inside msbuild script just hurts my inner perfectionist man.
I found the proper way - new Msbuild allow to define AdditionalProperties metadata on item. So with this feature everything work fine and have no problems with escaping\encoding
<ItemGroup>
<DbProjectToBuild Include="$(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj">
<AdditionalProperties>Configuration=$(BuildConfiguration)</AdditionalProperties>
<AdditionalProperties>OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\</AdditionalProperties>
<AdditionalProperties>TargetDatabase=$(DeployDatabaseName)</AdditionalProperties>
<AdditionalProperties>TargetConnectionString="Data Source=$(DeployDatabaseServer);Integrated Security=True;Pooling=False"</AdditionalProperties>
</DbProjectToBuild>
</ItemGroup>
<MSBuild Projects="%(DbProjectToBuild.Identity)" Targets="Build;Deploy" />

Breaking MsBuild package & deploy into separate MsBuild and MsDeploy commands

I'm having a few problems breaking out an MsBuild package+deploy command into two separate commands. (I need to do this to pass additional parameters to MsDeploy).
The command that works fine looks like this:
msbuild "src\Solution.sln"
/P:Configuration=Deploy-Staging
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=https://192.168.0.1:8172/MsDeploy.axd
/P:DeployIISAppPath=staging.website.com
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WmSvc
/P:CreatePackageOnPublish=True
/P:UserName=staging-deploy
/P:Password=xyz
The separated packaging command looks like this:
msbuild "src\Solution.sln"
/P:Configuration=Deploy-Staging
/P:DeployOnBuild=True
/P:DeployTarget=Package
/P:_PackageTempDir=C:\temp\web
which works fine. But then the MsDeploy portion:
msdeploy
-verb:sync
-allowUntrusted
-usechecksum
-source:manifest=
'src\WebProject\obj\Deploy-Staging\Package\WebProject.SourceManifest.xml'
-dest:auto,ComputerName=
'https://192.168.0.1:8172/MsDeploy.axd?site=staging.website.com',
username='staging-deploy',password='xyz',authType='basic',includeAcls='false'
-enableRule:DoNotDeleteRule
fails, with the following error in WmSvc.log
wmsvc.exe Error: 0 : Attempted to perform an unauthorized operation.
setAcl/C:\temp\web (Read)
ProcessId=15784
ThreadId=31
DateTime=2011-03-30T14:57:02.4867689Z
Timestamp=3802908721815
wmsvc.exe Error: 0 : Not authorized.
Details: No rule was found that could authorize user 'staging-deploy',
provider 'setAcl', operation 'Read', path 'C:\temp\web'.
(and several more Read/Write operations)
Something is clearly going wrong with the paths it's trying to access (as it works fine with the other method) - I'm not sure it's even trying to use the iisApp targeting correctly, and at the moment I don't think the correct web.config's will be deployed either.
I've got this fixed now - I needed a different command to the one the automatically generated .cmd file was using, but comparing the two allowed me to fix it up (thanks #Vishal R. Joshi)
The differences I needed was:
basic authentication
allow untrusted certificates
?site=staging.webserver on the end of the MsBuild.axd path, as with my original command
override the IIS Web App name that is set in the params file
enable the do not delete rule
The winning command is as follows:
msdeploy
-verb:sync
-allowUntrusted
-source:package='src\WebProject\obj\Deploy-Staging\Package\WebProject.zip'
-dest:auto,ComputerName=
'https://192.168.0.1:8172/MsDeploy.axd?site=staging.website.com',
username='staging-deploy',password='xyz',authType='basic',includeAcls='false'
setParamFile:
"src\WebProject\obj\Deploy-Staging\Package\WebProject.SetParameters.xml"
-setParam:name='IIS Web Application Name',value='staging.website.com'
-enableRule:DoNotDeleteRule
-disableLink:AppPoolExtension -disableLink:ContentExtension
-disableLink:CertificateExtension
Hope this helps someone!
Add a delegation rule on the server using inetmgr to allow staging-deploy to carry out set-Acl operations.
Inetmgr -> Click on server node -> Management Service Delegation (in Management) -> Click Add rule to the right -> Choose the template labelled "Set Permissions for Applications" -> Accept defaults and click OK.
This should let you deploy any package or manifest with setAcl as long as the user you are deploying as, has permissions to the site you are deploying to.
You are able to specify the -setParam:name='',value='' flag when calling the MyProject.deploy.cmd file that is created when you generate a Package from a web project. The cmd is a friendly wrapper around msdeploy.exe, so you have no need to specify all the rest of the defaults.
Here's the details: http://evolutionarydeveloper.blogspot.co.uk/2013/05/specifying-environment-variables-at.html