Esempio n. 1
0
        public async Task Handle(MetricQueryRequest <WorkItemQueryWidget> request, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(request.DataContext.QueryId))
            {
                return;
            }

            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var workItemQueryResult = await api.QueryWorkItemsByIdAsync(request.DataContext.QueryId, cancellationToken).ConfigureAwait(false);

            var ids = workItemQueryResult.WorkItems.Select(w => w.Id).ToList();

            if (ids.Any())
            {
                var workItems = await api.GetWorkItemsAsync(ids, cancellationToken).ConfigureAwait(false);

                _uiAction.Invoke(() => UpdateWidget(request.DataContext, workItemQueryResult.WorkItems, workItems));
            }
            else
            {
                request.DataContext.Value = 0;
                request.DataContext.State = State.Ok;

                _uiAction.Invoke(request.DataContext.Clear);
            }
        }
Esempio n. 2
0
        public async Task Handle(InitializeRequest <WorkItemQueryWidget> request, CancellationToken cancellationToken)
        {
            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var workItemQueries =
                await api.GetWorkItemQueriesAsync(request.DataContext.Project, request.DataContext.Query, 1,
                                                  cancellationToken).ConfigureAwait(false);

            if (workItemQueries.Count == 0)
            {
                request.DataContext.State   = State.Unknown;
                request.DataContext.QueryId = string.Empty;
                request.DataContext.URL     = string.Empty;

                _uiAction.Invoke(request.DataContext.Clear);

                request.DataContext.Clear();

                _logger.Error($"Work item query {request.DataContext.Query} was not found.");
            }
            else
            {
                var query = workItemQueries.Value.First();
                request.DataContext.QueryId = query.Id;
                request.DataContext.URL     = query.Links["html"]["href"];
            }
        }
Esempio n. 3
0
        public async Task Handle(StartRequest <ReleaseEnvironmentWidget> request, CancellationToken cancellationToken)
        {
            var dialog = new ConfirmationDialog($"Are you sure you want to start {request.DataContext.Name}?");

            if (_dialogService.ShowDialog(dialog) != DialogResult.Yes)
            {
                return;
            }

            if (request.DataContext.Parent is ReleaseWidget parent)
            {
                var api = new AzureDevOpsApi(parent.ConnectionSettings);

                var response = await api.GetReleasesAsync(parent.Project, parent.DefinitionId, 1, cancellationToken).ConfigureAwait(false);

                if (response.Count == 0)
                {
                    throw new Exception("Release not found.");
                }

                var release = response.Value.First();

                await api.DeployAsync(parent.Project, release.Id, request.DataContext.DeploymentId, cancellationToken).ConfigureAwait(false);

                request.DataContext.State = State.Queued;
            }
        }
Esempio n. 4
0
        public async Task Handle(MetricQueryRequest <WorkItemsWidget> request, CancellationToken cancellationToken)
        {
            const string workItemsQuery = "SELECT [System.Id] FROM WorkItems " +
                                          "WHERE [System.AssignedTo] = {0} " +
                                          "AND [State] NOT IN ('Done','Closed','Inactive','Completed')";

            var query = string.Format(workItemsQuery, request.DataContext.AssignedTo);

            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var workItemQueryResult = await api.QueryWorkItemsAsync(query, cancellationToken).ConfigureAwait(false);

            var ids = workItemQueryResult.WorkItems.Select(w => w.Id).ToList();

            if (ids.Count != 0)
            {
                var workItems = await api.GetWorkItemsAsync(ids, cancellationToken).ConfigureAwait(false);

                _uiAction.Invoke(() => UpdateWidget(request.DataContext, workItemQueryResult.WorkItems, workItems));
            }
            else
            {
                request.DataContext.Value = 0;
                request.DataContext.State = State.Ok;

                _uiAction.Invoke(request.DataContext.Clear);
            }
        }
Esempio n. 5
0
        public async Task Handle(HealthCheckRequest <ReleaseWidget> request, CancellationToken cancellationToken)
        {
            var widget = request.DataContext;

            var api = new AzureDevOpsApi(widget.ConnectionSettings);

            var releases = await api.GetReleasesAsync(widget.Project, widget.DefinitionId, 1, cancellationToken).ConfigureAwait(false);

            if (releases.Count == 0)
            {
                widget.State = State.None;

                return;
            }

            var release = releases.Value.First();

            UpdateInfo(widget, release);

            _uiAction.Invoke(() => UpdateEnvironments(widget, release));

            var deployments = await api.GetDeploymentsAsync(widget.Project, widget.DefinitionId, 10, cancellationToken).ConfigureAwait(false);

            if (deployments.Count > 0)
            {
                UpdateHistory(widget, deployments.Value.ToList());
            }
        }
Esempio n. 6
0
        public async Task Handle(HealthCheckRequest <BuildWidget> request, CancellationToken cancellationToken)
        {
            var widget = request.DataContext;

            var api = new AzureDevOpsApi(widget.ConnectionSettings);

            var results = await api.GetBuildsAsync(widget.Project, widget.DefinitionId, 10, cancellationToken).ConfigureAwait(false);

            if (results.Count == 0)
            {
                widget.State = State.None;

                return;
            }

            var builds = results.Value.ToList();

            UpdateInfo(widget, builds[0]);

            UpdateStats(widget, builds);

            builds.Reverse();

            UpdateHistory(widget, builds);
        }
Esempio n. 7
0
        protected override async Task Handle(StatusRequest <AzureDevOpsWorkItemsWidget> request, CancellationToken cancellationToken)
        {
            var api = new AzureDevOpsApi(Endpoint);

            var wiql = string.Format(query, request.Context.Iteration);

            var response = await api.QueryWorkItemsAsync(request.Context.Account, request.Context.Project, wiql, cancellationToken);

            if (response.WorkItems.Any())
            {
                var ids = response.WorkItems.Select(w => w.Id).ToList();

                var workItems = await api.GetWorkItemsAsync(request.Context.Account, request.Context.Project, ids, cancellationToken);

                request.Context.Text = workItems.Count.ToString();

                _dispatcher.Invoke(() => new AzureDevOpsWorkItemsSynchronizer(_mapper, request.Context)
                                   .Synchronize(workItems.Value.ToList(), request.Context.OfType <AzureDevOpsWorkItemWidget>().ToList()));
            }
            else
            {
                request.Context.Text = default;

                _dispatcher.Invoke(request.Context.Clear);
            }

            request.Context.Status = Status.OK;
        }
Esempio n. 8
0
        private static async Task <UpdateResult> CrawlReleases(ILogger log, CancellationToken ct)
        {
            var config = new ConfigurationBuilder()
                         .AddJsonFile("host.json", optional: true, reloadOnChange: true)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            var status = "starting";

            using (var hc = new HealthchecksApi(config, log, "crawler"))
                using (var videoLan = new VideoLanApi())
                    using (var azure = new AzureDevOpsApi(config["azure-auth"]))
                    {
                        try
                        {
                            status = "reporting start to healthchecks";
                            await hc.Start(ct);

                            status            = "searching latest available version";
                            var(version, url) = await videoLan.GetLatestVersion(ct);

                            status = "loading azure config";
                            var variables = await azure.GetBuildVariables(ct);

                            if (variables.TryUpdate("latest.version", version))
                            {
                                variables.TryUpdate("latest.url", url);

                                status = "updating azure config";
                                await azure.UpdateBuildVariables(variables, ct);

                                status = "queuing new build";
                                await azure.QueueBuild(ct);

                                status = "reporting success to healthchecks";
                                await hc.Report(ct);

                                return(UpdateResult.Succeeded());
                            }
                            else
                            {
                                status = "reporting success (not changed) to healthchecks";
                                await hc.Report(ct);

                                return(UpdateResult.NotChanged());
                            }
                        }
                        catch (Exception e)
                        {
                            await hc.Failed(ct);             // cannot fail

                            return(UpdateResult.Failed(status, e));
                        }
                    }
        }
Esempio n. 9
0
        protected async override Task Handle(StatusRequest <AzureDevOpsPullRequestsWidget> request, CancellationToken cancellationToken)
        {
            var api = new AzureDevOpsApi(Endpoint);

            var pullRequests = await api.GetPullRequestsAsync(request.Context.Account, request.Context.Project).ConfigureAwait(false);

            request.Context.Text = pullRequests.Count.ToString();

            if (pullRequests is null || pullRequests.Count == 0)
            {
                _dispatcher.InvokeAsync(request.Context.Clear);
            }
Esempio n. 10
0
        public async Task Handle(StopRequest <BuildWidget> request, CancellationToken cancellationToken)
        {
            var dialog = new ConfirmationDialog($"Are you sure you want to stop {request.DataContext.Name}?");

            if (_dialogService.ShowDialog(dialog) != DialogResult.Yes)
            {
                return;
            }

            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            await api.CancelBuildAsync(request.DataContext.Project, request.DataContext.LastBuildId, cancellationToken).ConfigureAwait(false);
        }
Esempio n. 11
0
        public async Task Handle(StartRequest <ReleaseWidget> request, CancellationToken cancellationToken)
        {
            var dialog = new ConfirmationDialog($"Are you sure you want to create a new release of {request.DataContext.Name}?");

            if (_dialogService.ShowDialog(dialog) != DialogResult.Yes)
            {
                return;
            }

            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            await api.CreateReleaseAsync(request.DataContext.Project, request.DataContext.DefinitionId, cancellationToken).ConfigureAwait(false);
        }
Esempio n. 12
0
        public async Task Handle(InitializeRequest <PullRequestsWidget> request, CancellationToken cancellationToken)
        {
            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var repository = await api.GetRepositoryAsync(request.DataContext.Project, request.DataContext.Repository, cancellationToken).ConfigureAwait(false);

            if (string.IsNullOrEmpty(repository.Id))
            {
                request.DataContext.State = State.Unknown;
            }
            else
            {
                request.DataContext.RepositoryId = repository.Id;
            }
        }
Esempio n. 13
0
        public async Task Handle(InitializeRequest <BuildWidget> request, CancellationToken cancellationToken)
        {
            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var response = await api.GetBuildDefinitionsAsync(request.DataContext.Project, request.DataContext.Definition, 1, cancellationToken).ConfigureAwait(false);

            var buildDefinition = response.Value.FirstOrDefault();

            if (buildDefinition == null)
            {
                throw new Exception($"Build definition \"{request.DataContext.Definition}\" was not found.");
            }

            request.DataContext.DefinitionId = buildDefinition.Id;
            request.DataContext.URL          = buildDefinition.Links["web"]["href"];
        }
Esempio n. 14
0
        public async Task Handle(HealthCheckRequest <ReleaseEnvironmentWidget> request, CancellationToken cancellationToken)
        {
            var widget = request.DataContext;

            if (widget.Parent is ReleaseWidget parent && parent.DefinitionId != 0)
            {
                var api = new AzureDevOpsApi(parent.ConnectionSettings);

                var response = await api.GetDeploymentsAsync(parent.Project, parent.DefinitionId, widget.DefinitionEnvironmentId, 10, cancellationToken).ConfigureAwait(false);

                var deployments = response.Value.ToList();

                if (deployments.Any())
                {
                    deployments.Reverse();

                    var maxDuration = deployments.Max(deployment => deployment.Duration);

                    deployments.ForEach(deployment => deployment.Percentage = (double)deployment.Duration.Ticks / maxDuration.Ticks);
                }

                widget.JobHistory = deployments;
            }
        }
Esempio n. 15
0
        public async Task Handle(MetricQueryRequest <PullRequestsWidget> request, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(request.DataContext.RepositoryId))
            {
                return;
            }

            var api = new AzureDevOpsApi(request.DataContext.ConnectionSettings);

            var pullRequests = await api.GetPullRequestsAsync(
                request.DataContext.Project,
                request.DataContext.RepositoryId,
                request.DataContext.SourceBranch,
                request.DataContext.TargetBranch,
                cancellationToken).ConfigureAwait(false);

            request.DataContext.Value = pullRequests.Count;

            var synchronizer = GetSynchronizer(request);

            _uiAction.Invoke(() => synchronizer.Synchronize(pullRequests.Value.ToList(), request.DataContext.Items));

            request.DataContext.State = State.Ok;
        }
        private static async Task <UpdateResult[]> CrawlReleases(string[] channels, ILogger log, CancellationToken ct)
        {
            var config = new ConfigurationBuilder()
                         .AddJsonFile("host.json", optional: true, reloadOnChange: true)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            using (var hc = new HealthchecksApi(config, log))
                using (var gitHub = new GitHubApi())
                    using (var azure = new AzureDevOpsApi(config["azureDevOpsAuth"]))
                    {
                        var releases = await gitHub.GetDuplicatiReleases(ct);

                        var variables = await azure.GetBuildVariables(ct);

                        var @default = variables["default"];

                        return(await Task.WhenAll(channels.Select(TryUpdateChannel)));

                        async Task <UpdateResult> TryUpdateChannel(string channel)
                        {
                            var status = "parsing inputs";

                            try
                            {
                                status = "searching release";
                                if (!releases.TryGetValue(channel, out var release))
                                {
                                    throw new Exception($"Cannot find release for {channel}");
                                }

                                status = "reporting start to healthchecks";
                                await hc.Start(channel, ct);                 // we report to HC only if we found a release. This prevent issue with the still awaited "stable" version :)

                                status = "searching variable group";
                                if (!variables.TryGetValue(channel, out var group))
                                {
                                    throw new Exception($"Cannot find build variables for {channel}");
                                }

                                status = "analyzing build config vs. found release";
                                var install = release.data.Assets.FirstOrDefault(a => a.Url.EndsWith(release.version + ".zip", StringComparison.OrdinalIgnoreCase))?.Url;
                                var version = release.version;
                                if (install.IsNullOrWhiteSpace() || version.IsNullOrWhiteSpace())
                                {
                                    throw new Exception($"The found release is invalid for {channel} (Failed to get required values 'install' and 'version')");
                                }

                                var hasChanged = false;
                                hasChanged |= group.TryUpdate("install", install);
                                hasChanged |= group.TryUpdate("version", version);
                                hasChanged |= group.TryUpdate("url", release.data.Url);
                                hasChanged |= group.TryUpdate("notes", release.data.Notes);

                                if (hasChanged)
                                {
                                    status = "updating build variables";
                                    await azure.UpdateBuildVariables(group, ct);

                                    if (@default["channel"] == channel)
                                    {
                                        status = "updating **default** build variables";

                                        @default.TryUpdate("install", install);
                                        @default.TryUpdate("version", version);
                                        @default.TryUpdate("url", release.data.Url);
                                        @default.TryUpdate("notes", release.data.Notes);

                                        await azure.UpdateBuildVariables(@default, ct);

                                        status = "queuing new **default** build";
                                        await azure.QueueBuild("default", ct);                         // So the image is tagged as 'latest'
                                    }
                                    else
                                    {
                                        status = "queuing new build";
                                        await azure.QueueBuild(channel, ct);
                                    }

                                    status = "reporting success to healthchecks";
                                    await hc.Report(channel, ct);

                                    return(UpdateResult.Succeeded(channel));
                                }
                                else
                                {
                                    status = "reporting success (not changed) to healthchecks";
                                    await hc.Report(channel, ct);

                                    return(UpdateResult.NotChanged(channel));
                                }
                            }
                            catch (Exception e)
                            {
                                await hc.Failed(channel, ct);                 // cannot fail

                                return(UpdateResult.Failed(channel, status, e));
                            }
                        }
                    }
        }