public static async Task UploadArtifactAsync(
            IAsyncCommandContext context,
            VssConnection connection,
            Guid projectId,
            long containerId,
            string containerPath,
            int buildId,
            string name,
            string jobId,
            Dictionary <string, string> propertiesDictionary,
            string source,
            CancellationToken cancellationToken)
        {
            var fileContainerHelper = new FileContainerServer(connection, projectId, containerId, containerPath);
            var size = await fileContainerHelper.CopyToContainerAsync(context, source, cancellationToken);

            propertiesDictionary.Add(ArtifactUploadEventProperties.ArtifactSize, size.ToString());

            var fileContainerFullPath = StringUtil.Format($"#/{containerId}/{containerPath}");

            context.Output(StringUtil.Loc("UploadToFileContainer", source, fileContainerFullPath));

            var buildHelper = context.GetHostContext().GetService <IBuildServer>();
            await buildHelper.ConnectAsync(connection);

            var artifact = await buildHelper.AssociateArtifactAsync(buildId, projectId, name, jobId, ArtifactResourceTypes.Container, fileContainerFullPath, propertiesDictionary, cancellationToken);

            context.Output(StringUtil.Loc("AssociateArtifactWithBuild", artifact.Id, buildId));
        }
        private async Task UpdateBuildNumberAsync(
            IAsyncCommandContext context,
            VssConnection connection,
            Guid projectId,
            int buildId,
            string buildNumber,
            CancellationToken cancellationToken)
        {
            var buildServer = context.GetHostContext().GetService <IBuildServer>();
            await buildServer.ConnectAsync(connection);

            var build = await buildServer.UpdateBuildNumber(buildId, projectId, buildNumber, cancellationToken);

            context.Output(StringUtil.Loc("UpdateBuildNumberForBuild", build.BuildNumber, build.Id));
        }
        public static async Task AssociateArtifactAsync(
            IAsyncCommandContext context,
            VssConnection connection,
            Guid projectId,
            int buildId,
            string name,
            string jobId,
            string type,
            string data,
            Dictionary <string, string> propertiesDictionary,
            CancellationToken cancellationToken)
        {
            var buildHelper = context.GetHostContext().GetService <IBuildServer>();
            await buildHelper.ConnectAsync(connection);

            var artifact = await buildHelper.AssociateArtifactAsync(buildId, projectId, name, jobId, type, data, propertiesDictionary, cancellationToken);

            context.Output(StringUtil.Loc("AssociateArtifactWithBuild", artifact.Id, buildId));
        }
        private async Task AddBuildTagAsync(
            IAsyncCommandContext context,
            VssConnection connection,
            Guid projectId,
            int buildId,
            string buildTag,
            CancellationToken cancellationToken)
        {
            var buildServer = context.GetHostContext().GetService <IBuildServer>();
            await buildServer.ConnectAsync(connection);

            var tags = await buildServer.AddBuildTag(buildId, projectId, buildTag, cancellationToken);

            if (tags == null || !tags.Any(t => t.Equals(buildTag, StringComparison.OrdinalIgnoreCase)))
            {
                throw new Exception(StringUtil.Loc("BuildTagAddFailed", buildTag));
            }
            else
            {
                context.Output(StringUtil.Loc("BuildTagsForBuild", buildId, String.Join(", ", tags)));
            }
        }
Exemple #5
0
        public async Task PublishCodeCoverageFilesAsync(IAsyncCommandContext context, Guid projectId, string jobId, long containerId, List <Tuple <string, string> > files, bool browsable, CancellationToken cancellationToken)
        {
            var publishCCTasks = files.Select(async file =>
            {
                var browsableProperty  = (browsable) ? bool.TrueString : bool.FalseString;
                var artifactProperties = new Dictionary <string, string> {
                    { ArtifactUploadEventProperties.ContainerFolder, file.Item2 },
                    { ArtifactUploadEventProperties.ArtifactName, file.Item2 },
                    { ArtifactAssociateEventProperties.ArtifactType, ArtifactResourceTypes.Container },
                    { ArtifactAssociateEventProperties.Browsable, browsableProperty },
                };

                var fileContainerHelper = new FileContainerServer(_connection, projectId, containerId, file.Item2);
                await fileContainerHelper.CopyToContainerAsync(context, file.Item1, cancellationToken);
                var fileContainerFullPath = StringUtil.Format($"#/{containerId}/{file.Item2}");

                var buildHelper = context.GetHostContext().GetService <IBuildServer>();
                await buildHelper.ConnectAsync(_connection);
                var artifact = await buildHelper.AssociateArtifactAsync(_buildId, projectId, file.Item2, jobId, ArtifactResourceTypes.Container, fileContainerFullPath, artifactProperties, cancellationToken);
                context.Output(StringUtil.Loc("PublishedCodeCoverageArtifact", file.Item1, file.Item2));
            });

            await Task.WhenAll(publishCCTasks);
        }
        private async Task <UploadResult> BlobUploadAsync(IAsyncCommandContext context, IReadOnlyList <string> files, int concurrentUploads, CancellationToken token)
        {
            // return files that fail to upload and total artifact size
            var uploadResult = new UploadResult();

            // nothing needs to upload
            if (files.Count == 0)
            {
                return(uploadResult);
            }

            DedupStoreClient            dedupClient     = null;
            BlobStoreClientTelemetryTfs clientTelemetry = null;

            try
            {
                var verbose        = String.Equals(context.GetVariableValueOrDefault("system.debug"), "true", StringComparison.InvariantCultureIgnoreCase);
                int maxParallelism = context.GetHostContext().GetService <IConfigurationStore>().GetSettings().MaxDedupParallelism;
                (dedupClient, clientTelemetry) = await DedupManifestArtifactClientFactory.Instance
                                                 .CreateDedupClientAsync(verbose, (str) => context.Output(str), this._connection, maxParallelism, token);

                // Upload to blobstore
                var results = await BlobStoreUtils.UploadBatchToBlobstore(verbose, files, (level, uri, type) =>
                                                                          new BuildArtifactActionRecord(level, uri, type, nameof(BlobUploadAsync), context), (str) => context.Output(str), dedupClient, clientTelemetry, token, enableReporting : true);

                // Associate with TFS
                context.Output(StringUtil.Loc("AssociateFiles"));
                var queue = new ConcurrentQueue <BlobFileInfo>();
                foreach (var file in results.fileDedupIds)
                {
                    queue.Enqueue(file);
                }

                // Start associate monitor
                var uploadFinished   = new TaskCompletionSource <int>();
                var associateMonitor = AssociateReportingAsync(context, files.Count(), uploadFinished, token);

                // Start parallel associate tasks.
                var parallelAssociateTasks = new List <Task <UploadResult> >();
                for (int uploader = 0; uploader < concurrentUploads; uploader++)
                {
                    parallelAssociateTasks.Add(AssociateAsync(context, queue, token));
                }

                // Wait for parallel associate tasks to finish.
                await Task.WhenAll(parallelAssociateTasks);

                foreach (var associateTask in parallelAssociateTasks)
                {
                    // record all failed files.
                    uploadResult.AddUploadResult(await associateTask);
                }

                // Stop monitor task
                uploadFinished.SetResult(0);
                await associateMonitor;

                // report telemetry
                if (!Guid.TryParse(context.GetVariableValueOrDefault(WellKnownDistributedTaskVariables.PlanId), out var planId))
                {
                    planId = Guid.Empty;
                }
                if (!Guid.TryParse(context.GetVariableValueOrDefault(WellKnownDistributedTaskVariables.JobId), out var jobId))
                {
                    jobId = Guid.Empty;
                }
                await clientTelemetry.CommitTelemetryUpload(planId, jobId);
            }
            catch (SocketException e)
            {
                ExceptionsUtil.HandleSocketException(e, this._connection.Uri.ToString(), context.Warn);

                throw;
            }
            catch
            {
                var blobStoreHost  = dedupClient.Client.BaseAddress.Host;
                var allowListLink  = BlobStoreWarningInfoProvider.GetAllowListLinkForCurrentPlatform();
                var warningMessage = StringUtil.Loc("BlobStoreUploadWarning", blobStoreHost, allowListLink);

                context.Warn(warningMessage);

                throw;
            }

            return(uploadResult);
        }