Best practice for bumping your version number in an automated build system? - tfs

My build system (Team Foundation Server 2015) does the following:
Get latest
Un-shelve developer changes
Check-out version file
Modify version file
Check-in modified version file
Run build/unit test
Check-in developer changes (on successful build/test run)
My issue with this method is that the build agent is modifying a file and checking that change in. To me this feels dirty.
So is there a better way of doing this, is this really best practice?

In my opinion, it's better to put version information in a version control system, not in a file. I haven't worked with TFS, but in my work I use Git and put version information in git tags. Using the git describe command you can get the information about the latest tag, a number of commits since the last tag and hash of the last commit. It also can provide you with information about uncommitted changes in your working copy.
All this information gives you the ability to distinguish one version of a binary from another.
And you don't have to create meaningless commits inside your repository.

Related

How to reproduce old/previous builds in TFS Build?

Environment:
TFS 2018 with source code in TFS Git
developers are using gitflow-like workflow (main, develop and short-lived feature branches)
there is a build definition used for CI (off of develop branch)
... and another one for releases (off of main branch)
as project evolves build definitions get updated (new steps, etc)
What is the best approach that allows reproduction of previous builds (or, at minimum, release builds)? (in case if previously made build was lost in boating accident)
Ideally I need to be able to plug in version (e.g. 8.5.12345.1) somewhere, press OK and eventually receive data identical to that produced by corresponding build in the past.
Your best approach is to switch to YAML builds and releases. That way your pipeline is versioned together with the code.
If you don't do that, you may need to clone your build and releases every time you make breaking changes.
Alternatively, use the version diff view in your pipeline to go back to an older version or use the json to create a new definition using the API.
Upgrading to Azure DevOps Servers 2020 will give you more advanced YAML features not yet available in Team Foundation Server 2018.
Note: for truly reproducible builds, you'll need to also find a way to lock the build tasks themselves, TFS and Azure DevOps will automatically roll forward to the latest minor version of a given build task. While task authors should try to prevent any breaking changes in those minor upgrades there are no guarantees. You can also never rely on any tool installers that use a v2.x notation or a task that relies on latest. Azure DevOps isn't ideally suited for full reproducible builds.
You can pin task versions in YAML now, if I remember correctly, this was added in Azure DevOps 2020.
You can set which minor version gets used by specifying the full version number of a task after the # sign (example: GoTool#0.3.1). You can only use task versions that exist for your organization.
See: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/tasks?view=azure-devops&tabs=yaml#task-versions
The Tasks docs offer special scripts to pin the versions of out-of-the-box tasks as well.

TFS 2017 Build Numbering

We have upgraded from TFS 2013 to TFS 2017, One feature we are trying to implement that we had in 2013 was the ability to have a custom build number. the previous method we had a file called BuildVersion.XML which during the first build step would read the major,minor, and revision and name the build with that build number + 1 on the revision. It would then change then checkout and update the revison number and check in the new version. I know that there are steps where people update the AssemblyInfo. The issue is that not all our code is .net apps. we also now have SSIS Packages, Cordova iOS/android apps, angular sites, aws Lambda functions with node.js which do not have the concept of AssemblyInfo. is there an easy way to implement this?
You can do exactly the same thing in Team Build in TFS 2017.
You can update the build number from any task by calling:
Write-Verbose -Verbose "##vso[build.updatebuildnumber]1.2.3.4"
Add a PowerShell task and add an inline script to read from your file and update the build number with the above.
You can then have additional scripts that use the build number any way you need to version your application.
You can see the full list of logging commands here
https://github.com/Microsoft/vso-agent-tasks/blob/master/docs/authoring/commands.md
You can use my VSTS TFVC tasks to interact with source control, though I do not recommend it. I built these tasks for clients of mine who were doing exactly what you are doing.
Instead of relying on a file in source control it would be a much better solution to pass the BuildNumber from the Build Definition along to the build, have one of your first steps update the files on disk with the correct version number then run your build.
If you manipulate files during the build and check them in you run the risk of inconsistent numbering when you scale up to multiple build agents, it's hard to use in combination with parallel builds and build variable multiplexing and it becomes notoriously hard to do Gated Checkins and Shelveset builds. Plus, it limits your options to move to Git in the future.

Using Mercurial locally with TFS Team Foundation Version Control Server Workspace

At work we are using TFS Team Foundation Version Control (TFVC) and the workspace is a server workspace (very large codebase). The limitations of our setup are that files checked out are locked for edit by other people. Also there is a culture of not committing until work is complete etc as many change-sets complicate merging later.
I am in no position to change the global rules or culture. I would like to locally setup a mercurial (hg) repo on my local machine. The idea is that I can work on my local copy make as many checkins to hg. When I am done I would like to bundle my changes into one changeset and send it off to the TFS location (also on my local machine). Then immediately checkin the changes to TFS server.
That way to the outside world I appear to checkout and then immediately checkin all of my code, only briefly locking the files changed. But locally in hg I get the full ability to make small checkins and work without worrying about locking files out for edit.
Somehow chain two version control systems, giving me the flexibility of HG locally, but continue using the global TFVC for final checkins.
Any ideas on how this could be achieved?
You can use git-tf and the hg-git. This was an intentional design decision when we built git-tf that this was a supported scenario.
That said... this seems a bit... icky.
You may want to write a few shell scripts to make this workflow a little bit easier.
But even with that, it's hard to imagine troubleshooting this when something inevitably goes wrong.
TFS doesn't have Mercurial support, but apparently does have Git support.
You can use the hg-git plugin to access TFS this way.
More details about the lack of support:
https://hglabhq.com/blog/2014/1/17/mercurial-support-in-tfs-declined
https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3607357-add-mercurial-support-to-team-foundation-server

How to perform the Build in TFS2010? What is the Logic should we adopt and How to get a files from TFS 2010?

Currently we are using StarTeam to perform the build as well as versioning. we planned to migrate startteam to TFS2010. We have some script for perform the build. i wanted to change this script according to my requirement. i gone through the TFS but i had lot more confusion.
in StarTeam, we will get a files from "Ready to Build" label and perform the build. In TFS, how we are going to get a files from TFS? What concept should i use to get a files and perform the build? i have gone through the lot of commands like get, check-in, checkout etc..
If we use "tf get" command, we can get all the files from TFS but i have a clarification on that. shall i get all the files from TFS for every build? i hope, this is unnecessary headache.. correct me if i am wrong..
how we perform the build in TFS? i have read some types of build such as manual, gatedcheckin, Continuous Integration and schedule.
Is there any relationship between branch and build activities?
In TFS, What is the meaning of Workspace?
As said, many questions in one. Hope this helps along the way:
A workspace is a mapping between the server and a local storage,
similar to checkout in Subversion, view in ClearCase, etc.
"TF get" normally only fetches those files that have changed since
last update. You can force it to fetch everything - and sometimes
have to - but its not normally done.
Team Build is the recommended system to build with when using TFS. It can take some time to get into (Windows Workflow-based), but is quite powerful. There are default process definitions that set up the most common actions for you.
By default, you can't control whether to build by setting a certain label, but you can define that only this label should be used when builds are triggered. Labels in TFS work a little differently compared to other VCS, though, so maybe there's an 'opportunity' to re-think your build process along the way. If you're set on using a label as before, you'll need to build a Custom build activity.

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