public override BuildImporterBase CreateFromForm()
        {
            var importer = new VsoBuildImporter
            {
                ArtifactName              = Util.CoalesceStr(this.Template.ArtifactName, this.Template.TeamProject),
                TeamProject               = this.Template.TeamProject,
                BuildDefinition           = this.Template.BuildDefinition,
                TfsBuildNumber            = (this.txtBuildNumber.Text != "last succeeded build" && this.txtBuildNumber.Text != "last completed build") ? this.txtBuildNumber.Text : null,
                IncludeUnsuccessful       = this.txtBuildNumber.Text == "last completed build",
                ServerId                  = this.Template.ServerId,
                CreateBuildNumberVariable = this.Template.CreateBuildNumberVariable
            };

            if (InedoLib.Util.Int.ParseN(importer.TfsBuildNumber) == null)
            {
                var config = (TfsConfigurer)this.GetExtensionConfigurer();

                var api = new TfsRestApi(config.BaseUrl, importer.TeamProject)
                {
                    UserName = config.UserName,
                    Password = config.Password
                };

                var tfsBuild = api.GetBuilds(
                    buildNumber: importer.TfsBuildNumber,
                    resultFilter: importer.IncludeUnsuccessful ? "" : "succeeded",
                    statusFilter: "completed",
                    top: 1
                    ).FirstOrDefault();

                if (tfsBuild == null)
                {
                    throw new InvalidOperationException("There were no matching builds found in TFS.");
                }

                var group = Regex.Match(tfsBuild.buildNumber, this.Template.BuildNumberPattern).Groups["num"];
                if (!group.Success || string.IsNullOrEmpty(group.Value))
                {
                    throw new InvalidOperationException("A build number could not be extracted using " + this.Template.BuildNumberPattern + " from TFS build number " + tfsBuild.buildNumber);
                }

                if (group.Value.Length > 10)
                {
                    throw new InvalidOperationException("The extracted build number (" + group.Value + ") is longer than 10 characters.");
                }

                importer.BuildNumber = group.Value;
            }

            return(importer);
        }
Beispiel #2
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);
                }
            }
        }