I'm using TeamCity to build and deploy into our demo site. We have one configuration called HTML Demo Site and one of the build step is using NAnt to deploy the HTML to the site.
The build file have defined a target:
<target name="deploy-html" description="Deploys the HTML to the demo server">
<echo message="Deploying HTML to the demo server..."/>
<copy todir="\\<server>\<dir>\<client>" includeemptydirs="true" overwrite="true">
<fileset basedir="..\html\_master">
<include name="**\*"/>
<exclude name="node_modules\**"/>
</fileset>
</copy>
</target>
Each time I run the build on TeamCity, it's failing with this error:
C:\tc\w\9149e011dfa8657d\build_scripts\website.build(27,14):
[NAnt output] Error creating FileSet.
[NAnt output] The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
So I tried running on PowerShell to get a list of files that exceed the max length:
Get-ChildItem -Recurse | Where-Object {$_.FullName.Length -gt 248}
But the only files returned are files under the node_modules directory. But in the build file, it's being excluded. So I'm not sure where else to look? Any ideas?
You could try a few things:
Delete the node_modules dir first
Use robocopy /mir in an <exec> task
try putting exclude first before include (not likely, but worth a try)
try changing the path expression to name="node_modules\**\*" or name="**\node_modules\**" or similar
Deleting first worked for me - but the built in nant delete task also has problems so I had to use the rmdir console command
<exec program="${environment::get-variable('WinDir')}\system32\cmd">
<arg value="/c "rmdir /q /s ${Build.BuildFolder}\WebApplication\node_modules"" />
</exec>
Related
Publish of ASP.Net Core project fails with next error:
"DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s).
They must have the same number of items.
I get an error when I try to publish an ASP.Net Core website to Azure. It builds and runs fine locally. The output prints this:
Task "Copy"
Task Parameter:
SourceFiles=
C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\appsettings.json
CopyToPublishDirectory=PreserveNewest
RelativePath=appsettings.json
TargetPath=appsettings.json
C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\appsettings.json
CopyToPublishDirectory=PreserveNewest
RelativePath=appsettings.json
TargetPath=appsettings.json
Task Parameter:DestinationFiles=C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\obj\Release\netcoreapp1.0\PublishTemp\PublishOutput\appsettings.json
Task Parameter:OverwriteReadOnlyFiles=False
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets(100,5): Error MSB3094: "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s). They must have the same number of items.
Output Item(s): FileWrites=C:\Users\Mikael\Source\Repos\GoMap-Web\src\Web\obj\Release\netcoreapp1.0\PublishTemp\PublishOutput\appsettings.json
Done executing task "Copy" -- FAILED.
Done building target "_CopyResolvedFilesToPublishPreserveNewest" in project "Web.csproj" -- FAILED.
Done building project "Web.csproj" -- FAILED.
The Microsoft.NET.Publish.targets file (the relevant part, i belive) look like this:
============================================================
CopyFilesToPublishDirectory
Copy all build outputs, satellites and other necessary files to the publish directory.
============================================================
-->
<Target Name="CopyFilesToPublishDirectory"
DependsOnTargets="_CopyResolvedFilesToPublishPreserveNewest;
_CopyResolvedFilesToPublishAlways" />
<!--
============================================================
_CopyResolvedFilesToPublishPreserveNewest
Copy _ResolvedFileToPublishPreserveNewest items to the publish directory.
============================================================
-->
<Target Name="_CopyResolvedFilesToPublishPreserveNewest"
DependsOnTargets="_ComputeResolvedFilesToPublishTypes"
Inputs="#(_ResolvedFileToPublishPreserveNewest)"
Outputs="#(_ResolvedFileToPublishPreserveNewest->'$(PublishDir)%(RelativePath)')">
<!--
Not using SkipUnchangedFiles="true" because the application may want to change
one of these files and not have an incremental build replace it.
-->
<Copy SourceFiles = "#(_ResolvedFileToPublishPreserveNewest)"
DestinationFiles="#(_ResolvedFileToPublishPreserveNewest -> '$(PublishDir)%(RelativePath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForPublishFilesIfPossible)"
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForPublishFilesIfPossible)">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
<!--
============================================================
_CopyResolvedFilesToPublishAlways
Copy _ResolvedFileToPublishAlways items to the publish directory.
============================================================
-->
<Target Name="_CopyResolvedFilesToPublishAlways"
DependsOnTargets="_ComputeResolvedFilesToPublishTypes">
<!--
Not using SkipUnchangedFiles="true" because the application may want to change
one of these files and not have an incremental build replace it.
-->
<Copy SourceFiles = "#(_ResolvedFileToPublishAlways)"
DestinationFiles="#(_ResolvedFileToPublishAlways -> '$(PublishDir)%(RelativePath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForPublishFilesIfPossible)"
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForPublishFilesIfPossible)">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
I have changed the DestinationFiles="#(_ResolvedFileToPublishPreserveNewest -> '$(PublishDir)%(RelativePath)')" according to another post here but I still get the same failure, and I don't know enough about it to find any clear errors, can anyone offer some insight? If this is affected by the bug mentioned in other posts that has no workaround, what alternative ways could I try to publish the app to azure that might work better?
My problem: I have build on TeamCity that produces a zip file: Files.zip
It contains lots of files, and a zip file is a good container for the files.
Sadly though, and due to legacy reasons, the zip file has no version number in it's title. I would like it to have a version number in it.
Like this: Files.1.2.3.4.zip
I thought that maybe I could create a containing zip, that I can adorn with a version number, like this: ContainingZip.1.2.3.4.zip!Files.zip
So that Files.zip is zipped into another zip! (Madness).
But I cannot work out how to do that through TeamCity and it's artifact paths?
What I feel should work is:
/**/. => Files.Zip => ContainingZip.1.2.3.4.zip!Files.zip
But that just makes Files.Zip
Breaking it into two steps, works not too:
/**/. => Files.Zip
Files.Zip => ContainingZip.1.2.3.4.zip
This doesn't work either as Files.zip doesn't exist when the artifact existence checks are done.
Anyone know how to do this?
(Or do I have to pre-zip in a build step?)
Thanks.
Answer: TeamCity will not let you double zip in the artifact window. You have to use a build step.
Which you can do...
Via a PowerShell build step you can use Compress-Archive if you have PowerShell 5+.
Or there is good infomation here http://stackoverflow.com/questions/1153126/how-to-create-a-zip-archive-with-powershell for older PowerShell versions.
Via an Ant build step:
<?xml version="1.0" encoding="UTF-8"?>
<project name="zipper" default="zip" basedir=".">
<property name="project-name" value="Files.zip" />
<property name="folder-to-zip" value="./FolderToZip/" />
<target name="zip">
<delete file="${project-name}" />
<zip destfile="${project-name}" basedir="${folder-to-zip}" excludes="${project-name}" />
</target>
</project>
You can use parameter references in the artifacts path, so if you define a configuration parameter called, say, VersionNumber that contains the version number value and use an artifact definition of
/**/. => Files.%VersionNumber%.Zip
then you will get the desired output.
i have a console application in vs2010 (C#) and in the project, i have a Folder added by me (right click on project.. add->folder) and i want that when i compile the application (debug or release), then the folder will be created (if not exists) in the debug or release directory.
Is that possible?
The console application is a daemon that access to a database and send emails with templates allocated in that folder.
I hope you can help me. Thanks!
There's no "automatic" way to get VS to create folders (other than the specified output folder) during a build, but there's two pretty easys ways to accomplish it.
Use a post-build event, which you set up in the Build Events tab of your project's properties. This is basically a batch file that you run after the build completes, something like this:
IF NOT EXIST $(OutDir)MySubFolder MKDIR $(OutDir)MySubFolder
XCOPY /D $(ProjectDir)MySubFolder\*.tmpl $(OutDir)MySubFolder
Use MSBuild's AfterBuild event. This is my preferred method, mostly because it integrates better with our automated build process, but it's a little more involved:
Right-click on your project node and Unload it
Right-click on the unloaded project node and Edit the file
Near the bottom is a commented-out pair of XML nodes. Uncomment the AfterBuild target and replace it with something like this:
<Target Name="AfterBuild">
<MakeDir Directory="$(OutDir)MySubFolder" Condition="!Exists('$(OutDir)MySubFolder')" />
<CreateItem Include="$(ProjectDir)MySubFolder\*.tmpl">
<Output TaskParameter="Include" ItemName="Templates" />
</CreateItem>
<Copy SourceFiles="#Templates" DestinationFolder="$(OutDir)MySubFolder" ContinueOnError="True" />
</Target>
Save the changes, close the .csproj file, then right-click and Reload the project.
I solve it, like this:
in the csproj:
<Target Name="AfterBuild">
<MakeDir Directories="$(OutDir)EmailTemplates" Condition="!Exists('$(OutDir)EmailTemplates')" />
<ItemGroup>
<Templates Include="$(ProjectDir)EmailTemplates\*.*" />
</ItemGroup>
<Copy SourceFiles="#(Templates)" DestinationFolder="$(OutDir)EmailTemplates" />
</Target>
Thank you for your help!
I have Cruise Control configured with a task to run a NAnt script, which runs an MSTest suite. MSTest allows me to specify test categories so I want to specify "!Integration" (which means "don't run Integration tests"). My Nant script successfully runs when I run it from the command line, but when Cruise runs it, the "!Integration" directive is being garbled -- the Cruise output suggests its inserting a line break after the '!' character. The result is that all my tests run, including integration tests.
Extract from ccnet.config:
<tasks>
<nant>
<executable>C:\nant\bin\nant.exe</executable>
<baseDirectory>C:\MyProject\BuildDirectory</baseDirectory>
<buildFile>MyProject.build</buildFile>
<targetList>
<target>CIServerBuild</target>
</targetList>
</nant>
</tasks>
Extract from MyProject.build:
<target name="CIServerBuild">
:
<call target="RunUnitTests" />
</target>
<target name="RunUnitTests">
<property name="TestCategories" value="!Integration" />
<call target="RunMSTest" failonerror="true"/>
</target>
<target name="RunMSTest">
<call target="BuildListOfTestContainers" failonerror="true"/>
<exec program="${MSTest.exe}"
commandline=" /category:"${TestCategories}" ${TestContainers} /resultsfile:${MSTest.ResultsFile} /nologo "
/>
</target>
Extract from Cruise output:
[exec] Starting 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe ( /category:"!
Integration" /testcontainer:C:\TaxWise\BuildDirectory\TaxWise\TaxWise.Data.Tests\bin\Debug\TaxWise.Data.Tests.dll /testcontainer:C:\TaxWise\BuildDirectory\TaxWise\TaxWise.Domain.Tests\bin\Debug\TaxWise.Domain.Tests.dll /testcontainer:C:\TaxWise\BuildDirectory\TaxWise\TaxWise.Infrastructure.Tests\bin\Debug\TaxWise.Infrastructure.Tests.dll /resultsfile:.\TestResults\UnitTests.trx /nologo )'
in 'C:\TaxWise\BuildDirectory'
I have tried replacing the '!' character with
'!'
but that made no difference.
Any ideas, anyone?
I suggest splitting the commandline attribute in the exec task into Nant arg elements.
http://nant.sourceforge.net/release/0.85/help/tasks/exec.html
You'll have more flexibility and the readability will increase.
Yes, perhaps it is not caused by CC. Try setting verbose="True" on the <exec> task and check the raw build protocol. Remember what you see on the report page is not the exact output (typically subject to line-wrap and coalescing whitespaces).
Maybe it depends on from where you run the script, a hidden dependency on a build property or different environment variables. You can check the latter using <exec program="cmd.exe" commandline="/c set" />. For the properties you can use the following script:
<script language="C#" prefix="util" verbose="true">
<code>
<![CDATA[
public static void ScriptMain(Project project)
{
foreach (DictionaryEntry entry in new System.Collections.SortedList(project.Properties) )
Console.WriteLine("{0}={1}", entry.Key, entry.Value);
}
]]>
</code>
</script>
I am trying to copy a folder to a remote machine using xcopy. This command is executed via cruise control task. I can run xcopy source destOnRemoteMachine successfully if i am running it from command prompt. But if i am executing it from cruise control .net, it is always complaining about "Invalid drive specification" error.
I tried :
> <exec
> executable="c:\Windows\System32\xcopy.exe">
> <baseDirectory>$(BASE)\Project</baseDirectory>
> <buildArgs>.\*.* RemoteMachine\Project /Y</buildArgs>
> <buildTimeoutSeconds>10</buildTimeoutSeconds>
> <successExitCodes>-1,0,1</successExitCodes>
> </exec>
and :
<exec executable="c:\Windows\System32\cmd.exe">
<baseDirectory>$(BASE)\Project</baseDirectory>
<buildArgs>/C xcopy $(BASE)\Project\*.* RemoteMachine /y</buildArgs>
<buildTimeoutSeconds>30</buildTimeoutSeconds>
<successExitCodes>-1,0,1</successExitCodes>
</exec>
Any Suggestions?
thanks for your answer. Putting xcopy in batch was also not helpful, the problem was something else. here is problem:
It was problem with the account on which Cruise Control .net service was running. It was running as local service. Thus was not able to see the network path. I changed CCNet Service to run on a domain account which have permission to read/ write on remote machine. This solved my problem.
Thanks.
Create a batch file using xcopy source destOnRemoteMachine command and execute that bat file using <exec> command in cruise control .net
In my case I was running CC as a user account, after having used NET USE to persistently map a drive letter to a network share on another domain. Although it worked in a desktop session, CC could still not get to the share as part of the build. Executing NET USE as part of the build (without a drive mapping) allowed the copy to succeed.
<exec program="net" verbose="true">
<arg value="use" />
<arg value="\\server\share" />
<arg value="password" />
<arg value="/user:domain\username" />
</exec>