I am using MS build to publish my ClickOnce app, in Visual Studio 2017 developer command line to a remote ftp site.
How do I initiate the FTP file upload that starts in Visual Studio after build? This is my command line, which builds the project:
msbuild /target:publish -property:Configuration=Release /p:PlatformTarget=x86 "%USERPROFILE%\VSProjects\IIC\IIC.UI.vbproj"
There are 2 problems with command line Click Once deployment: (1) Auto Incrementing option from the publish property page of a project is not honored from the command line, and (2) the subject of the question, starting the FTP upload to the remote site.
Solution (with Visual Studio 2017 Developer Command Prompt v15.7.3)
Download community ms build tasks from here: https://github.com/loresoft/msbuildtasks
Unload the project and open with notepad++ or your editor of choice and import the community ms build tasks. Follow the instructions on their github page.
Add file ProjectName.version.txt with just one line with the version information of your project. For example:
1.2.78.1341
The numbers correspond to {Major}.{Minor}.{Build}.{ApplicationRevision}
Add the following target to the bottom of the project, which uses the Version and FileUpdate community tasks:
<Target Name="beforePublishCmd">
<Message Text="revision before: 3.0.0.$(ApplicationRevision)"/>
<Version VersionFile="ProjectName.version.txt" BuildType="Automatic" Major="3" Minor="0" Build="0" RevisionType="Increment">
<Output TaskParameter="Major" PropertyName="Major" />
<Output TaskParameter="Minor" PropertyName="Minor" />
<Output TaskParameter="Build" PropertyName="Build" />
<Output TaskParameter="Revision" PropertyName="ApplicationRevision" />
</Version>
<Message Text="revision after: 3.0.0.$(ApplicationRevision)"/>
<FileUpdate Files="ProjectName.vbproj"
Regex="<ApplicationRevision>(\d+)"
ReplacementText="<ApplicationRevision>$(ApplicationRevision)" />
</Target>
Call the above target from the command line BEFORE calling the publish target, like so:
msbuild /target:beforePublishCmd -property:Configuration=Release /p:PlatformTarget=x86 "%USERPROFILE%\VSProjects\ProjectName.vbproj"
Add an "afterPublish" target, which uses the FtpUploadDirectoryContent community task. This target is automatically called after the publish target finishes.
<Target Name="afterPublish">
<PropertyGroup>
<CurrentDate>$([System.DateTime]::Now.ToString(yyyy MMM dd HH:mm:ss))</CurrentDate>
</PropertyGroup>
<FtpUploadDirectoryContent
ServerHost="projectname.org"
Username="*****"
Password="*****"
LocalDirectory=".\bin\Release\app.publish"
RemoteDirectory="/"
Recursive="true"
/>
<Exec Command="C:\Progra~1\TortoiseSVN\bin\svn commit ..\ --non-interactive --message "Release 3.0.0.$(Revision) on $(CurrentDate): $(commitMessage)""/>
</Target>
Finally, call the publish target from the command line:
msbuild /target:publish -property:Configuration=Release /p:PlatformTarget=x86 "%USERPROFILE%\VSProjects\ProjectName.vbproj"
MSBuild ClickOnce app: Upload files after build
You can add a copy task into your project file to upload files after build:
To accomplish this, unload your project. Then at the very end of the </project>, just before the end-tag, place below scripts:
<ItemGroup>
<UploadFiles Include="ThePathOfYourUploadFiles\*.*"/>
</ItemGroup>
<Target Name="AfterBuild">
<Copy
SourceFiles="#(UploadFiles)"
DestinationFolder="PathWhereYouWantTouploadYourUploadFiles"
/>
</Target>
With this target, Visual Studio/MSBuild will upload the files after build.
Hope this helps.
Related
I am using following code in 2 our of 3 projects from the solution default target is set to PublishMe
<Target Name="PublishMe" DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="'$(PublishDestination)'==''" Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))" Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(PublishFiles)" DestinationFiles="#(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="True" />
</Target>
If I run msbuild it builds and publishes just as expected, the problem is that I can't build it from VS anymore, I am having error of missing projectname.dll
Is there way I can change default build target if it is msbuild doing build?
I tried to /t:ProjectName:target;ProjectName2:target, but it isn't working with custom targets for some reason.
Is there way I can specify param from msbuild console to run PublishMe target and if not present run simple build?
You can usefollowing command
msbuild projectname /t:targetname.
Also please check the below link for more info
Building a solution file using msbuild
I'm trying to make Visual Studio do my entire build, currently I've got my extra build steps written in nant. But it's not ideal having to run ant separately.
I'm trying to run a jar file named plovr as part of my node application, although at the moment publish keeps failing on the line I've added to my build with exit code 1. This is the code I'm trying at the end of my build file within the <Project></Projet> tags.
<Target Name="Build">
<Exec Command="java -jar $(Plovr) build $(PlovrConfig)" />
</Target>
I've got these properties setup earlier in the file
<Plovr>dependencies\plovr.jar</Plovr>
<PlovrConfig>dependencies\plovr-config.js</PlovrConfig>
How can I get msbuild to run the plovr.jar?
If you put in the full path to java.exe.....the EXEC command should work.
It just does a command line call....at the end of the day.
<Target Name="Build">
<Exec Command=""C:\Program Files (x86)\Java\jre7\bin\java.exe" -jar $(Plovr) build $(PlovrConfig)" />
</Target>
Also note the use of " .. to delimit a quote...
You can also put in some Message's to make sure you have what you think you have:
<Message Text="Plovr: $(Plovr)"/>
<Message Text="PlovrConfig: $(PlovrConfig)"/>
I'm trying to debug an msbuild script that is being run on our TFS build agent. I have no permissions to the build agent server.
Is there a way I can add some debugging to my msbuild script ("Message" or similar) to output a listing of all the files in a given directory?
Hope this helps to list all the files in the folder where the MSBuild files are there recursively:
<Target Name="Listing">
<ItemGroup>
<PackageFiles Include="$(MSBuildProjectDirectory)\**\*.*;"/>
</ItemGroup>
<Message Text="%(PackageFiles.FullPath)"/>
</Target>
I am deploying some files on the server. But when I am doing this, build is deleting all the files and folder which are residing at that location. I don't want to delete all the files from the server. I want to exclude one folder (folder name is Temp) from the destination folder. Temp folder should not get deleted while deleting other files. How to do that?
Here is TFS Build Definition
<PropertyGroup Condition=" '$(DeployEnvironment)' == 'Dev' ">
<DeployPath>\\server1\D$\temp\reports</DeployPath>
</PropertyGroup>
<Target Name="CoreCompileSolution" />
<Target Name="AfterCompile">
<Message Importance ="high" Text="Solution Root: $(SolutionRoot)" />
<Message Importance ="high" Text="Out Dir: $(OutDir)" />
<Copy SourceFiles="#(RPTFiles)" DestinationFolder="$(OutDir)_PublishedWebsites\Reports\" />
</Target>
<Target Name="AfterDropBuild" >
<CreateItem Exclude="$(DeployPath)\Temp*.*">
<Output ItemName="PreviousDeployment" TaskParameter="Include" />
</CreateItem>
</Target>
Why are you using a Copy task? I think it is intended to be used for local manipulations during build, rather than deployment (because it does not give you a chance to easily configure behaviour).
I suggest that instead of copy tsak you use one of the following options
Non-web applications - use Robocopy:
/XD dirs [dirs]... : eXclude Directories matching given names/paths.
XF and XD can be used in combination e.g.
ROBOCOPY c:\source d:\dest /XF *.doc *.xls /XD c:\unwanted /S
see this link for usage guide. You either run it from the command line (using <Exec Command="" > task, or employ MBuiild Community Tasksproject which has a nice wrapper.
Web applications: you should use Web Deploy for your deployments. You an either use MSBuild integration (VS 2010 and later, see this blog series for guidance on setup and configure on VS2010 NB: it has been much simplified in VS 2012, but I don't have a link to share at the moment) or run it from command line (prior to VS 2010):
<Exec Command=""$(WebDeployToolPath)" -verb:sync - source:dirPath='$(MSBuildProjectDirectory)\Published\' -dest:dirPath='$(DeployDirectoryLocalPath)',computerName=$(DeployTargetURL),userName='$(DeployUserName)',password='$(Password)',authType='Basic' -skip:skipaction='Delete',objectname='filePath',absolutepath='app_offline.htm' -skip:skipaction='Delete',objectname='filePath',absolutepath='logs\\.*' -skip:skipaction='Delete',objectname='dirPath',absolutepath='logs\\.*' -skip:skipaction='Delete',objectname='filePath',absolutepath='UserFiles\\.*' -skip:skipaction='Delete',objectname='dirPath',absolutepath='UserFiles\\.*' -verbose -allowUntrusted" />
NB using skip:skipaction='Delete.. to skip removing files and folders.
Update
It looks like I've undestood this a bit incorrect (I supposed, deployment happenned in AfterCompile target, however, as I see now, TFS uses CoreDropBuild target to do the deployment.
So I think, what you need is to override CoreDropBuild target as described: here. (although, I've never tried this).
You can either use Copy task as the author of the thread, or go with Robocopy/webdeploy based on your personal preference.
I'm creating a custom ITask for MSBuild which uploads the output files of my build. I'm using a web deployment project to publish my app and hooking in to the AfterBuild target to do my custom work.
If I add a file to my web application, the first time I do a build, my custom task is not recognizing the recently added file. In order for that file to show up in my array of ITaskItems, I have to first do a build with my 'AfterBuild' target removed and then start the build again with my 'AfterBuild' target in place.
Here is what my build file looks like:
<ItemGroup>
<PublishContent Include="$(OutputPath)\**" />
</ItemGroup>
<Target Name="AfterBuild">
<UploadTask FilesToPublish="#(PublishContent)" />
</Target>
The list in #(PublishContent) seems to be initialized at the beginning of the build instead of reflecting any changes that might have taken place by the build process itself.
Any ideas?
Thanks
Your ItemGroup is going to get evaluated when the project file first loads (when you first open Visual Studio or you 'unload' and 'reload' the project in Solution Explorer).
What you probably need is to create an ItemGroup as a task in your 'AfterBuild' target. Example:
<CreateItem Include="$(OutputPath)\**">
<Output TaskParameter="Include" ItemName="OutputFiles"/>
</CreateItem>
followed by:
<Target Name="AfterBuild">
<UploadTask FilesToPublish="#(OutputFiles)" />
</Target>