Our TFS 2010 server has stopped associating change sets with builds and i cant for the life of me figure out why.
All the current builds are in a status of 'Build Succeeded'
the build definition has both the 'associate changesets and work items' and 'label sources' set to true.
The build goes through just fine
I've checked ...
the source control history for the solutions and they all have labels assigned associated with the build number
the diagnostic version of the log shows...
Final Property Values
AgentSettings = Use agent where Name=* and Tags is empty; Max Wait Time: 04:00:00
AssociateChangesetsAndWorkItems = True
BuildNumberFormat = IQ_$(Date:yyyyMMdd)$(Rev:.r)
BuildSettings = Build 2 project(s) for 1 platform(s) and configuration(s)
CleanWorkspace = All
CreateLabel = True
CreateTriggerFileList = False
CustomArguments =
and no errors relating to labels that i can see.
I've tried...
deleting the build definition and setting it up again
Any help would be appreciated, I'm just not sure where to start looking next.
Thanks
Aidan
Aidan,
You should be looking for the following item in your workflow template:
Make sure that this has not been tampered with, and if it has, correct the changes. As others have said, check the history in source control for the workflow template file.
Related
First off the setup in question:
A Jenkins Instance with several build nodes and on prem Azure-Devops server containing the Git Repositories.
The Repo in question is too large to always build on push for all branches and all devs, so a small workaround was done:
The production branches have a polling enabled twice a day (because of testing duration which is handled downstream more builds would not help with quality)
All other branches have their automated building suppressed. They still can start it manually for Builds/Deployments/Unittests if they so choose.
The jenkinsfile has parameterization for which platforms to build, on prod* all the platforms are true, on all other branches false.
This helps because else the initial build of a feature branch would always build/deploy locally all platforms which would take too much of a load on the server infrastructure.
I added a service endpoint for Jenkins in the Azure Devops, added a Buildvalidation .yml - this basically works because when I call the sourcebranch of the pull request with the merge commitID i added a parameter
isPullRequestBuild which contains the ID of the PR.
snippet of the yml:
- task: JenkinsQueueJob#2
inputs:
serverEndpoint: 'MyServerEndpoint'
jobName: 'MyJob'
isMultibranchJob: true
captureConsole: true
capturePipeline: true
isParameterizedJob: true
multibranchPipelineBranch: $(System.PullRequest.SourceBranch)
jobParameters: |
stepsToPerform=Build
runUnittest=true
pullRequestID=$(System.PullRequest.PullRequestId)
Snippet of the Jenkinsfile:
def isPullRequest = false
if ( params.pullRequestID?.trim() )
{
isPullRequest = true
//do stuff to change how the pipeline should react.
}
In the jenkinsfile I look whether the parameter is not empty and reset the platforms to build to basically all and to run the unittests.
The problem is: if the branch has never run, Jenkins does not already know the parameter in the first run, so it is ignored, building nothing, and returning with 0 because "nothing had to be done".
Is there any way to only run the jenkins build if it hasnt run already?
Or is it possible to get information from the remote call if this was the build with ID 1?
The only other thing would be to Call the Jenkins via web api and check for the last successful build, but in that case I would have have the token somewhere stored in source control.
Am I missing something obvious here? I dont want to trigger the feature branch builds to do nothing more than once, because Devs could lose useful information about their started builds/deployments.
Any ideas appreciated
To whom it may concern with similar problems:
In the end I used the following workaround:
The Jenkins Endpoint is called via a user that only is used for automated builds. So, in case that this user triggered the build, I set everything to run a Pull Request Validation, even if it is the first build. Along the lines of
def causes = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
if (causes != null)
{
def buildCauses= readJSON text: currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause').toString()
buildCauses.each
{
buildCause ->
if (buildCause['userId'] == "theNameOfMyBuildUser")
{
triggeredByAzureDevops = true
}
}
}
getBuildcauses must be allowed to run by a Jenkins Admin for that to work.
TFS 2012
VS 2012
I have large number of Build Definitions that are derived from single template.
I also have a Master Build to queue all those builds and pass arguments if I need to do so.
That part was done using TFS Community Extension: QueueBuilds.
Problem:
Is there a way to access Build Definitions, loop through them, (can get up to here by myself) and change their ProcessParameters and save them.
You can use the Microsoft.TeamFoundation.Build.Client and related assemblies to update the process parameters via PowerShell or C#. The one tricky part is the parameters are stored in XML so you have to deserialize, make your changes, then serialize again to set them.
This likely won't run without some tweaking but here are some snippets from one of my scripts that will help:
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Build.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Build.Workflow')
$projectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($TFSUri)
$buildServer = $projectCollection.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer]) $buildServer = GetBuildServer -TFSUri $TFSUri
$buildDefinition = $buildServer.GetBuildDefinition($TeamProjectName, $BuildName);
...
$parameters = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::DeserializeProcessParameters($buildDefinition.ProcessParameters)
$msBuildArguments = $parameters.Get_Item("MSBuildArguments")
$msBuildArguments = "$msBuildArguments /p:ImportParametersFilesOverride=true"
$parameters.Set_Item("MSBuildArguments", $msBuildArguments)
$parameters.Add("GetVersion", "c$TFSChangeSetNumber")
$buildRequest.ProcessParameters = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::SerializeProcessParameters($parameters)
I'm used to working with TeamCity so it might be that I should completely change my workflow, in that case answer with a suggestion of a new workflow instead.
In TeamCity I usually build and run unit tests as one build task (at every commit). Longer running tests are scheduled nightly and are run in the same way. So far I've manged to replicate the process in TFS. But on top of this I have a build task to deploy/publish a package. This is something I start manually once we are ready for it. This script references the artifact from a previous build (i.e. a drop folder or a drop zip in TFS).
I've read this article about deployment scripts but I can't find any information about how I can trigger them in TFS.
So the question in short: How do I reference a "drop as zip" or a drop folder instead of the source when building in TFS?
You can "Get Specific Build" or the "Latest Successful Build" on a specific Build, and then you can refer to that build's drop location.
Using TFS API, getting latest one should look something like this:
using (TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfsserver:8080/tfs/DefaultCollection")))
{
var buildServer= tpc.GetService<IBuildServer>();
var buildSpec = buildServer.CreateBuildDetailSpec(teamProjectName, buildDefinition);
buildSpec.InformationTypes = null;
buildSpec.MinFinishTime = DateTime.Now.AddHours(-lastXHours);
buildSpec.MaxBuildsPerDefinition = 1;
buildSpec.QueryOrder = Microsoft.TeamFoundation.Build.Client.BuildQueryOrder.FinishTimeDescending;
buildSpec.Status=Microsoft.TeamFoundation.Build.Client.BuildStatus.Succeeded;
var buildDetails = buildServer.QueryBuilds(buildSpec).Builds;
if (buildDetails.Length ==1){var dropLocation= buildDetails[0].DropLocation; }
else { Console.WriteLine("No builds found." );}
}
I am building a VS2010 addin. This addin will work only for our custom project types and create a menu item that will copy the output assembly from the current solution to another solution. Both are under TFS control.
I have the following code:
var tfs = new TeamFoundationServer(address);
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace(System.Net.Dns.GetHostName().ToString(), version.AuthorizedUser);
workspace.PendEdit(dest);
System.IO.File.Copy(source, dest, true);
Now I want to checkin the change. The problem is that I don't know how to select only that file I checked out just now? I have other pending changes in the same project and also in other projects. Will this checkin EVERYTHING I have checked out?
Can I be more selective?
PendingChange[] pendingChange = workSpace.GetPendingChanges(dest);
workSpace.CheckIn(pendingChange, comments);
Workspace.GetPendingChanges Method (String)
http://msdn.microsoft.com/en-us/library/bb139277(v=vs.100).aspx
Parameters
item: The path, local or server, to the item that is being queried.
And
Workspace.CheckIn Method
http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.workspace.checkin(v=vs.100).aspx
Parameters
changes
The set of pending changes to check in. If you do not specify this parameter, all changes in the workspace are checked in.
comment
The comment to be associated with this check-in. May be null.
In order to retrieve the information which Changeset was included in which Build, we use "Label Sidekick" of Team Foundation Sidekicks, where we place the Label of the Build & expect to find the newly built Changeset.
Our development process in TFS 2010 is making use of 'Gated' checkins, so we are faced with the situation that the latest checkins are not presented in Sidekicks (we actually receive the changeset of the previous build). This is explainable, since at the time the labeling takes place, the latest changes have not yet been committed.
The BuildLog does report the associated Changeset correctly.
I 've made several experiments in our Build Process Template but can't seem to get what we need.
Placing, for example, the Labeling activity out of the "Run On Agent" scope, lead me to a build that fails at the very start with an "Object reference not set to an instance of an object." (I suppose this is related with fact I had to widen the scope for 'Label' & 'Workspace' variables to get the second part running).
The 'before' state of the build process template for this attempt is here (this works), the 'after' state ("Object ref not set..") is here.
So, to summarize, two different types of input could help me out:
How should I change our build process template so that the labeling happens after the Gated checkins have been committed? (-- This would rationalize the display in Sidekicks)
or
How can I programmatically retrieve the associated Changeset of each Build? (-- This would enable me to write a small app that could obsolete the Sidekicks angle)
You can use the TFS API to get this done.
public static void GetBuild()
{
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfsdevlonuk:8080/tfs/gazprom.mt"), new UICredentialsProvider());
tfs.EnsureAuthenticated();
var buildServer = tfs.GetService<IBuildServer>();
// Get Project Name
var versionControl = tfs.GetService<VersionControlServer>();
var teamProjects = versionControl.GetAllTeamProjects(true);
// Get Builds for a team project
var buildDetails = buildServer.QueryBuilds(teamProjects[0].Name);
// For each build
foreach (IBuildDetail buildDetail in buildDetails)
{
// Get the build details
var buildInfor = buildDetail.Information;
// More build infor like shelveset, etc
Debug.Write(buildDetail.LabelName + buildDetail.ShelvesetName);
}
The above code will help you get the build details programatically. I have some blog posts on how to connect to tfs programmatically and use the tfs api. http://geekswithblogs.net/TarunArora/archive/2011/06/18/tfs-2010-sdk-connecting-to-tfs-2010-programmaticallyndashpart-1.aspx