TFS 2010 Team Build - rename a file - tfs

As part of my TFS 2010 team build, I'm trying to copy a configuration file from a network location to the output folder where the build goes to.
Using xcopy as an invoke process task, I've successfully gotten it all working EXCEPT that I want to rename the file as part of the copy. The problem is that if you supply a different destination filename, XCOPY asks if the destination is a file or a directory e.g.
XCOPY \\networkshare\configs\live.config \\networkshare\release\server.exe.config /R /Y
results in XCOPY asking me to press F if server.exe.config is a file or D if it's a directory. XCOPY doesn't seem to have any way to suppress this behaviour. I've tried using the basic COPY commmand but Team Build just says that it doesn't recognise the COPY command.
Is there any way to easily rename a file as part of Team Build or use another command line tool to achieve this?
Cheers

Just to confirm - setting the process as CMD.EXE and starting the arguments as "/c copy" does the trick.

Related

Azure Web App Referencing DLL in Windows Directory

We are looking to get out of a Virtual Machine and convert a C# MVC website into an Azure Web App. The only hurdle, is that our web application references a C++ project that uses a DLL that has to be stored in the OS's Windows directory. Anyone know how to get around this or any other options?
Use a post-build action in your project, and add the commands to copy the offending DLL. The post-build action are written as a batch script.
The output directory can be referenced as $(OutDir). The project directory is available as $(ProjDir). Try to use relative paths where applicable, so that you can copy or move your project folder without breaking the post-build action.
You needed to copy some dlls to target directory (the build directory) so used the following in a Post-Build event in my project settings:
xcopy $(ProjectDir)openal32.dll $(TargetDir) /Y /D
Here are some commonly used switches with xcopy:
/I - treat as a directory if copying multiple files
/Q - Do not display the files being copied.
/S - Copy subdirectories unless empty.
/E - Copy empty subdirectories.
/Y - Do not prompt for overwrite of existing files.
/R - Overwrite read only files.

TFS build renaming the cspkg file

I currently use TFS build for my Azure cloud service project.
as a output of that .cspkg and .cscfg file is created after the successful build.
is there any way to add the $(Build.BuildNumber) to my .cspkg file
say for eg: currently my output file looks like
SchoolWebPortalAzure.cspkg
is it possible to rename like SchoolWebPortal_1.0.0.1.cspkg in the tfs build definition.
thanks,
kind regards,
Snegha
You could use the Run Command Line task or do it in a PowerShell script in build.
1). Add the Inline Powershell task from the marketplace before the copy task in build definition.
2).Enter the following Powershell in the text area
Param (
[string]$pathToFileToRename
)
Rename-Item $pathToFileToRename Helloworld_$(Build.BuildNumber).exe
3). Enter any required arguments in the arguments text box (you could
use environment variables) e.g. -pathToFileToRename $(Build.SourcesDirectory)\somepath\CurrentName.exe
Then you will get the renamed file in the drop folder.

Get sourcecode into Jenkins WORKSPACE subdirectory

Is it possible to configure Jenkins to get source code into a subdirectory of a %WORKSPACE%? Right now the source gets pulled into %WORKSPACE% and for the build output I explicitly specify a directory outside of the %WORKSPACE%.
Ideally I would like to have something similar to this:
%WORKSPACE%\source for source code and %WORKSPACE%\artifacts for build outputs. Is it possible to have this configuration?
Create a 'run batch command' build step and use xcopy, this is presuming jenkins is running on a Windows machine, if it's a deployment directory then make it a post build step.
cd c:/
xcopy /Y "c:/program files 86/junkies/workspace/app" "c:/path to new directory"
This is just a guess at your directories, replace with correct ones, the /Y forces it to be overwritten every time it's copied.

Prevent TFS Build Definition Source Settings from triggering a build

When I create a build definition I have setup some source settings, example below:
Problem is I want it to trigger a build when someone checks into the Builds or Install folders, but the Includes folder is just some libraries and other items it needs. I don't want it to re-run when these libraries are changed. However I need to set them up here to make sure they are copied across to the Build drop server. Is there a way to copy across this Includes folder without forcing a build trigger when someone checks in to this folder?
There are 2 things to do to approach this.
First you need to get your source folders into a build centric layout, this will help to eliminate as much overlapping as possible.
If you need a particular shared folder that shouldn't trigger a build, then don't include it in the source mappings, instead add a script to download the files to your workspace as an early part of the build.
The example will need updating for your visual studio version, and you should pass the sources Directory to the script.
REM %1 represents the Sources directory
REM Compute variables
SET TfExe="%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe"
REM SET TfExe="C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe"
Set RefPath="$/TFS BUILDS/Shapes/Main/Includes"
Set localPath="%~1\Includes"
REM set the Drive Letter for this build
Set Localdrive=%localPath:~1,2%
%Localdrive%
cd %1
REM Map the folders
%TfExe% workfold /map %RefPath% %localPath%
REM Get the required content
%TfExe% get %RefPath%
REM Unmap the folders
%TfExe% workfold /unmap %RefPath%
There is no easy way to do this. As you've discovered, the source settings do double-duty, they define the set of files needed for the build that are downloaded and the set of files that trigger a CI.
I would argue this isn't a problem, if the Includes are used in your build, then I would want to kick off a new build when they change, to ensure that the change didn't break anything in the build process.
Use the special keyword ***_NO_CI*** in your checkin into the Includes directory.
See this post for further details.

Build step triggered by TeamCity always builds - even when there are no changes

The problem: I am setting up TeamCity as a build server for an ASP.NET MVC project. I am using Powershell with psake to run msbuild against our .csproj file and create a deployable package. From the build server, I can open up powershell, run the script and, because there are no source code changes, msbuild does not regenerate the project DLL files. BUT, when I call the exact same script from the TeamCity web interface, msbuild ALWAYS rebuilds and regenerates the DLL files even though there are no changes. Not what it should do AFAIK.
I have narrowed this problem down to a single step. To keep it simple, I have set up my TeamCity config so it is not using any source control, it runs a single "powershell" build step that calls my powershell script.
The powershell script runs a single command:
exec { &$msbuild $ProjectFile /t:Package "/p:PackageLocation=$PackageFile;OutDir=$TempPath;Configuration=$Config;SolutionDir=$BaseDir\Source\" /v:m }
When I call the script manually from a powershell command line, I see:
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
When I call the exact same script through TeamCity, I see:
[11:11:26]: CoreCompile:
[11:11:26]: c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig ...
<SNIP>
[11:11:32]: CopyFilesToOutputDirectory:
[11:11:32]: Copying file from "obj\Demo\Website.Web.dll" to "d:\deploy\Build\package\Demo\temp\Website.Web.dll".
[11:11:32]: Website.Web -> d:\deploy\Build\package\Demo\temp\Website.Web.dll
[11:11:32]: Copying file from "obj\Demo\Website.Web.pdb" to "d:\deploy\Build\package\Demo\temp\Website.Web.pdb".
[11:11:32]: _CopyWebApplicationLegacy:
[11:11:32]: Copying Web Application Project Files for Website.Web
[11:11:32]: Copying file from "obj\Demo\Website.Web.dll" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Web.dll".
[11:11:32]: Copying file from "obj\Demo\Website.Web.pdb" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Web.pdb".
[11:11:32]: Copying file from "d:\deploy\Build\package\Demo\temp\Website.Data.dll" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Data.dll".
[11:11:32]: Copying file from "d:\deploy\Build\package\Demo\temp\Website.Data.pdb" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Data.pdb".
Any ideas why running this script from TeamCity causes msbuild to detect changes and rebuild, but running the exact same script manually does not?
UPDATE:
Thinking this might be caused by some quirk with the TeamCity Powershell runner, I just tried making a batch file that passes the script into Powershell.exe and called it using the Command Line runner:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -File D:\deploy\Build\run-build.ps1 && exit /b %ERRORLEVEL%
and I get the exact same behavior. If I call this batch file from the command line, the msbuild skips compilation. If I call it from TeamCity, the DLLs are recompiled.
UPDATE #2:
Eureka! I turned on diagnostic debugging in msbuild and found the cause of the forced recompile. It is caused by the GenerateTargetFrameworkMonikerAttribute target. Here is the key bits from the log output:
[15:23:28]: Target "GenerateTargetFrameworkMonikerAttribute" in file "c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "d:\deploy\source\Website.Data\Website.Data.csproj" (target "BeforeCompile" depends on it):
[15:23:28]: Building target "GenerateTargetFrameworkMonikerAttribute" completely.
[15:23:28]: Output file "C:\TeamCity\buildAgent\temp\buildTmp\.NETFramework,Version=v4.0.AssemblyAttributes.cs" does not exist.
[15:23:28]: Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
[15:23:28]: Task "WriteLinesToFile"
[15:23:28]: Done executing task "WriteLinesToFile".
[15:23:28]: Done building target "GenerateTargetFrameworkMonikerAttribute" in project "SMM.Data.csproj".
It looks like this target creates/updates an AssemblyAttributes file in the TEMP dir as specified in the TEMP environment variable. Apparently TeamCity overrides the TEMP environment variable and sets it to: C:\TeamCity\buildAgent\temp\buildTmp and this directory is cleaned before every build.
I can see this if I call Get-ChildItem Env: from powershell:
TEMP C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
TMP C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
But if I call it from the powershell script as called from TeamCity:
TEMP C:\TeamCity\buildAgent\temp\buildTmp
TMP C:\TeamCity\buildAgent\temp\buildTmp
The key piece is that after this file is regnerated:
[15:23:28]: Building target "CoreCompile" completely.
[15:23:28]: Input file "C:\TeamCity\buildAgent\temp\buildTmp\.NETFramework,Version=v4.0.AssemblyAttributes.cs" is newer than output file "obj\Demo\SMM.Data.pdb".
And this is why the whole project is getting recompiled.
When I run the script from Powershell, the temp directory is not changed or cleaned and the build runs as expected.
So, anyone know how I can either change the directory that this AssemblyAttributes file is created, or tell TeamCity to use a different TEMP dir? I have to believe that this is an issue that others have run into.
Thanks!
So, as I mentioned in "Update #2" above, the problem seems to be caused by 2 things:
- TeamCity sets the TEMP and TMP environment vars to its own temp directory
- TeamCity "cleans" this temp directory prior to every build
- Part of the msbuild process runs a GenerateTargetFrameworkMonikerAttribute target that updates a specific file in the directory specified by the TEMP environment variable - causing the compiler to thing it needs to recompile the whole project
Once I figured this out, I found an applicable answer in this unrelated question:
In Visual Studio 2010 why is the .NETFramework,Version=v4.0.AssemblyAttributes.cpp file created, and can I disable this?
So I added:
<Target Name="GenerateTargetFrameworkMonikerAttribute" />
to both of the projects in my solution that compile to DLLs and it worked.
As a variation of obliojoe's answer, you can backup and restore these files to/from TEMP folder, if you do not want or cannot change the individual project files:
First attempt to restore the files from a backup:
copy temp\*.* %%temp%% /y
echo AssemblyAttributes restore attempted
Then perform your build step(s) using TeamCity build runner
Backup the files:
mkdir temp 2> nil
copy %%temp%%\*AssemblyAttributes.cs temp /y
echo AssemblyAttributes files saved
Both batch files need to run from the same directory.
Do note the final ECHO in these batch files, it is there to guarantee successful exit (error code 0).

Resources