Querying for agent running a build - c#

I am trying to query which agents are currently running a build using the TFS Extended Client. This is for the new TFS 2015 (non-XAML) build system.
I can easily query currently running builds with the code below, but I can not see any way to access details of the agent running the build. Neither the properties of the Build type or any of the BuildHttpClient methods appear to expose this.
Is there any way to achieve this?
VssConnection connection = new VssConnection(new Uri("TfsUri"), new VssAadCredential());
var buildClient = connection.GetClient<BuildHttpClient>();
var builds = await buildClient.GetBuildsAsync(
statusFilter: BuildStatus.InProgress,
project:"project"
);
foreach (var build in builds)
{
var buildNumber = build.BuildNumber;
var buildQueue = build.Queue;
//How to query for agent executing build?
}

You can potentially use the workername property contained in the build's timeline record as an identification mechanism for the agent.
The agent's worker name typically matches the agent name when added to a queue.
To access this detail of the build via the api you're using; I tested against builds that have already completed and builds in progress, this detail was populated already at the point of execution, you may want to do additional object reference validity checking in case a worker has not yet been assigned to the specified build.
None the less here is the foreach loop from your snippet modified to include a lookup of the worker name using the build's timeline records.
foreach (var build in builds)
{
var buildNumber = build.BuildNumber;
var buildQueue = build.Queue;
//How to query for agent executing build? ... Perhaps use the the worker name
var buildDetail = await buildClient.GetBuildTimelineAsync(build.Project.Id, build.Id);
var workerName = (string.IsNullOrEmpty(buildDetail.Records.Select(x => x.WorkerName).First())) ? "WORKER NOT INDICATED" : buildDetail.Records.Select(x => x.WorkerName).First();
}

Related

Octopus client, getting version from project name in C#

First of, I am completely new to octopus client, used it for the first time just before posting this.
So, I've been landed with this project to update the version number on a webpage monitoring some of our octopus deployed projects. I have been looking around the octopus client and not really gotten anywhere. The best I have so far is:
OctopusServerEndpoint endPoint = new OctopusServerEndpoint(server, apiKey);
OctopusRepository repo = new OctopusRepository(endPoint);
var releases = repo.Releases.FindAll();
From these releases I can get the ProjectId and even the Version, the issue is that releases is 600 strong and I am only looking for 15 of them.
The existing code I have to work from used to parse the version from local files so that is all out the window. Also, the existing code only deals with the actual names of the projects, like "AWOBridge", not their ProjectId, which is "Projects-27".
Right now my only option is to manually write up a keyList or map to correlate the names I have with the IDs in the octopus client, which I of course rather not since it is not very extendable or good code practice in my opinion.
So if anyone has any idea on how to use the names directly with octopus client and get the version number from that I would very much appriciate it.
I'll be getting down into octopus client while waiting. Let's see if I beat you to it!
Guess I beat you to it!
I'll just leave an answer here if anyone ever has the same problem.
I ended up using the dashboardto get what I needed:
OctopusServerEndpoint endPoint = new OctopusServerEndpoint(server, apiKey);
OctopusRepository repo = new OctopusRepository(endPoint);
DashboardResource dash = repo.Dashboards.GetDashboard();
List<DashboardItemResource> items = dash.Items;
DashboardItemResource item = new DashboardItemResource();
List<DashboardProjectResource> projs = dash.Projects;
var projID = projs.Find(x => x.Name == projectName).Id;
item = items.Find(x => x.ProjectId == projID && x.IsCurrent == true);
The dashboard is great since it contains all the info that the web dashboard shows. So you can use Project, Release, Deployment and Environment with all the information they contain.
Hope this helps someone in the future!
I'm using LINQPad to run C# snippets for Octopus automation using the Octopus Client library and I have come up with following to get any version of a project making use of Regular expression pattern. It works quite well if you use Pre-release semantic versioning.
For example to get latest release for a project:
var project = Repo.Projects.FindByName("MyProjectName");
var release = GetReleaseForProject(project);
To get specific release use that has 'rc1' in the version for example (also useful if you use source code branch name in the version published to Octopus:
var release = GetReleaseForProject(project, "rc1");
public ReleaseResource GetReleaseForProject(ProjectResource project, string versionPattern = "")
{
// create compiled regex expression to use for search
var regex = new Regex(versionPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
var releases = Repo.Projects.GetReleases(project);
if (!string.IsNullOrWhiteSpace(versionPattern) && !releases.Items.Any(r => regex.IsMatch(r.Version)))
{
return null;
}
return (!string.IsNullOrWhiteSpace(versionPattern)) ? releases.Items.Where(r => regex.IsMatch(r.Version))?.First() : releases.Items?.First();;
}

SharePoint Event Reciever Works On One Machine/computer/user

So we have created an updated version of a WSP for SharePoint 2010 due to our migration/update from 2007 to 2010.
The WSP is a event handler/reciever for ItemAdded() and we have it working as intended. Issue is that the operation seems to only work for one computer/machine and no others.
When the Item is Added to a list the WSP creates a Folder in Shared Documents library, creates a wiki page, then updates the new List Item with links to the Shared Doc and Wiki.
When triggered by Machine #1 and User #1 all operations work, when Machine #2(M2) and user #2(U2) or M3 and U3 non of the tasks take place when a new Item is created.
User #2 can log in on M1 and create a new item and all operations work. But if U1 uses M2 or M3 to create an item the events don't trigger. Machine #1 is able to trigger the event as many times as they want but no other computer is able to.
If you were able to follow is it something with the code or some sort of cache setting on the local machine or the SP server, or something else? Any help is appreciated.
Update: All machines are on the same network. Non of the machines are the server but various personal laptops. Development was done on a separate machine. All are accessing via the same URL. All users have same access. This is on our test site currently which would be switched to being production once migration/upgrade takes place.
Before current .WSP deployment we noticed the same issue but it was reverse, Machine #2 did all the updates but Machine #1 and #3 couldn't. Only thing we can think of was that those machines were the first to trigger the event after deployment.
I'm Not doing the .WSP install but our IT guy is(won't let us have access :/ but I understand) but below is the install commands he is running.
Add-SPSolution -LiteralPath "OurPath/ourFile.wsp"
Install-SPSolution -Identity ourIdentity -WebApplication http://myhost.com/ -GACDeployment
Below is the main part of the code
public class CreateWikiAndFolder : Microsoft.SharePoint.SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
//this.DisableEventFiring();
base.EventFiringEnabled = false;
string sUrlOfWikiPage = string.Empty;
string sUrlOfNewFolder = string.Empty;
string sSubsiteRUL = string.Empty;
string sCurrentItemTitle = properties.ListItem["Title"].ToString();
string sWikiListName = "TR Wikis";
string sDocLibName = "Shared Documents";
string sTRListID = "TR Status";
if (sTRListID.ToUpper().Equals(properties.ListTitle.ToString().ToUpper()))
{
//Create the Folder
sUrlOfNewFolder = CreateFolder(properties.ListItem.Web, sDocLibName, sCurrentItemTitle);
//Create the Wiki
string ItemDispFormUrl = String.Concat(properties.ListItem.Web.Url, "/", properties.ListItem.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, "?ID=", properties.ListItem.ID.ToString());
sUrlOfWikiPage = CreateWiki(properties.ListItem.Web, sWikiListName, sCurrentItemTitle, ItemDispFormUrl, sUrlOfNewFolder);
//Update the current TR Item
SPWeb myWeb = properties.ListItem.Web;
myWeb.AllowUnsafeUpdates = true;
SPListItem myListItem = properties.ListItem;
SPFieldUrlValue shareFolderURLValue = new SPFieldUrlValue();
shareFolderURLValue.Description = "Shared Folder";
shareFolderURLValue.Url = sUrlOfNewFolder ;
myListItem["SharedFolder"] = shareFolderURLValue;
myListItem.Update();
myWeb.AllowUnsafeUpdates = false;
}
base.EventFiringEnabled = true;
}
catch (Exception e)
{
//Currently throwing nothing
}
}
}
It could be a hardcoded path/url, however there is not enough information to identify the problem, I would be glad to update my answer with a more detailed theory if you provide more details or if you share some of your code.
Figured out the issue. I didn't include them with the above file code. But we were StreamWriting to a text file on the server to help us with debugging. Issue was with that, When user 1 was logged on their machine and the log files didn't exist, they would get generated. Now no other users then had read/write access to those files and so it errored out at our debug files for anyone else. But that Windows user could run it as much as they wanted as they were the owner of the file :/

TFS can't find BuildDefinition

I am working on a solution where I want to get parameters from a Builddefinition per Code. When I hit it, I get an error message "No build definition was found for
team project ToyStory with name Spass-mit-Flaggen."
The used code is written below:
var tfsCreds = new TfsClientCredentials(new WindowsCredential(), false);
var tpc = new TfsTeamProjectCollection(new Uri(options.CollectionUri), tfsCreds);
var buildServer = (IBuildServer)tpc.GetService(typeof(IBuildServer));
var buildDetail = buildServer.GetBuild(new Uri(options.BuildUri));
var buildDefinition = buildServer.GetBuildDefinition(
buildDetail.TeamProject,
options.BuildDefinition);
The options object contains all program parameters. In this case they are the following strings:
options.CollectionUri == "http://tfs-test:8080/tfs/Test/"
options.BuildUri == "vstfs:///Build/Build/85"
options.BuildDefiniton == "Spass-mit-Flaggen"
Has someone an idea what's going wrong here?
Thanks in advance
You're using the old SOAP API for accessing builds. The new build system introduced in TFS 2015 doesn't use SOAP messaging, it has a totally separate REST API. You'll need to use the REST API, available in easily-consumable object model form on NuGet.

Get build and changeset number from Team Foundation Server

I have been given a task to use the TFS API in order to check which build has which changeset number, after deployment. I haven't worked with TFS before, so mainly I've been trying to Google things, to find the answer. I've been at it for 2 days now, so I'm hoping someone can nudge me in the right direction...
Here is what I have done so far:
Uri collectionUri = new Uri("mytfs/tfs/");
var server = TfsConfigurationServerFactory.GetConfigurationServer(collectionUri);
server.Authenticate();
server.EnsureAuthenticated();
var service = server.GetService<TswaClientHyperlinkService>();
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("mytfs/tfs/collection"));
var cssService = projectCollection.GetService<ICommonStructureService3>();
var project = cssService.GetProjectFromName("project");
WorkItemStore workItemStore = projectCollection.GetService<WorkItemStore>();
WorkItemCollection workItemCollection = workItemStore.Query("SELECT * FROM WorkItems");
So in the workItemCollection object, I tried a few queries, but it seems it doesn't allow me to change database, use joins etc. just a simple select/from statement.
Am I on the right track - is this how I should be getting build and changeset number?? If yes, where can I see what tables I need to query?
The problem here is that you're thinking of this as a database. It's not a database. It's an object model that allows you to programmatically access various aspects of TFS through a well-defined API.
Work item queries are not SQL, they are WIQL (work item query language). The work item object will definitely have a link to the associated changeset, but it won't have a link to a build. Some work item types have a field for "fixed in" that will be automatically updated with the build, but not all of them, so it's not necessarily reliable.
To find particular builds, you'll need to use the IBuildServer service and search for a build spec.

How to use libgit2sharp to create a new branch from local to remote?

I want to create and delete a branch on git using libgit2sharp. I came up with this code but it throws an error at repo.Network.Push(localBranch, pushOptions);
using (var repo = new Repository(GIT_PATH))
{
var branch = repo.CreateBranch(branchName);
var localBranch = repo.Branches[branchName];
//repo.Index.Stage(GIT_PATH);
repo.Checkout(localBranch);
repo.Commit("Commiting at " + DateTime.Now);
var pushOptions = new PushOptions() { Credentials = credentials };
repo.Network.Push(localBranch, pushOptions); // error
branch = repo.Branches["origin/master"];
repo.Network.Push(branch, pushOptions);
}
The error message is The branch 'buggy-3' ("refs/heads/buggy-3") that you are trying to push does not track an upstream branch.
I tried searching this error on the internet but no solution that I found could fix the problem. Is it possible to do this using libgit2sharp?
You have to associate your local branch with a remote against which you'd like to push.
For instance, given an already existing "origin" remote:
Remote remote = repo.Network.Remotes["origin"];
// The local branch "buggy-3" will track a branch also named "buggy-3"
// in the repository pointed at by "origin"
repo.Branches.Update(localBranch,
b => b.Remote = remote.Name,
b => b.UpstreamBranch = localBranch.CanonicalName);
// Thus Push will know where to push this branch (eg. the remote)
// and which branch it should target in the target repository
repo.Network.Push(localBranch, pushOptions);
// Do some stuff
....
// One can call Push() again without having to configure the branch
// as everything has already been persisted in the repository config file
repo.Network.Push(localBranch, pushOptions);
Note:: Push() exposes other overloads that allow you to dynamically provide such information without storing it in the config.

Categories

Resources