private static async Task <Byte[]> GetImageDataAsync(BuildMonitorSettings settings, IUser user) { try { var response = await GetRequestResponseAsync(user.ImageUrl, settings).ConfigureAwait(false); if (response.IsSuccessStatusCode) { if (response.Content.Headers.ContentType.MediaType == "image/png") { return(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false)); } if (response.Content.Headers.ContentType.MediaType == "image/svg+xml") { using (var memoryStream = new MemoryStream()) { await response.Content.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; var svgDoc = SvgDocument.Open <SvgDocument>(memoryStream); var converter = new ImageConverter(); return((Byte[])converter.ConvertTo(svgDoc.Draw(128, 128), typeof(Byte[]))); } } } } catch (Exception) { return(null); } return(null); }
private void OnAddProvider(IIdentifierMetadata selectedProvider) { var providerid = selectedProvider.Id; var buildMonitorSettings = new BuildMonitorSettings(providerid); this.buildMonitorSettingsContainer.Add(buildMonitorSettings); AddView(providerid, buildMonitorSettings); }
public virtual void Initialize(BuildMonitorSettings settings) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } MonitorSettings = settings; OnInitialized(); }
private async Task ResolveAdditionalBuildDataAsync(BuildMonitorSettings settings, List <TBuild> data, String projectUrl) { data.Select(d => d.Definition).OfType <TBuildDefinition>().ToList().ForEach(d => d.BuildSettingsId = settings.UniqueId); await ResolveSourceVersionAsync(data, projectUrl, settings).ConfigureAwait(false); await ResolveArtifactsAsync(data, projectUrl, settings).ConfigureAwait(false); await ResolveTestRunsAsync(data, projectUrl, settings).ConfigureAwait(false); data.Select(d => d.DisplayUser).OfType <TUser>().ToList().ForEach(a => a.ImageDataLoader = GetImageDataAsync(settings, a)); }
private void AddView(String providerid, BuildMonitorSettings buildMonitorSettings) { var providerView = BuildProviderViews.GetSingleOrDefault(a => a.Id == providerid); if (providerView != null) { var view = providerView.CreateExport().Value; view.ViewModel.Initialize(buildMonitorSettings); Views.Add(view); } }
public void TestIfSavingAndLoadingWorks() { var tempFile = Path.GetTempFileName(); var settings = new BuildMonitorSettings(Guid.NewGuid().ToString()); settings.Add("Test1", "02fdb4e0-fa5d-472a-918a-fc02c48b11a8"); settings.Add("Test2", new List <String> { "Item1", "Item2" }); //settings.Add("Test3", new List<IBuildDefinition> { GetTestBuildDefinition(1), GetTestBuildDefinition(2) }); var container = new SettingsContainer <BuildMonitorSettings>(); container.Add(settings); container.Save(tempFile); var loadedContainer = SettingsContainer <BuildMonitorSettings> .Load(tempFile); Assert.IsNotNull(loadedContainer); Assert.AreEqual(container.Count, loadedContainer.Count); var loadedSettings = loadedContainer.Single(); Assert.IsNotNull(loadedSettings); Assert.AreEqual(settings.BuildProviderId, loadedSettings.BuildProviderId); Assert.AreEqual(settings.UniqueId, loadedSettings.UniqueId); Assert.AreEqual(settings.Count, loadedSettings.Count); foreach (var keyValuePair in settings) { var loadedValue = loadedSettings[keyValuePair.Key]; Assert.IsNotNull(loadedValue); var expected = keyValuePair.Value as ICollection; if (expected != null) { CollectionAssert.AreEqual(expected, loadedValue as ICollection); } else { Assert.AreEqual(keyValuePair.Value, loadedValue); } } }
public static void ThrowIfKeyNotExists(this BuildMonitorSettings settings, String key) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (String.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(nameof(key)); } if (!settings.ContainsKey(key)) { throw new KeyNotFoundException($"Required key {key} not found in settings!"); } }
private static async Task <TSourceVersion> GetTfsGitSourceVersionAsync(BuildMonitorSettings settings, String projectUrl, TBuild build) { var requestUrl = $"{projectUrl}/_apis/git/repositories/{build.Repository.Id}/commits/{build.SourceVersionInternal}?api-version=1.0"; var sourceVersion = await GetSourceVersionAsync <TSourceVersion>(settings, requestUrl).ConfigureAwait(false); // special case detection if it as auto merge commit made by TFS pull requests if (build.Reason == BuildReason.PullRequest || build.Reason == BuildReason.Validation) { if (sourceVersion?.Parents != null && sourceVersion.Parents.Length > 1 && sourceVersion.Pusher != null && sourceVersion.Pusher.IsServiceUser) { var innerRequestUrl = $"{projectUrl}/_apis/git/repositories/{build.Repository.Id}/commits/{sourceVersion.Parents.Last()}?api-version=1.0"; return(await GetSourceVersionAsync <TSourceVersion>(settings, innerRequestUrl).ConfigureAwait(false)); } } return(sourceVersion); }
public static void ThrowIfKeyNotExistsAndValueEmpty(this BuildMonitorSettings settings, String key) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (String.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(nameof(key)); } settings.ThrowIfKeyNotExists(key); var value = settings[key]; if (value == null || value is String && String.IsNullOrEmpty(value.ToString())) { throw new NullReferenceException($"Value for key {key} must not be empty or null!"); } }
private async Task ResolveSourceVersionAsync(IEnumerable <TBuild> builds, String projectUrl, BuildMonitorSettings settings) { var grpByRepoType = builds.GroupBy(a => a.Repository.RepositoryType); foreach (var group in grpByRepoType) { if (group.Key == RepositoryType.TfsVersionControl) { foreach (var build in group) { var requestUrl = $"{projectUrl}/_apis/tfvc/changesets/{build.SourceVersionInternal}?api-version=1.0&includeDetails=true"; build.SourceVersion = await GetSourceVersionAsync <TSourceVersion>(settings, requestUrl).ConfigureAwait(false); } } else if (group.Key == RepositoryType.TfsGit) { foreach (var build in group) { build.SourceVersion = await GetTfsGitSourceVersionAsync(settings, projectUrl, build).ConfigureAwait(false); } } else if (group.Key == RepositoryType.GitHub) { // ToDo: can't poll everytime because of rate limits... return; #if DEBUG // special case when it is a TFS project with external GitHub repository foreach (var build in group) { var ownerAndRepo = GetGitOwnerAndRepo(build.Repository.Id); var requestUrl = $"{GitHubApiPrefix}/repos/{ownerAndRepo.Item1}/{ownerAndRepo.Item2}/commits/{build.SourceVersionInternal}"; var requestResponse = await HttpRequestHelper.GetRequestResponseAsync(requestUrl).ConfigureAwait(false); if (requestResponse.IsSuccessStatusCode) { var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); build.SourceVersion = JsonConvert.DeserializeObject <GitHubSourceVersion>(result); } } #endif } } }
private async Task <IEnumerable <IBuild> > PollBuildsAsync(IBuildProvider provider, BuildMonitorSettings settings) { try { if (this.generalSettings?.ViewStyle == BuildViewStyle.GroupByPullRequest) { var prBuilds = await provider.GetBuildsByPullRequestsAsync(settings).ConfigureAwait(false); prBuilds.ThrowIfUnsuccessful(); var definitionsInUse = prBuilds.Data.GroupBy(a => a.Definition, build => build, this.buildDefinitionEqualityComparer).Select(a => a.Key); var unusedDefinitions = settings.SelectedBuildDefinitions.Except(definitionsInUse, this.buildDefinitionEqualityComparer).ToList(); if (unusedDefinitions.Any()) { var defBuilds = await provider.GetBuildsAsync(settings.SelectedBuildDefinitions, settings).ConfigureAwait(false); defBuilds.ThrowIfUnsuccessful(); return(prBuilds.Data.Concat(defBuilds.Data)); } return(prBuilds.Data); } var builds = await provider.GetBuildsAsync(settings.SelectedBuildDefinitions, settings).ConfigureAwait(false); builds.ThrowIfUnsuccessful(); return(builds.Data); } catch (DataResponseUnsuccessfulException ex) { this.logger.Warn($"Http status code {ex.StatusCode} returned while polling for builds!"); this.notificationProvider?.ShowMessage("Failure on getting builds", $"Please check the connection for project(s) '{String.Join(", ", settings.SelectedBuildDefinitions.Select(b => b.Project.Name).Distinct())}'. StatusCode was '{ex.StatusCode}'. See log for more details."); } catch (Exception exception) { this.logger.Warn("Failure on polling builds", exception); this.notificationProvider?.ShowMessage("Failure on getting builds", $"Please check the connection for project(s) '{String.Join(", ", settings.SelectedBuildDefinitions.Select(b => b.Project.Name).Distinct())}'. See log for details."); } return(Enumerable.Empty <IBuild>()); }
private static async Task <TInnerSourceVersion> GetSourceVersionAsync <TInnerSourceVersion>(BuildMonitorSettings settings, String requestUrl) where TInnerSourceVersion : ISourceVersion, new() { var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); if (requestResponse.IsSuccessStatusCode) { var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); return(JsonConvert.DeserializeObject <TInnerSourceVersion>(result)); } return(default(TInnerSourceVersion)); }
public virtual async Task <DataResponse <IEnumerable <IBuild> > > GetBuildsByPullRequestsAsync(BuildMonitorSettings settings) { var projectUrl = settings.GetValueStrict <String>(ProjectUrlSettingKey).TrimEnd('/'); var requestUrl = $"{projectUrl}/_apis/git/pullrequests?api-version={ApiVersion}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); requestResponse.ThrowIfUnsuccessful(); var dict = new Dictionary <IPullRequest, IEnumerable <TBuild> >(); var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); var data = JsonConvert.DeserializeObject <List <TPullRequest> >(JObject.Parse(result)["value"].ToString()); foreach (var pullRequest in data) { var buildsResponse = await GetBuildsOfPullRequestAsync(pullRequest, settings).ConfigureAwait(false); if (buildsResponse.IsSuccessStatusCode) { dict.Add(pullRequest, buildsResponse.Data); } else { throw new Exception("Error while processing method!"); } } // sets the relation of the PR to the build object foreach (var keyValuePair in dict) { foreach (var build in keyValuePair.Value) { build.PullRequest = keyValuePair.Key; } } return(new DataResponse <IEnumerable <IBuild> > { Data = dict.Values.SelectMany(a => a).ToList(), StatusCode = requestResponse.StatusCode }); }
public virtual async Task <DataResponse <IEnumerable <IBuild> > > GetBuildsAsync(IEnumerable <IBuildDefinition> buildDefinitions, BuildMonitorSettings settings) { var buildDefinitionsList = buildDefinitions.ToList(); if (!buildDefinitionsList.Any()) { return(new DataResponse <IEnumerable <IBuild> > { Data = Enumerable.Empty <TBuild>(), StatusCode = HttpStatusCode.NoContent }); } var projectUrl = settings.GetValueStrict <String>(ProjectUrlSettingKey).TrimEnd('/'); var maxBuilds = settings.GetDefaultValueIfNotExists <Int32?>(MaxBuildsPerDefinitionSettingsKey) ?? 5; // use fallback value when no value was defined via settings if (!String.IsNullOrWhiteSpace(projectUrl)) { var buildDefinitionsCommaList = String.Join(",", buildDefinitionsList.Select(a => a.Id)); var requestUrl = $"{projectUrl}/_apis/build/builds?api-version={ApiVersion}&definitions={buildDefinitionsCommaList}&maxBuildsPerDefinition={maxBuilds}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); requestResponse.ThrowIfUnsuccessful(); var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); var data = JsonConvert.DeserializeObject <List <TBuild> >(JObject.Parse(result)["value"].ToString()); await ResolveAdditionalBuildDataAsync(settings, data, projectUrl).ConfigureAwait(false); return(new DataResponse <IEnumerable <IBuild> > { Data = data, StatusCode = requestResponse.StatusCode }); } throw new Exception("Error while processing method!"); }
private static async Task <HttpResponseMessage> GetRequestResponseAsync(String requestUrl, BuildMonitorSettings settings) { var credentials = settings.GetValueStrict <ICredentials>(ProjectCredentialsSettingKey); var accessToken = settings.GetDefaultValueIfNotExists <String>(PersonalAccessTokenSettingsKey); if (!String.IsNullOrWhiteSpace(accessToken)) { return(await HttpRequestHelper.GetRequestResponseAsync(requestUrl, accessToken).ConfigureAwait(false)); } return(await HttpRequestHelper.GetRequestResponseAsync(requestUrl, credentials).ConfigureAwait(false)); }
private async Task ResolveArtifactsAsync(IEnumerable <TBuild> builds, String projectUrl, BuildMonitorSettings settings) { foreach (var build in builds) { var requestUrl = $"{projectUrl}/_apis/build/builds/{build.Id}/artifacts?api-version={ApiVersion}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); if (requestResponse.IsSuccessStatusCode) { var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); build.Artifacts = JsonConvert.DeserializeObject <IEnumerable <TArtifact> >(JObject.Parse(result)["value"].ToString()); } } }
public virtual async Task <DataResponse <IEnumerable <IBuildDefinition> > > GetBuildDefinitionsAsync(BuildMonitorSettings settings) { var projectUrl = settings.GetValueStrict <String>(ProjectUrlSettingKey).TrimEnd('/'); if (!String.IsNullOrWhiteSpace(projectUrl)) { var requestUrl = $"{projectUrl}/_apis/build/definitions?api-version={ApiVersion}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); requestResponse.ThrowIfUnsuccessful(); var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); var data = JsonConvert.DeserializeObject <List <TBuildDefinition> >(JObject.Parse(result)["value"].ToString()); foreach (var buildDefinition in data) { buildDefinition.BuildSettingsId = settings.UniqueId; } return(new DataResponse <IEnumerable <IBuildDefinition> > { Data = data, StatusCode = requestResponse.StatusCode }); } throw new Exception("Error while processing method!"); }
private async Task <DataResponse <IEnumerable <TBuild> > > GetBuildsOfPullRequestAsync(IPullRequest pullRequest, BuildMonitorSettings settings) { var projectUrl = settings.GetValueStrict <String>(ProjectUrlSettingKey).TrimEnd('/'); var maxBuilds = settings.GetDefaultValueIfNotExists <Int32?>(MaxBuildsPerDefinitionSettingsKey) ?? 5; // use fallback value when no value was defined via settings var requestUrl = $"{projectUrl}/_apis/build/builds?api-version={ApiVersion}&branchName=refs%2Fpull%2F{pullRequest.Id}%2Fmerge&$top={maxBuilds}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); requestResponse.ThrowIfUnsuccessful(); var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); var data = JsonConvert.DeserializeObject <List <TBuild> >(JObject.Parse(result)["value"].ToString()); await ResolveAdditionalBuildDataAsync(settings, data, projectUrl).ConfigureAwait(false); return(new DataResponse <IEnumerable <TBuild> > { Data = data, StatusCode = requestResponse.StatusCode }); }
private static async Task ResolveTestRunsAsync(IEnumerable <TBuild> builds, String projectUrl, BuildMonitorSettings settings) { foreach (var build in builds) { var requestUrl = $"{projectUrl}/_apis/test/runs?api-version=1.0&buildUri={build.Uri}"; var requestResponse = await GetRequestResponseAsync(requestUrl, settings).ConfigureAwait(false); if (requestResponse.IsSuccessStatusCode) { var result = await requestResponse.Content.ReadAsStringAsync().ConfigureAwait(false); build.TestRuns = JsonConvert.DeserializeObject <IEnumerable <TTestRun> >(JObject.Parse(result)["value"].ToString()); } } }