Пример #1
0
        /// <summary>
        /// Downloads and imports and artifact from Visual Studio Online.
        /// </summary>
        /// <param name="configurer">The configurer.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="teamProject">The team project.</param>
        /// <param name="buildNumber">The build number.</param>
        /// <param name="artifactId">The artifact identifier.</param>
        public static string DownloadAndImport(TfsConfigurer configurer, ILogger logger, string teamProject, string buildNumber, string buildDefinitionName, ArtifactIdentifier artifactId)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (configurer == null)
            {
                throw new ArgumentNullException("A configurer must be configured or selected in order to import a VS online build.");
            }
            if (string.IsNullOrEmpty(configurer.BaseUrl))
            {
                throw new InvalidOperationException("The base URL property of the TFS configurer must be set to import a VS online build.");
            }

            var api = new TfsRestApi(configurer.BaseUrl, teamProject)
            {
                UserName = string.IsNullOrEmpty(configurer.Domain) ? configurer.UserName : string.Format("{0}\\{1}", configurer.Domain, configurer.UserName),
                Password = configurer.Password
            };

            logger.LogInformation($"Finding last successful build...");
            var buildDefinitions = api.GetBuildDefinitions();

            var buildDefinition = buildDefinitions.FirstOrDefault(b => b.name == buildDefinitionName);

            if (buildDefinition == null)
            {
                throw new InvalidOperationException($"The build definition {buildDefinitionName} could not be found.");
            }

            logger.LogInformation($"Finding {Util.CoalesceStr(buildNumber, "last successful")} build...");

            var builds = api.GetBuilds(
                buildDefinition: buildDefinition.id,
                buildNumber: InedoLib.Util.NullIf(buildNumber, ""),
                resultFilter: "succeeded",
                statusFilter: "completed",
                top: 2
                );

            if (builds.Length == 0)
            {
                throw new InvalidOperationException($"Could not find build number {buildNumber}. Ensure there is a successful, completed build with this number.");
            }

            var build = builds.FirstOrDefault();

            string tempFile = Path.GetTempFileName();

            try
            {
                logger.LogInformation($"Downloading {artifactId.ArtifactName} artifact from VSO...");
                logger.LogDebug("Downloading artifact file to: " + tempFile);
                api.DownloadArtifact(build.id, artifactId.ArtifactName, tempFile);
                logger.LogInformation("Artifact file downloaded from VSO, importing into BuildMaster artifact library...");

                using (var stream = FileEx.Open(tempFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    ArtifactBuilder.ImportZip(artifactId, stream);
                }

                logger.LogInformation($"{artifactId.ArtifactName} artifact imported.");

                return(build.buildNumber);
            }
            finally
            {
                if (tempFile != null)
                {
                    FileEx.Delete(tempFile);
                }
            }
        }
Пример #2
0
        protected override void Execute()
        {
            var configurer = this.GetExtensionConfigurer();

            if (configurer == null)
            {
                throw new InvalidOperationException("A configurer must be configured or selected in order to queue a VS online build.");
            }
            if (string.IsNullOrEmpty(configurer.BaseUrl))
            {
                throw new InvalidOperationException("The base URL property of the TFS configurer must be set to queue a VS online build.");
            }

            var api = new TfsRestApi(configurer.BaseUrl, this.TeamProject)
            {
                UserName = string.IsNullOrEmpty(configurer.Domain) ? configurer.UserName : string.Format("{0}\\{1}", configurer.Domain, configurer.UserName),
                Password = configurer.Password
            };

            this.LogDebug("Finding VSO build definition...");
            var definition = api.GetBuildDefinitions()
                             .FirstOrDefault(d => string.IsNullOrEmpty(this.BuildDefinition) || string.Equals(d.name, this.BuildDefinition, StringComparison.OrdinalIgnoreCase));

            if (definition == null)
            {
                throw new InvalidOperationException("Could not find a build definition named: " + Util.CoalesceStr(this.BuildDefinition, "any"));
            }

            this.LogInformation($"Queueing VSO build of {this.TeamProject}, build definition {definition.name}...");

            var queuedBuild = api.QueueBuild(definition.id);

            this.LogInformation($"Build number \"{queuedBuild.buildNumber}\" created for definition \"{queuedBuild.definition.name}\".");

            if (this.CreateBuildNumberVariable)
            {
                this.LogDebug($"Setting $TfsBuildNumber build variable to {queuedBuild.buildNumber}...");
                StoredProcs.Variables_CreateOrUpdateVariableDefinition(
                    Variable_Name: "TfsBuildNumber",
                    Environment_Id: null,
                    Server_Id: null,
                    ApplicationGroup_Id: null,
                    Application_Id: this.Context.ApplicationId,
                    Deployable_Id: null,
                    Release_Number: this.Context.ReleaseNumber,
                    Build_Number: this.Context.BuildNumber,
                    Execution_Id: null,
                    Value_Text: queuedBuild.buildNumber,
                    Sensitive_Indicator: YNIndicator.No
                    ).Execute();

                this.LogInformation("$TfsBuildNumber build variable set to: " + queuedBuild.buildNumber);
            }

            if (this.WaitForCompletion)
            {
                string lastStatus = queuedBuild.status;
                this.LogInformation($"Current build status is \"{lastStatus}\", waiting for \"completed\" status...");

                while (!string.Equals(queuedBuild.status, "completed", StringComparison.OrdinalIgnoreCase))
                {
                    this.ThrowIfCanceledOrTimeoutExpired();
                    Thread.Sleep(4000);
                    queuedBuild = api.GetBuild(queuedBuild.id);
                    if (queuedBuild.status != lastStatus)
                    {
                        this.LogInformation($"Current build status changed from \"{lastStatus}\" to \"{queuedBuild.status}\"...");
                        lastStatus = queuedBuild.status;
                    }
                }

                this.LogInformation("Build status result is \"completed\".");

                if (this.ValidateBuild)
                {
                    this.LogInformation("Validating build status result is \"succeeded\"...");
                    if (!string.Equals("succeeded", queuedBuild.result, StringComparison.OrdinalIgnoreCase))
                    {
                        this.LogError("Build status result was not \"succeeded\".");
                        return;
                    }
                    this.LogInformation("Build status result was \"succeeded\".");
                }
            }

            this.LogInformation($"VSO build {queuedBuild.buildNumber} created.");
        }