private void Server_OnProjectsUpdated(object sender, BuildQueryEventArgs e) { if (e == null) { return; } Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { TeamProject project = sender as TeamProject; if (project != null) { lock (buildContent) { //Get current build item list Dictionary<string, BuildDetail> currentBuilds = new Dictionary<string, BuildDetail>(); foreach (BuildDetail item in buildContent) { currentBuilds.Add(item.BuildDefinitionUri, item); } //Get updated builds var query = from buildQueryItem in e.BuildQueryResults where buildQueryItem.Builds.Count() > 0 orderby buildQueryItem.Builds[0].BuildNumber select buildQueryItem; foreach (BuildQueryResult buildQuery in query) { foreach (BuildDetail item in buildQuery.Builds) { //If the item doesnt exist or needs updating if ((currentBuilds.ContainsKey(item.BuildDefinitionUri) && (buildUpdates[item.BuildDefinitionUri] < item.LastChangedOn)) || (!currentBuilds.ContainsKey(item.BuildDefinitionUri))) { //Update the last time if (buildUpdates.ContainsKey(item.BuildDefinitionUri)) { buildUpdates[item.BuildDefinitionUri] = item.LastChangedOn; } else { buildUpdates.Add(item.BuildDefinitionUri, item.LastChangedOn); } //Add if doesn't exist if (!currentBuilds.ContainsKey(item.BuildDefinitionUri)) { currentBuilds.Add(item.BuildDefinitionUri, item); buildContent.Add(item); //Add to view if not hidden if (!HiddenBuilds.Contains(item.BuildDefinitionUri)) { buildContentView.Add(item); } } else //Update the item { currentBuilds[item.BuildDefinitionUri].Status = item.Status; currentBuilds[item.BuildDefinitionUri].RequestedFor = item.RequestedFor; currentBuilds[item.BuildDefinitionUri].LogLocation = item.LogLocation; } //If the icon is green and a build is failing, set it to red, only if visible if (!HiddenBuilds.Contains(item.BuildDefinitionUri)) { if ((currentIconColour != IconColour.Amber) && (item.Status == BuildStatus.Failed)) { SetIcon(IconColour.Red); } else if (currentIconColour == IconColour.Grey) { SetIcon(IconColour.Green); } } //Update the name to a friendly name foreach (TeamServer server in servers) { string buildName = server.GetDefinitionByUri(item.BuildDefinitionUri).GetFriendlyName(); if (!String.IsNullOrEmpty(buildName)) { currentBuilds[item.BuildDefinitionUri].BuildNumber = buildName; break; } } } } } } //Send alerts for changes AlertChanges(e); } })); }
private void AlertChanges(BuildQueryEventArgs buildQueryEventArgs) { bool iconChanged = false; IconColour mainIconColour = IconColour.Green; //Cleanup history CleanupIds(); //Find in progress builds foreach (BuildQueueQueryResult queueResult in buildQueryEventArgs.BuildQueueQueryResults) { //Check for cancelled builds IconColour? iconColour = CheckCancelledBuilds(queueResult); if (iconColour.HasValue) { mainIconColour = iconColour.Value; iconChanged = true; } //Loop through builds with active histories foreach (QueuedBuild build in queueResult.Builds.OrderBy(item => item.Id)) { //Check if build is hidden if (HiddenBuilds.Contains(build.BuildDefinitionUri)) { continue; } //Get the friendly names string buildName = GetFriendlyName(build.BuildDefinitionUri); //Adding builds while the tray is running can cause it to fail, only builds which have atleast 1 successfull build will be displayed. if (!String.IsNullOrEmpty(buildName)) { //Check if this is an "In Progress" status and has not been displayed before if ((!buildIdsAlertedInProgress.Contains(build.Id)) && (build.Status == QueueStatus.InProgress)) { StatusMessage message = new StatusMessage { EventDate = DateTime.Now, BuildStatus = IconColour.Amber, Message = String.Format(CultureInfo.CurrentUICulture, ResourcesMain.NotifierWindow_InProgress, build.RequestedBy, buildName) }; statusMessages.Enqueue(message); mainIconColour = IconColour.Amber; iconChanged = true; buildIdsAlertedInProgress.Add(build.Id); buildIdUris.Add(build.Id, build.BuildDefinitionUri); NotifyIconMainIcon.Text = ResourcesMain.MainWindow_Title + " - Building"; UpdateMainWindowItem(build.BuildDefinitionUri, BuildStatus.InProgress, build.RequestedBy); } //Check if this is an "Queued" status and has not been displayed before else if ((!buildIdsAlertedQueued.Contains(build.Id)) && (build.Status == QueueStatus.Queued)) { StatusMessage message = new StatusMessage { EventDate = DateTime.Now, BuildStatus = IconColour.Amber, Message = String.Format(CultureInfo.CurrentUICulture, ResourcesMain.NotifierWindow_Queued, build.RequestedBy, buildName) }; statusMessages.Enqueue(message); buildIdsAlertedQueued.Add(build.Id); }//Check if this is an "Completed" status and has not been displayed before else if ((!buildIdsAlertedDone.Contains(build.Id)) && (build.Status == QueueStatus.Completed)) { StatusMessage message = new StatusMessage { EventDate = DateTime.Now }; buildIdsAlertedInProgress.Remove(build.Id); buildIdUris.Remove(build.Id); //Get the status from the build log foreach (BuildDetail item in buildContent) { if (item.BuildDefinitionUri == build.BuildDefinitionUri) { switch (item.Status) { case BuildStatus.Succeeded: message.BuildStatus = IconColour.Green; message.Message = String.Format(CultureInfo.CurrentUICulture, ResourcesMain.NotifierWindow_BuildPassed, buildName); break; case BuildStatus.PartiallySucceeded: message.BuildStatus = IconColour.Red; message.Message = String.Format(CultureInfo.CurrentUICulture, ResourcesMain.NotifierWindow_BuildPartial, buildName); break; default: message.BuildStatus = IconColour.Red; message.Message = String.Format(CultureInfo.CurrentUICulture, ResourcesMain.NotifierWindow_FailedBuild, build.RequestedFor, buildName); break; } message.HyperlinkUri = new Uri(item.LogLocation); mainIconColour = message.BuildStatus; iconChanged = true; break; } } NotifyIconMainIcon.Text = ResourcesMain.MainWindow_Title; statusMessages.Enqueue(message); buildIdsAlertedDone.Add(build.Id); } } } } //Only pop up if new messages if (statusMessages.Count > 0) { lastStatusMessage = statusMessages.Dequeue(); MessageWindow.Show(lastStatusMessage, 3000); } //Only update the main icon if its a valid status change if (iconChanged) { SetIcon(mainIconColour); } }