Send notification to be received on TFS Get Latest Version - tfs

We are using TFS on Visual Studio 2013. When our developers Get Latest Version (GLV) and there is a new db script file received, it is stored under a specific folder, to be run using our custom update app.
What I want is that upon doing a GLV, they get a notification (in Visual Studio) that there are new scripts to run to update the db (generically speaking, that a new file has been added under a certain path).
Is there a way to achieve this with TFS?

It will not give you exactly what you want, but you can use built in TFS alerts to notify you or the team when a file is checkedin under a folder with a specific name/specified path/file extension.

You could write a visual studio extension, to be triggered on Get Latest, which would check a certain path within source control, you would have to roll this to all of your developers and would either have to store the lookup paths centrally or redeploy the app if the look up paths changed.
Alternatively you could add a bat / powershell script to your source control. within this script you could do the get latest and also run any scripts that you would like to run. you would then get the developers to get the latest against this script and then run it, which would get the rest of the files and would also run the db scripts.

If I understand correctly, you want your users to be running their locally built solutions against the latest database version to keep everyone in sync. Why not just use the usual workflow to procure 'notifications' in the form of build output?
I've dealt with this in the past, and the best solution I've come up with is to write a custom MSBuild target for 'BeforeBuild' into each of the projects that rely on the database being updated. The MSBuild target checks the version of the database installed (You would have to come up with a means for doing so, it can be tricky!).
If the currently deployed database does not match the version in the scripts you have just synced to, a build event could be raised. When the versions match the target would output a success message (or maybe nothing at all), and if the versions do not match the target would issue a build Warning or build Error depending on the severity of change observed (it might depend for you insofar as Major/Minor version variance is considered).

Related

Automatic Versioning with Team Foundation Server 2012; Increment Only on Changed Assembly

I've been tasked with setting up a new Team Foundation/Build server at my company, with which we'll be starting a new project. Nobody here currently has experience with TFS, so I'm learning all of this on my own. Everything is working so far; The server's been set up, the Repository and Team Project has been created, the Build Server has been created, and I've created a simple hello world application to verify the source control and Continuous Integration builds (on the build server) run properly.
However, I'm having a problem setting up the automatic versioning. I've installed the TfsVersioning project, and it's working fine; I'm able to define a format for my assembly versions. I haven't yet decided what format I'll use; probably something like Major.Minor.Changeset.Revision (I'm aware of the potential problem regarding using the changeset number in the assembly version, so I may decide to switch to Major.Minor.Julian.Revision before we begin development).
The problem:
I don't want assemblies to have new file versions if their source code has NOT changed since the last build. With a continuous Integration build this isn't a problem, as the build server will only grab the source files that have changed, causing an incremental build which produces only updated modules; the existing unchanged modules won't be built, so their version will remain unchanged.
If I set up a nightly build, I'll want to clean the workspace and perform a Build-All. However, this means that ALL assemblies will have new version (assuming the Assembly File Version includes the build number).
A solution?
This has prompted me to consider using the latest changeset number in the Assembly File Version. This way, if nothing has been committed between two successive Build-Alls, the versions won't be incremented. However, this would mean that a change and commit to a single file would force a version increment on ALL assemblies.
I'm looking for one of two things:
A way to only increment Assembly Version Numbers if their source/dependencies have changed since the last build. Successive Build-Alls should not cause changes in version numbers.
OR
A way for testers and non-developers to be able to tell version W.X.Y.Z and version W.X.Y.Z+1 of assembly 'Foo' are identical, even though they have differing file versions.
I've probably read about 20 articles on the subject, and nobody (except this guy) seem to address the issue. If what I'm asking for isn't common practice in the Team Foundation ALM, how do I address the second bullet point above?
Thanks for your time!
This is something I did in the past. The solution has two critical points:
You must use an incremental build, i.e. Clean Workspace = None
The change to AssemblyInfo.cs must be computed at each project
This latter is the most complex and I will just draft the solution here.
In the custom MSBuild properties use CustomAfterMicrosoftCommonTargets to inject an hook in normal Visual Studio compile
/property:CustomAfterMicrosoftCommonTargets=custom.proj
Also forward a value for the version
/property:BuildNumber=1.2.3.4
In custom.proj redefine the target BeforeCompile to something similar
<Target Name="BeforeCompile"
Inputs="$(MSBuildAllProjects);
#(Compile);
#(_CoreCompileResourceInputs);
$(ApplicationIcon);
$(AssemblyOriginatorKeyFile);
#(ReferencePath);
#(CompiledLicenseFile);
#(EmbeddedDocumentation);
$(Win32Resource);
$(Win32Manifest);
#(CustomAdditionalCompileInputs)"
Outputs="#(DocFileItem);
#(IntermediateAssembly);
#(_DebugSymbolsIntermediatePath);
$(NonExistentFile);
#(CustomAdditionalCompileOutputs)"
Condition="'$(BuildNumber)'!=''">
<Message Text="*TRACE* BuildNumber: $(BuildNumber)"/>
<MyTasksThatReplaceAssemblyVersion
BuildNumber="$(BuildNumber)"
File="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs"/>
</Target>
You need to have a task for replacing the AssemblyFileVersion in the AssemblyInfo.cs source. MSBuild Extension Pack has an AssemblyInfo task for this purpose.
I posted the full details at my blog here, here and here.

Retrieving path to solution(s)?

We are currently setting up Team Build 2010 for our company, and I am trying to use workflow activities to retrieve the exact local path to the current solution being built. I haven't found a way to get this value, does anybody know how (without writing a custom activity)?
Either one of server or local path would suffice (i.e $/TeamProject/Branch/OurProject or C:\TeamBuild\src\path\to\branch\OurProject) since we can use the conversion activities on the server item.
The reason we need this path is for updating version info files, and that needs to be done for only the current solution being built, and the files have the same names (AssemblyInfo.cs, for example).
In this similar question, the solution is to define a parameter, but since this information is particular to the solution being built and not some external path, we were hoping that this info would retrievable.
You can retrieve this particular info without adding anything. If you navigate within your Build Process Template to the position where MSBuild breaks out, you will see that the solution that shall be build is set as a string named localProject. This will contain the local path where TFS has downloaded your SLN, something like C:\TeamBuild\src\path\to\branch\OurProject\OurProject.sln.Open the XAML and navigate to:
Run On Agent
Try Compile, Test, and Associate Changesets and Work Items
Compile, Test, and Associate Changesets and Work Items
Try Compile and Test
Compile and Test
For Each Configuration in BuildSettings.PlatformConfigurations
Compile and Test for Configuration
If BuildSettings.HasProjectsToBuild
For Each Project in BuildSettings.ProjectsToBuild
Try to Compile the Project
Compile the Project
Run MSBuild for Project
if you select Run MSBuild for Project & hit F4 you see it.
In order to retrieve what you are after you can define another string-variable solutionPath in your Build Process Template & insert under the Run MSBuild for Project a new Assign activity withTo : solutionPath andValue : Path.GetDirectoryName(localProject)
Have you looked at the TFS Community Build Extensions, they give you a assembly versioning out of the box?
You can use the variable called SourcesDirectory to get the current Source Directory on the Build Server. You can also use an ConvertWorkspaceItem activity to convert between server and local paths.
There's also a blog post that cover's all of this here.

Team Build: Publish locally using MSDeploy

I'm just getting started with the team build functionality and I'm finding the sheer amount of things required to do something pretty simple a bit overwhelming. My setup at the moment is a solution with a web app, an assembly app and a test app. The web app has a PublishProfile set up which publishes via the filesystem.
I have a TFS build definition set up which currently builds the entire solution nightly and drops it onto a network share as a backup of old builds. All I want to do now is have the PublishProfile I've already setup publish the web app for me. I'm sure this is really simple but I've been playing with MSBuild commands for a full day now with no luck. Help!
Unfortunately sharing of the Publish Profile is not supported or implemented in MSBuild. The logic to publish from the profile is contained in VS itself. Fortunately the profile doesn't contain much information so there are ways to achieve what you are looking for. Our targets do not specifically support the exact same steps as followed by the publish dialog, but to achieve the same result from team build you have two choices, I will outline both here.
When you setup your Team Build definition in order to deploy you need to pass in some values for the MSBuild Arguments for the build process. See image below where I have highlighted this.
Option 1:
Pass in the following arguments:
/p:DeployOnBuild=true;DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder;PackageTempRootDir="\\sayedha-w500\BuildDrops\Publish";AutoParameterizationWebConfigConnectionStrings=false
Let me explain these parameters a bit, show you the result then explain the next option.
DeployOnBuild=true:This tells the project to execute the target(s) defined in the DeployTarget property.
DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder: This specifies the DeployTarget target.
PackageTempRootDir="\\sayedha-w500\BuildDrops\Publish": This specifies the location where the package files will be written. This is the location where the files are written before they are packaged.
AutoParameterizationWebConfigConnectionStrings=false: This tells the Web Publishing Pipeline (WPP) to not parameterize the connection strings in the web.config file. If you do not specify this then your connection string values will be replaced with placeholders like $(ReplacableToken_dummyConStr-Web.config Connection String_0)
After you do this you can kick off a build then inside of the PackageTempRootDir location you will find a PackageTmp folder and this contains the content that you are looking for.
Option 2:
So for the previous option you probably noticed that it creates a folder named PackageTmp and if you do not want that then you can use the following options instead.
/p:DeployOnBuild=true;DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder;_PackageTempDir="\\sayedha-w500\BuildDrops\Publish";AutoParameterizationWebConfigConnectionStrings=false
The difference here is that instead of PackageTempRootDir you would pass in _PackageTempDir. The reason why I don't suggest that to begin with is because MSBuild properties that start with _ signify that the property in essentially "internal" in the sense that in a future version it may mean something else or not exist at all. So use at your own risk.
Option 3
With all that said, you could just use the build to package your web. If you want to do this then use the following arguments.
/p:DeployOnBuild=true;DeployTarget=Package
When you do this in the drop folder for your build you will find the _PublishedWebsites folder as you normally would, then inside of that there will be a folder {ProjectName}_Package where {ProjectName} is the name of the project. This folder will contain the package, the .cmd file, the parameters file and a couple others. You can use these files to deploy your web.
I hope that wasn't information over load.
The ability to publish web sites, configure IIS and push schema changes for the DEV->QA->RELEASE cycle has required either custom configuration to imitate publish or custom code where IIS settings are involved.
As of Visual Studio 2013.2 Microsoft has added a third party product that manages deployment of web sites, configuration changes and database deployment with windows workflow and would be the recommended solution for automating deployment from TFS build.
More information can be found here:
http://www.visualstudio.com/en-us/explore/release-management-vs.aspx
You can use the Publish/Deploy in Visual Studio 2010.
See http://www.ewaldhofman.nl/post/2010/04/12/Auto-deployment-of-my-web-application-with-Team-Build-2010-to-add-Interactive-Testing.aspx for more information

Why doesn't TFS get latest get the latest?

Why Why WHY doesn't TFS's get latest work consistently?
You would have thought that feature would have been tested thoroughly.
What I have to do is, get specific version, then check both overwrite writetable files + overwrite all files.
Is my local setup messed up or you do this also?
TFS redefined what "Get Latest" does. In TFS terms, Get Latest means get the latest version of the files, but ignore the ones that the server thinks is already in your workspace. Which to me and just about everyone else on the planet is wrong.
See this link: http://blogs.microsoft.co.il/blogs/srlteam/archive/2009/04/13/how-get-latest-version-really-works.aspx
The only way to get it to do what you want is to Get Specific Version, then check both of the "Overwrite ..." boxes.
Sometimes Get specific version even checking both checkboxes won't get you the latest file. You've probably made a change to a file, and want to undo those changes by re-getting the latest version. Well... that's what Undo pending changes is for and not the purpose of Get specific version.
If in doubt:
undo pending check in on the file(s)
do a compare afterwards to make sure your file matches the expected version
run a recursive 'compare' on your whole project afterwards to see what else is different
keep an eye on pending changes window and sometimes you may need to check 'take server version' to resolve an incompatible pending change
And this one's my favorite that I just discovered :
keep an eye out in the the Output window for messages such as this :
Warning - Unable to refresh R:\TFS-PROJECTS\www.example.com\ExampleMVC\Example MVC\Example MVC.csproj because you have a pending edit.
This critical message appears in the output window. No other notifications!
Nothing in pending changes and no other dialog message telling you that the file you just requested explicitly was not retrieved! And yes - you resolve this by just running Undo pending changes and getting the file.
TFS, like some other source control providers, such as Perforce, do this, as the system knows what the last version you successfully got was, so get latest turns into "get changes since x". If you play by its rules and actually check things out before editing them, you don't confuse matters, and "get latest" really does as it says.
As you've seen, you can force it to reassess everything, which has a much greater bandwidth usage, but behaves closer to how SourceSafe used to.
It's hard to respond to a statement without examples of how it's not working, but it's crucial to understand that TFVC (in "Server Workspace" mode, which was the mechanism prior to TFS 2012) does not examine the state of your local filesystem. TFVC Server Workspaces are a "checkout-edit-checkin" type of system where this is by-design, an intentional decision made to massively reduce the amount of file I/O required to determine the state of your workspace. Instead, the workspace information is saved on the server.
This allows TFVC Server Workspaces to scale to very large codebases very efficiently. If you are in a multi-gigabyte code base (like Visual Studio or the Windows source tree) then your client does not need to scan your local filesystem, looking for files that may have changed, because the contract you have with TFS is that you will explicitly check a file out when you want to edit it.
You are expected to not mark a file as write-only and change it without explicitly checking it out first. If you go down this route, then the server does not know that you have made changes to your file, and performing a "Get Latest" operation will not update your local workspace, because you haven't told the server that you've made changes.
If you do subvert this mechanism then you can use the tfpt reconcile command to examine your local workspace for changes that you have made locally.
If you find yourself using "Get Specific Version" and selecting the "force" and "overwrite" options, then it is very likely that you are in the habit of bypassing all of the enforcements that TFS has implemented to keep you from hurting yourself, and you should probably consider TFVC Local Workspaces.
TFVC Local Workspaces provide an "edit-merge-commit" type of version control system, which means that you do not need to explicitly check files out before editing them and they are not read-only on-disk. Instead, you simply need to edit the file, and your client will scan the filesystem, notice the change, and present this as a pending change.
TFVC Local Workspaces are recommended for small projects that do not require fine-grained permissions control, since they present a much nicer workflow. You are not required to be online, and you do not have to explicitly check files out before editing them.
TFVC Local Workspaces are the default in TFS 2012, and if they are not enabled for you, then you should ask your server administrator. (Organizations with very large codebases or strict auditing requirements may disable TFVC Local Workspaces.)
Eric Sink's excellent book Version Control By Example outlines the differences between checkout-edit-checkin and edit-merge-commit systems and when one is more appropriate than the other.
The Professional Team Foundation Server 2013 book also provides excellent information about the differences between TFVC Server Workspaces and TFVC Local Workspaces. The MSDN documentation and blogs also provide detailed information:
Decide between using a local or a server workspace
Server workspaces vs. local workspaces
Team Foundation Server – Trying to understand Server versus Local Workspaces
Team Foundation Server (TFS) keeps track of its local copy in a hidden directory called $TF.When you issue the "get Latest Version", TFS looks into this folder and see weather I have the latest copy or not. If it does it will not download the latest copy. It does not matter if you have the original file or not. In fact you might have deleted the entire folder (as in my case) and TFS won't fetch the latest copy because it does not look into the actual file but the hidden directory where it records changes. The flaw with this design is, anything done outside the system will not be recorded in TFS. For example, you may go into Windows explorer, delete a folder or file and TFS wont recognize it. It will be totally blind. At least I would expect there Windows would not let you delete this file but it does!
One way to enforce the latest copy is to delete the hidden $TF folder manually. To do that, go to command prompt and navigate to the root folder where you project was checked out and issue this command
rd/s $tf // remove $TF folder and everything inside it
If you want to just check the hidden folder, you can do it using
dir /ah // display hidden files and folders
Note: If you do it, the tf will think you do not have any local copy even though you have it in files and it will sync up everything again.
Caution: Use this method at your own risk. Please do not use it on critical work.
"Get latest version" by default will only download the files that have changed on the server since the last time you ran "Get latest version". TFS keeps track of the files you download so it doesn't spend time downloading the same version of the files again. If you are modifying the files outside of Visual Studio, this can cause the consistency problems it sounds like you are seeing.
Unfortunately, there has to be one or more bugs in TFS 2008, since this problem regularly crop up on developer machines and build servers where I work as well.
I can do Get Latest, I can see in the history list of the project that there have been commits after I last did a Get Latest, I have not touched the files on disk in any way, but after the "Get Latest" function has completed, when I check the TFS tab, some of the files still says that they're not the latest version.
Obviously TFS is able to determine that I have old files locally, since the list says so. Yet, Get Latest fails to do that, get the latest version. If I do what you did, use the Get Specific version, and check the two checkboxes at the bottom of the dialog, then the files are retrieved.
We changed our build servers to always use the Get Specific version type of function instead, so this part now works, but since our build server (TeamCity) also relies on checking if there have been changes to the files in order to kick off a build, sometimes it lapses into a "nothing changed, nothing to see here, move along" mode and does nothing until we forcibly run the build configuration.
Note that I have experienced this problem on a machine that is never touched, except for get latest + build, both manually, so there's nothing tampering with the files. It's just TFS getting confused.
One time this cropped up I verified that the files on disk was indeed binary identical to the version previously retrieved, so no manual tampering had been done with the files.
Also, I fail to see how TFS can "know" whether files have changed on disk or not without actually looking at the contents. If one part of TFS can see that the files are indeed not the latest version, then the Get Latest version should absolutely be able to get the latest version. This in reference to comments to other answers here.
It might because you are login TFS as the same user, and the workspace name (based on machine name by default) is also the same, so TFS thinks your are on the same machine and same workspace, thus you already have the latest version of the files, so it wont get them for you.
try rename your machine, and create a new workspace as a new machine.
Go with right click: Advanced > Get Specific Version. Select "Letest Version" and now, important, mark two checks:
The checks are:
Overwrite writeable files that are not checked
Overwrite all files even if the local version matches the specified version
WHen I run into this problem with it not getting latest and version mismatches I first do a "Get Specific Version" set it to changeset and put in 1. This will then remove all the files from your local workspace (for that project, folder, file, etc) and it will also have TFS update so that it knows you now have NO VERSION DOWNLOADED. You can then do a "Get Latest" and viola, you will actually have the latest
I had the same issue with Visual Studio 2012. No matter what I did, it didn't get the code from TFS source control.
In my case, the cause was mappings a folder + subfolder from the source control separately but to the same tree in my local HD.
The solution was removing the subfolder mapping using the "manage workspaces" window.
Most of the issues I've seen with developers complaining that Get Latest doesn't do what they expect stem from the fact that they're performing a Get Latest from Solution Explorer rather than from Source Control Explorer. Solution Explorer only gets the files that are part of the solution and ignores anything that may be required by files within the solution, and therefore part of source control, whereas Source Control explorer compares your local workspace against the repository on the server to determine which files are needed.
It could happen when you use TFS from two different machines with the same account, if so you should compare to see changed files and check out them then get latest then undo pending changes to remove checkout
This worked for me:
1. Exit Visual Studio
2. Open a command window and navigate to the folder: "%localappdata%\Local\Microsoft\Team Foundation\"
3. Navigate to the sub folders for every version and delete the sub folder "cache" and its contents
4. Restart Visual Studio and connect to TFS.
5. Test the Get Latest Version.
In my case, Get specific version, even checking both check boxes and undoing all pending changes didn't work.
Checked the work spaces. Edit current workspace. Check all paths.
The solution path was incorrect and was pointing to a deleted folder.
Fixed the path and get latest worked fine.
Every time this happens to me (so far) is because I have local edits pending on the .csproj project file. That file seems to keep a list of all the files included in the project. Any new files added by somebody else are "not downloaded" because they are not in my locally edited (now stale) project file. To get all the files I first have to undo pending changes to the .csproj file first then "get all". I do not have to undo other changes I have made, but I may have to go back and include my new files again (and then the next guy gets the same problem when he tries to "get all"...)
It seems to me there is some fundamental kludginess when multiple people are adding new files at the same time.
(this is in .Net Framework projects, maybe the other frameworks like Core behave differently)
just want to add TFS MSBuild does not support special characters on folders i.e. "#"
i had experienced in the past where one of our project folders named as External#Project1
we created a TFS Build definition to run a custom msbuild file then the workspace folder is not getting any contents at the External#Project1 folder during workspace get latest. It seems that tfs get is failing but does not show any error.
after some trial and error and renaming the folder to _Project1. voila we got files on the the folder (_Project1).
Tool:
TFS Power Tools
Source:
http://dennymichael.net/2013/03/19/tfs-scorch/
Command:
tfpt scorch /recursive /deletes C:\LocationOfWorkspaceOrFolder
This will bring up a dialog box that will ask you to Delete or Download a list of files. Select or Unselect the files accordingly and press ok. Appearance in Grid (CheckBox, FileName, FileAction, FilePath)
Cause:
TFS will only compare against items in the workspace. If alterations were made outside of the workspace TFS will be unaware of them.
Hopefully someone finds this useful. I found this post after deleting a handful of folders in varying locations. Not remembering which folders I deleted excluded the usual Force Get/Replace option I would have used.
I encountered the same problem:
My development server was corrupted and restored, but the information restored was from a few days ago.
TFS was updated that all the files are up to date, but in practice my files were correct a few days ago!
Nothing I did helped. get latest did not get the latest version.
At the end I got specific varision from a month ago. my files were updated accordingly, and then I did get latest.
And it worked. the files have been updated.

Team Foundation Server Testing

Let's say I have my TFS team project setup the way I want it, and all the code between my machine and the team project is in sync (i.e. if I do a get latest it says everything is up to date).
What I would like to do is test whether or not I can pull the project back down to my local machine from TFS source control have everything work properly. By work properly, I mean I'm able to build all the projects, run the web sites, etc.
I thought what I could do is just blow away the code on my local machine and then do a get latest. But TFS seems to think that my local machine and TFS are still in sync (this is a bit different from the way Visual Source Safe worked).
In a nutshell, I'm just trying to test whether or not if another developer were to pull this team project down to their machine, that I know the project is setup correctly with all the necessary dependencies, etc. such that the other developer could build and run the project. But since I only have one machine to test this with currently, I need to do this test on the same machine.
The only way I've found to do it is to use "Get specific version" and force it to overwrite existing files, but it seems like if I delete the stuff off my hard drive, it should know when I do a get latest that "hey, the files aren't there anymore, I need to pull them down".
Any ideas on how I can do this? Thanks.
Not withstanding the answer above highlighting the merits of having an automated build process and continuous integration...
The easiest way to validate what you've checked-in is to create a new workspace with the same folder mappings, albeit to a different location on your hard-drive. You can then 'Get Latest' into this new workspace and confirm that everything builds locally, this should prove that:
The correct versions of existing files are in source control
All the required files have actually been added to source control
Alternatively if you'd rather not check-in your changes until you've validated your pending changes, then your best bet is to 'Shelve' all your changes (ticking the box to undo your pending changes), and then 'Unshelve' that shelveset into a new Workspace and do your testing against that instance of the codebase... or even ask a colleague to pull down your shelveset and do the validation (typically this called a 'Buddy Build').
TFS is a little different that VSS in that local workspaces are maintained so that every file doesn't have to be compared with every GET. In addition to removing the code from your development machine, you should also delete your local workspace. Check out "Working with Version Control Workspaces" on MSDN:
http://msdn.microsoft.com/en-us/library/ms181383.aspx
Really, though, the best way to make sure that your code can be pulled down and built easily is to create an automated build in TFS for continuous integration. That way you know immediately if you have done something that would make the solution un-buildable.
Check out the overviews of Team Foundation Build on MSDN:
http://msdn.microsoft.com/en-us/library/ms181710.aspx
The answers above are good. Except it will not completely test you entire scenario. If you have references outside of your solution (such as dll in the GAC, or dll from an SDK installed on your machine), creating a new workspace or deleting and getting latest code won't found those problems.
The only way to make sure is to pull down the code on another computer. If you don't have another computer handy, you can use a Virtual machine.
Do Get Specific Version and specify the latest. This will force TFS to download everything, ignoring the current synchronisation status.
TFS uses your workspace to know what is synched between the server and local.
I don't think there is an option to make Get Latest to behave like you want (Get Specific Version and specifying Latest Version and Overwrite).

Resources