private async Task SetBuildConfigurationIdFromName()
        {
            this.Logger.LogDebug("Attempting to resolve build configuration ID from project and name...");
            using (var client = new TeamCityWebClient(this.ConnectionInfo))
            {
                this.Logger.LogDebug("Downloading build types...");
                string result = await client.DownloadStringTaskAsync("app/rest/buildTypes").ConfigureAwait(false);

                var doc = XDocument.Parse(result);
                var buildConfigurations = from e in doc.Element("buildTypes").Elements("buildType")
                                          let buildType = new BuildType(e)
                                                          where string.Equals(buildType.BuildConfigurationName, this.BuildConfigurationName, StringComparison.OrdinalIgnoreCase)
                                                          let match = new
                {
                    BuildType = buildType,
                    Index     = Array.FindIndex(buildType.ProjectNameParts, p => string.Equals(p, this.ProjectName, StringComparison.OrdinalIgnoreCase))
                }
                where match.Index > -1 || string.Equals(match.BuildType.ProjectName, this.ProjectName, StringComparison.OrdinalIgnoreCase)
                orderby match.Index
                select match.BuildType.BuildConfigurationId;

                this.BuildConfigurationId = buildConfigurations.FirstOrDefault();
                if (this.BuildConfigurationId == null)
                {
                    throw new ExecutionFailureException($"Build configuration ID could not be found for project \"{this.ProjectName}\" and build configuration \"{this.BuildConfigurationName}\".");
                }

                this.Logger.LogDebug("Build configuration ID resolved to: " + this.BuildConfigurationId);
            }
        }
        private async Task <string> GetActualBuildNumber()
        {
            this.Logger.LogDebug("Resolving actual build number...");

            string apiUrl = this.TryGetPredefinedConstantBuildNumberApiUrl(this.BuildNumber);

            if (apiUrl == null)
            {
                this.Logger.LogDebug("Using explicit build number: {0}", this.BuildNumber);
                return(this.BuildNumber);
            }

            this.Logger.LogDebug("Build number is the predefined constant \"{0}\", resolving...", this.BuildNumber);

            try
            {
                if (this.BranchName != null)
                {
                    apiUrl += ",branch:" + Uri.EscapeDataString(this.BranchName);
                }

                using (var client = new TeamCityWebClient(this.ConnectionInfo))
                {
                    string xml = await client.DownloadStringTaskAsync(apiUrl).ConfigureAwait(false);

                    var doc = XDocument.Parse(xml);
                    return(doc.Element("builds").Element("build").Attribute("number").Value);
                }
            }
            catch (Exception ex)
            {
                this.Logger.LogError("Could not parse actual build number from TeamCity. Exception details: " + ex);
                return(null);
            }
        }
示例#3
0
        private string GetActualBuildNumber(string buildNumber)
        {
            string apiUrl = this.TryGetPredefinedConstantBuildNumberApiUrl(buildNumber);

            if (apiUrl == null)
            {
                this.LogDebug($"Using explicit build number: {buildNumber}");
                return(buildNumber);
            }

            this.LogDebug($"Build number is the predefined constant \"{buildNumber}\", resolving...");

            try
            {
                var    configurer = this.GetExtensionConfigurer();
                string branch     = this.GetBranchName(configurer);
                if (branch != null)
                {
                    apiUrl += ",branch:" + Uri.EscapeDataString(branch);
                }

                using (var client = new TeamCityWebClient(configurer))
                {
                    string xml = client.DownloadString(apiUrl);
                    var    doc = XDocument.Parse(xml);
                    return(doc.Element("builds").Element("build").Attribute("number").Value);
                }
            }
            catch (Exception ex)
            {
                this.LogError("Could not parse actual build number from TeamCity. Exception details: " + ex);
                return(null);
            }
        }
        public async Task <IEnumerable <string> > GetSuggestionsAsync(IComponentConfiguration config)
        {
            var credentialName = config["CredentialName"];

            if (string.IsNullOrEmpty(credentialName))
            {
                return(Enumerable.Empty <string>());
            }

            var projectName = config["ProjectName"];

            if (string.IsNullOrEmpty(projectName))
            {
                return(Enumerable.Empty <string>());
            }

            var buildConfigurationName = config["BuildConfigurationName"];

            if (string.IsNullOrEmpty(projectName))
            {
                return(Enumerable.Empty <string>());
            }

            var credentials = ResourceCredentials.Create <TeamCityCredentials>(credentialName);

            using (var client = new TeamCityWebClient(credentials))
            {
                return(await client.GetBuildNumbersAsync(projectName, buildConfigurationName).ConfigureAwait(false));
            }
        }
示例#5
0
        public override async Task <IEnumerable <string> > EnumerateValuesAsync(ValueEnumerationContext context)
        {
            var credentials = ResourceCredentials.Create <TeamCityCredentials>(this.CredentialName);

            using (var client = new TeamCityWebClient(credentials))
            {
                return(await client.GetBuildNumbersAsync(this.ProjectName, this.BuildConfigurationName).ConfigureAwait(false));
            }
        }
示例#6
0
        protected override void Execute()
        {
            var configurer = this.GetExtensionConfigurer();

            string relativeUrl = string.Format("repository/download/{0}/{1}/{2}", this.BuildConfigurationId, this.BuildNumber, this.ArtifactName);

            string branchName = this.GetBranchName(configurer);

            if (branchName != null)
            {
                this.LogDebug("Getting artifact using branch: " + branchName);
                relativeUrl += "?branch=" + Uri.EscapeDataString(branchName);
            }

            this.LogDebug("Downloading TeamCity artifact \"{0}\" from {1} to {2}", this.ArtifactName, configurer.BaseUrl + relativeUrl, this.Context.TargetDirectory);

            var fileOps = this.Context.Agent.GetService <IFileOperationsExecuter>();

            string tempFile;

            using (var client = new TeamCityWebClient(configurer))
            {
                tempFile = Path.GetTempFileName();
                client.DownloadFile(relativeUrl, tempFile);
            }

            if (this.ExtractFilesToTargetDirectory)
            {
                this.LogDebug("Transferring artifact to {0} before extracting...", this.Context.TempDirectory);
                string remoteTempPath = fileOps.CombinePath(this.Context.TempDirectory, this.ArtifactName);
                fileOps.WriteFileBytes(
                    remoteTempPath,
                    File.ReadAllBytes(tempFile)
                    );

                this.LogDebug("Extracting TeamCity artifact to {0}...", this.Context.TargetDirectory);
                fileOps.ExtractZipFile(remoteTempPath, this.Context.TargetDirectory, true);
            }
            else
            {
                this.LogDebug("Transferring artifact to {0}...", this.Context.TargetDirectory);
                fileOps.WriteFileBytes(
                    fileOps.CombinePath(this.Context.TargetDirectory, this.ArtifactName),
                    File.ReadAllBytes(tempFile)
                    );
            }

            this.LogInformation("Artifact retrieved successfully.");
        }
        public async Task <string> ImportAsync()
        {
            this.Logger.LogInformation($"Importing artifact \"{this.ArtifactName}\" from TeamCity...");

            if (this.BuildConfigurationId == null)
            {
                if (this.BuildConfigurationName != null && this.ProjectName != null)
                {
                    await SetBuildConfigurationIdFromName().ConfigureAwait(false);
                }
                else
                {
                    throw new ExecutionFailureException("If BuildConfigurationId is not specified directly, a project name and configuration name are required.");
                }
            }

            if (string.IsNullOrEmpty(this.BuildNumber))
            {
                this.Logger.LogDebug("BuildNumber was not specified, using lastSuccessful...");
                this.BuildNumber = "lastSuccessful";
            }

            string relativeUrl = string.Format("repository/download/{0}/{1}/{2}", this.BuildConfigurationId, this.BuildNumber, this.ArtifactName);

            if (!string.IsNullOrEmpty(this.BranchName))
            {
                this.Logger.LogDebug("Branch name was specified: " + this.BranchName);
                relativeUrl += "?branch=" + Uri.EscapeDataString(this.BranchName);
            }

            this.Logger.LogDebug(string.Format("Importing TeamCity artifact \"{0}\" from {1}...", this.ArtifactName, this.ConnectionInfo.GetApiUrl() + relativeUrl));

            string tempFile = null;

            try
            {
                using (var client = new TeamCityWebClient(this.ConnectionInfo))
                {
                    tempFile = Path.GetTempFileName();
                    this.Logger.LogDebug($"Downloading temp file to \"{tempFile}\"...");
                    try
                    {
                        await client.DownloadFileTaskAsync(relativeUrl, tempFile).ConfigureAwait(false);
                    }
                    catch (WebException wex)
                    {
                        var response = wex.Response as HttpWebResponse;
                        if (response != null && response.StatusCode == HttpStatusCode.NotFound)
                        {
                            this.Logger.LogWarning("The TeamCity request returned a 404 - this could mean that the branch name, build number, or build configuration is invalid.");
                        }

                        throw;
                    }
                }

                this.Logger.LogInformation("Importing artifact into BuildMaster...");
                using (var file = File.OpenRead(tempFile))
                {
                    await SDK.CreateArtifactAsync(
                        applicationId : (int)this.Context.ApplicationId,
                        releaseNumber : this.Context.ReleaseNumber,
                        buildNumber : this.Context.BuildNumber,
                        deployableId : this.Context.DeployableId,
                        executionId : this.Context.ExecutionId,
                        artifactName : TrimWhitespaceAndZipExtension(this.ArtifactName),
                        artifactData : file,
                        overwrite : true
                        );
                }
            }
            finally
            {
                if (tempFile != null)
                {
                    this.Logger.LogDebug("Removing temp file...");
                    FileEx.Delete(tempFile);
                }
            }

            this.Logger.LogInformation(this.ArtifactName + " artifact imported.");

            return(await this.GetActualBuildNumber().ConfigureAwait(false));
        }