예제 #1
1
        private async Task<TimeSpan> GetLastSuccesfulBuildTimeRest(TfsTeamProjectCollection teamProjectCollection, DefinitionReference definitionReference, BuildHttpClient httpClient)
        {
            var buildTime = new TimeSpan();

            try
            {
                var lastSuccessFullList = await httpClient.GetBuildsAsync(definitions: new List<int> { definitionReference.Id }, project: definitionReference.Project.Id, resultFilter: BuildResult.Succeeded,  statusFilter: Microsoft.TeamFoundation.Build.WebApi.BuildStatus.Completed, top: 1).ConfigureAwait(false);
                var build = lastSuccessFullList.FirstOrDefault();

                if (build == null)
                {
                    var lastPartiallySucceededList =   await httpClient.GetBuildsAsync(definitions: new List<int> { definitionReference.Id }, project: definitionReference.Project.Id, resultFilter: BuildResult.PartiallySucceeded, statusFilter: Microsoft.TeamFoundation.Build.WebApi.BuildStatus.Completed, top: 1).ConfigureAwait(false);
                    build = lastPartiallySucceededList.FirstOrDefault();
                }

                if (build != null)
                {
                    buildTime = build.FinishTime.GetValueOrDefault() - build.StartTime.GetValueOrDefault();
                }
                

            }
            catch (Exception)
            {
                
                throw;
            }
            return buildTime;
        }
예제 #2
0
 private static BuildDefinition GetBuildDefinition(int buildDef, string sourceProject, BuildHttpClient buildClient)
 {
     var definitionAsync = buildClient.GetDefinitionAsync(sourceProject, buildDef);
     definitionAsync.Wait();
     var definition = (BuildDefinition) definitionAsync.Result;
     return definition;
 }
예제 #3
0
 private static BuildHttpClient CreateClient(string accessToken)
 {
     var collectionUri = new Uri("https://riskfirst.visualstudio.com/DefaultCollection", UriKind.Absolute);
     var cred = new VssBasicCredential(string.Empty, accessToken);
     var buildClient = new BuildHttpClient(collectionUri, cred);
     return buildClient;
 }
예제 #4
0
 public BuildServer(VssConnection connection)
 {
     ArgUtil.NotNull(connection, nameof(connection));
     _buildHttpClient = connection.GetClient <BuildHttpClient>();
 }
예제 #5
0
        private void EnsureVersionBelongsToLinkedDefinition(ArtifactDefinition artifactDefinition, BuildHttpClient buildClient, XamlBuildHttpClient xamlBuildClient)
        {
            var buildArtifactDetails = artifactDefinition.Details as BuildArtifactDetails;

            if (buildArtifactDetails != null && buildArtifactDetails.DefintionId > 0)
            {
                var buildId = Convert.ToInt32(artifactDefinition.Version, CultureInfo.InvariantCulture);
                TeamFoundation.Build.WebApi.Build build = null;

                try
                {
                    build = buildClient.GetBuildAsync(buildArtifactDetails.Project, buildId).Result;
                }
                catch (AggregateException ex)
                {
                    if (ex.InnerException != null && ex.InnerException is BuildNotFoundException)
                    {
                        build = xamlBuildClient.GetBuildAsync(buildArtifactDetails.Project, buildId).Result;
                    }
                }

                if (build != null && build.Definition.Id != buildArtifactDetails.DefintionId)
                {
                    string errorMessage = StringUtil.Loc("RMBuildNotFromLinkedDefinition", artifactDefinition.Name, buildArtifactDetails.DefinitionName);
                    throw new ArtifactDownloadException(errorMessage);
                }
            }
        }
예제 #6
0
        private async Task <int> GetPipelineIdAsync(
            AgentTaskPluginExecutionContext context,
            string pipelineDefinition,
            string pipelineVersionToDownload,
            string project,
            string[] tagFilters,
            BuildResult resultFilter            = BuildResult.Succeeded,
            string branchName                   = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (String.IsNullOrWhiteSpace(pipelineDefinition))
            {
                throw new InvalidOperationException(StringUtil.Loc("CannotBeNullOrEmpty", "Pipeline Definition"));
            }

            VssConnection   connection      = context.VssConnection;
            BuildHttpClient buildHttpClient = connection.GetClient <BuildHttpClient>();

            var isDefinitionNum = Int32.TryParse(pipelineDefinition, out int definition);

            if (!isDefinitionNum)
            {
                var definitionReferencesWithName = await AsyncHttpRetryHelper.InvokeAsync(
                    async() => await buildHttpClient.GetDefinitionsAsync(new Guid(project), pipelineDefinition, cancellationToken: cancellationToken),
                    maxRetries : MaxRetries,
                    tracer : tracer,
                    context : "GetBuildDefinitionReferencesByName",
                    cancellationToken : cancellationToken,
                    continueOnCapturedContext : false);

                var definitionRef = definitionReferencesWithName.FirstOrDefault();

                if (definitionRef == null)
                {
                    throw new ArgumentException(StringUtil.Loc("PipelineDoesNotExist", pipelineDefinition));
                }
                else
                {
                    definition = definitionRef.Id;
                }
            }
            var definitions = new List <int>()
            {
                definition
            };

            List <Build> list;

            if (pipelineVersionToDownload == pipelineVersionToDownloadLatest)
            {
                list = await AsyncHttpRetryHelper.InvokeAsync(
                    async() => await buildHttpClient.GetBuildsAsync(
                        project,
                        definitions,
                        tagFilters: tagFilters,
                        queryOrder: BuildQueryOrder.FinishTimeDescending,
                        resultFilter: resultFilter,
                        cancellationToken: cancellationToken),
                    maxRetries : MaxRetries,
                    tracer : tracer,
                    context : "GetLatestBuild",
                    cancellationToken : cancellationToken,
                    continueOnCapturedContext : false);
            }
            else if (pipelineVersionToDownload == pipelineVersionToDownloadLatestFromBranch)
            {
                list = await AsyncHttpRetryHelper.InvokeAsync(
                    async() => await buildHttpClient.GetBuildsAsync(
                        project,
                        definitions,
                        branchName: branchName,
                        tagFilters: tagFilters,
                        queryOrder: BuildQueryOrder.FinishTimeDescending,
                        resultFilter: resultFilter,
                        cancellationToken: cancellationToken),
                    maxRetries : MaxRetries,
                    tracer : tracer,
                    context : "GetLatestBuildFromBranch",
                    cancellationToken : cancellationToken,
                    continueOnCapturedContext : false);
            }
            else
            {
                throw new InvalidOperationException("Unreachable code!");
            }

            if (list.Count > 0)
            {
                return(list.First().Id);
            }
            else
            {
                throw new ArgumentException(StringUtil.Loc("BuildsDoesNotExist"));
            }
        }
예제 #7
0
        private async Task<IEnumerable<BuildInfoDto>> GetBuildInfoDtosPerBuildDefinitionRest(TfsTeamProjectCollection teamProjectCollection, IList<DefinitionReference> definitionReferences, BuildHttpClient httpClient)
        {
            try
            {

           
            var buildInfoDtos = new List<BuildInfoDto>();
            foreach (var definitionReference in definitionReferences)
            {
                var builds = await httpClient.GetBuildsAsync(top: 1, project: definitionReference.Project.Id, minFinishTime: DateTime.Now.AddMonths(-6),  definitions: new[] { definitionReference.Id }).ConfigureAwait(false);
                var build = builds.FirstOrDefault();

                if (build == null) continue;

                var buildInfoDto = new BuildInfoDto();

                buildInfoDto.Builddefinition = definitionReference.Name;
                buildInfoDto.FinishBuildDateTime = build.FinishTime.GetValueOrDefault();
                buildInfoDto.LastBuildTime = new TimeSpan();
                buildInfoDto.PassedNumberOfTests = 0;
                buildInfoDto.RequestedByName = build.RequestedFor.DisplayName;
                buildInfoDto.RequestedByPictureUrl = build.RequestedFor.ImageUrl;
                buildInfoDto.StartBuildDateTime = build.StartTime.GetValueOrDefault();
                buildInfoDto.Status = build.Result.HasValue ?
                        Char.ToLowerInvariant(build.Result.ToString()[0]) + build.Result.ToString().Substring(1)
                    : Char.ToLowerInvariant(build.Status.ToString()[0]) + build.Status.ToString().Substring(1);
                    
                buildInfoDto.TeamProject = definitionReference.Project.Name;
                buildInfoDto.TeamProjectCollection = teamProjectCollection.DisplayName;
                buildInfoDto.TotalNumberOfTests = 0;
                buildInfoDto.Id = "TFS" + definitionReference.Project.Id + definitionReference.Id;

                if (build.Uri == null)
                {
                    continue;
                }

                buildInfoDto.BuildReportUrl = _helperClass.GetReportUrl(teamProjectCollection.Uri != null ? teamProjectCollection.Uri.ToString() : "", definitionReference.Project.Name, build.Uri.ToString());

                if (build.Result.HasValue && build.Result.Value == BuildResult.PartiallySucceeded)
                {
                    var testResults = GetTestResultsRest(teamProjectCollection, definitionReference, build);

                    if (testResults.ContainsKey("PassedTests"))
                    {
                        buildInfoDto.PassedNumberOfTests = testResults["PassedTests"];
                        buildInfoDto.TotalNumberOfTests = testResults["TotalTests"];
                    }
                }

                //Add last succeeded build if in progress
                if (build.Status.HasValue && build.Status.Value == Microsoft.TeamFoundation.Build.WebApi.BuildStatus.InProgress)
                {
                    buildInfoDto.LastBuildTime = await GetLastSuccesfulBuildTimeRest(teamProjectCollection, definitionReference, httpClient).ConfigureAwait(false);
                }

                lock (buildInfoDtos)
                {
                    buildInfoDtos.Add(buildInfoDto);
                }
            }

            return buildInfoDtos;
            }
            catch (Exception exception)
            {
                LogService.WriteError(exception);
                throw;
            }
        }
        public static async Task <BuildInfo> GetArtifactsInfoAsync(this BuildHttpClient azureDevOpsClient, string commit, Build build, CancellationToken cancellationToken)
        {
            if (azureDevOpsClient == null)
            {
                return(null);
            }

            var result = new BuildInfo
            {
                Commit     = commit,
                StartTime  = build.StartTime,
                FinishTime = build.FinishTime,
                Status     = build.Status,
                Result     = build.Result,
            };
            var artifacts = await azureDevOpsClient.GetArtifactsAsync(Config.AzureDevOpsProjectId, build.Id, cancellationToken : cancellationToken).ConfigureAwait(false);

            // windows build
            var windowsBuildArtifact = artifacts.FirstOrDefault(a => a.Name.Contains("Windows"));
            var windowsBuild         = windowsBuildArtifact?.Resource;

            if (windowsBuild?.DownloadUrl is string winDownloadUrl)
            {
                result.WindowsBuildDownloadLink = winDownloadUrl;
                if (windowsBuild.DownloadUrl.Contains("format=zip", StringComparison.InvariantCultureIgnoreCase))
                {
                    try
                    {
                        using var httpClient = HttpClientFactory.Create();
                        using var stream     = await httpClient.GetStreamAsync(winDownloadUrl).ConfigureAwait(false);

                        using var zipStream = ReaderFactory.Open(stream);
                        while (zipStream.MoveToNextEntry() && !cancellationToken.IsCancellationRequested)
                        {
                            if (zipStream.Entry.Key.EndsWith(".7z", StringComparison.InvariantCultureIgnoreCase))
                            {
                                result.WindowsFilename = Path.GetFileName(zipStream.Entry.Key);
                                break;
                            }
                        }
                    }
                    catch (Exception e2)
                    {
                        Config.Log.Error(e2, "Failed to get windows build filename");
                    }
                }
            }

            // linux build
            var linuxBuildArtifact = artifacts.FirstOrDefault(a => a.Name.EndsWith(".GCC") || a.Name.EndsWith("Linux"));
            var linuxBuild         = linuxBuildArtifact?.Resource;

            if (linuxBuild?.DownloadUrl is string linDownloadUrl)
            {
                result.LinuxBuildDownloadLink = linDownloadUrl;
                if (linuxBuild.DownloadUrl.Contains("format=zip", StringComparison.InvariantCultureIgnoreCase))
                {
                    try
                    {
                        using var httpClient = HttpClientFactory.Create();
                        using var stream     = await httpClient.GetStreamAsync(linDownloadUrl).ConfigureAwait(false);

                        using var zipStream = ReaderFactory.Open(stream);
                        while (zipStream.MoveToNextEntry() && !cancellationToken.IsCancellationRequested)
                        {
                            if (zipStream.Entry.Key.EndsWith(".AppImage", StringComparison.InvariantCultureIgnoreCase))
                            {
                                result.LinuxFilename = Path.GetFileName(zipStream.Entry.Key);
                                break;
                            }
                        }
                    }
                    catch (Exception e2)
                    {
                        Config.Log.Error(e2, "Failed to get linux build filename");
                    }
                }
            }
            return(result);
        }
예제 #9
0
        static async Task <int> Main(string[] args)
        {
            string clientId     = "";
            string clientSecret = "";
            bool   showHelp     = false;
            var    parser       = new OptionSet
            {
                {
                    "h|?|help",
                    "Show help.",
                    h => showHelp = h != null
                },
                {
                    "ci=|clientid=",
                    "The client ID to use for authentication token retreival.",
                    id => clientId = id
                },
                {
                    "cs=|clientsecret=",
                    "The client secret to use for authentication token retreival.",
                    secret => clientSecret = secret
                },
            };

            List <string> extraArguments = null;

            try
            {
                extraArguments = parser.Parse(args);
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to parse arguments.");
                Console.WriteLine(e.Message);
                return(1);
            }

            if (extraArguments.Count > 0)
            {
                Console.WriteLine($"Unknown arguments: {string.Join(" ", extraArguments)}");
                return(1);
            }

            if (showHelp)
            {
                parser.WriteOptionDescriptions(Console.Out);
                return(0);
            }

            try
            {
                var authToken = await GetSecret("vslsnap-vso-auth-token", clientId, clientSecret);

                var client          = new BuildHttpClient(new Uri("https://devdiv.visualstudio.com"), new VssBasicCredential("", authToken));
                int buildsProcessed = 0;

                var definitions = new List <BuildDefinitionReference>();
                definitions.AddRange(await client.GetDefinitionsAsync(project: "DevDiv", name: "Roslyn-Signed-Legacy-15.6AndEarlier"));
                definitions.AddRange(await client.GetDefinitionsAsync(project: "DevDiv", name: "Roslyn-Signed"));
                definitions.AddRange(await client.GetDefinitionsAsync(project: "DevDiv", name: "TestImpact-Signed"));

                foreach (var definition in definitions)
                {
                    var folderName = definition.Name == "Roslyn-Signed-Legacy-15.6AndEarlier" ? "Roslyn-Signed" : definition.Name;

                    string dropBase = $@"\\cpvsbuild\drops\roslyn\{folderName}";

                    var builds = await client.GetBuildsAsync(definition.Project.Id, definitions : new[] { definition.Id }, deletedFilter : QueryDeletedOption.IncludeDeleted);

                    foreach (var build in builds)
                    {
                        if (build.Status == BuildStatus.Completed)
                        {
                            string dropPath = Path.Combine(dropBase, Path.GetFileName(build.SourceBranch), "Release", build.BuildNumber);

                            if (Directory.Exists(dropPath))
                            {
                                bool deleted = build.Deleted;

                                if (!deleted)
                                {
                                    // HACK: if your retention policy says to keep the build record (but delete everything else),
                                    // you can't rely on build.Deleted.
                                    var logs = await client.GetBuildLogsAsync(definition.Project.Id, build.Id);

                                    var artifacts = await client.GetArtifactsAsync(definition.Project.Id, build.Id);

                                    if (logs == null && artifacts.Count == 0)
                                    {
                                        deleted = true;
                                    }
                                }

                                if (deleted)
                                {
                                    buildsProcessed++;
                                    Console.WriteLine($"Deleting {dropPath}...");
                                    try
                                    {
                                        Directory.Delete(dropPath, recursive: true);
                                    }
                                    catch (UnauthorizedAccessException)
                                    {
                                        Console.WriteLine("ACCESS EXCEPTION!");
                                    }
                                    catch (DirectoryNotFoundException e)
                                    {
                                        Console.WriteLine(e.Message);
                                    }
                                    catch (IOException e)
                                    {
                                        Console.WriteLine(e.ToString());
                                    }
                                }
                            }
                        }
                    }

                    /*
                     * // Also clean up any now empty branch folders
                     * foreach (var branchFolder in new DirectoryInfo(dropBase).GetDirectories())
                     * {
                     *  var releaseFolder = branchFolder.GetDirectories("Release").SingleOrDefault();
                     *
                     *  if (releaseFolder != null)
                     *  {
                     *      releaseFolder.DeleteIfEmpty();
                     *  }
                     *
                     *  branchFolder.DeleteIfEmpty();
                     * }
                     */
                }

                Console.WriteLine($"Builds processed: {buildsProcessed}");
                return(0);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(1);
            }
        }
예제 #10
0
        public BlobUploadProcessor(ILogger <BlobUploadProcessor> logger, BuildLogProvider logProvider, BlobServiceClient blobServiceClient, BuildHttpClient buildClient, TestResultsHttpClient testResultsClient)
        {
            if (blobServiceClient == null)
            {
                throw new ArgumentNullException(nameof(blobServiceClient));
            }

            this.logger                = logger ?? throw new ArgumentNullException(nameof(logger));
            this.logProvider           = logProvider ?? throw new ArgumentNullException(nameof(logProvider));
            this.buildClient           = buildClient ?? throw new ArgumentNullException(nameof(buildClient));
            this.testResultsClient     = testResultsClient ?? throw new ArgumentNullException(nameof(testResultsClient));
            this.buildsContainerClient = blobServiceClient.GetBlobContainerClient(BuildsContainerName);
            this.buildTimelineRecordsContainerClient = blobServiceClient.GetBlobContainerClient(BuildTimelineRecordsContainerName);
            this.buildLogLinesContainerClient        = blobServiceClient.GetBlobContainerClient(BuildLogLinesContainerName);
            this.testRunsContainerClient             = blobServiceClient.GetBlobContainerClient(TestRunsContainerNameTestRunsContainerName);
        }
예제 #11
0
 public BuildServer(VssConnection connection)
 {
     connection.Settings.SendTimeout = TimeSpan.FromSeconds(300);
     ArgUtil.NotNull(connection, nameof(connection));
     _buildHttpClient = connection.GetClient<BuildHttpClient>();
 }
        public static void AddScreenshots(string tfsURL, string tfsToken, string projectId, string buildDefinitionName, string projectName, string nameOfProjectWithTests)
        {
            var dictionary = DictionaryInteractions.ReadFromPropertiesFile(ReturnPath.SolutionFolderPath() + nameOfProjectWithTests + "/ExtentReport/ReportProperties.txt");

            string[] fileArray       = Directory.GetFiles(dictionary["ReportPath"]);
            var      onlyScreenshots = fileArray.Where(s => s.IndexOf(".png") != -1);

            if (onlyScreenshots.ToList().Count != 0)
            {
                VssConnection     vc  = new VssConnection(new Uri(tfsURL), new VssBasicCredential(string.Empty, tfsToken));
                BuildHttpClient   bhc = vc.GetClient <BuildHttpClient>();
                ProjectHttpClient ddd = vc.GetClient <ProjectHttpClient>();

                //ITestManagementTeamProject ddd1 = ddd.GetProject("hgfyjh");



                var   buildsPerProject = bhc.GetBuildsAsync(projectId).GetAwaiter().GetResult();
                var   lastBuildId      = buildsPerProject.Where <Build>(x => x.Definition.Name == buildDefinitionName).Max <Build>(z => z.Id);
                Build lastBuild        = buildsPerProject.FirstOrDefault <Build>(x => x.Id == lastBuildId);

                Console.Write("Last Build Number: " + lastBuildId);
                TestManagementHttpClient ithc = vc.GetClient <TestManagementHttpClient>();
                QueryModel     qm             = new QueryModel("Select * From TestRun Where BuildNumber Contains '" + lastBuild.BuildNumber + "'");
                List <TestRun> testruns       = ithc.GetTestRunsByQueryAsync(qm, projectName).Result;
                Console.Write("testruns.Count: " + testruns.Count);

                foreach (TestRun testrun in testruns)
                {
                    List <TestCaseResult> testresults = ithc.GetTestResultsAsync(projectName, testrun.Id).Result;
                    Console.Write("testresults.Count: " + testresults.Count);
                    foreach (TestCaseResult tcr in testresults)
                    {
                        var testNamesFromScreents = onlyScreenshots.Select(s => s.ToLower().Split(new string[] { "sec\\" }, StringSplitOptions.None)[1].Split(new string[] { "20" }, StringSplitOptions.None)[0]).Distinct();
                        //var screentsShotPerTest = onlyScreenshots.Where(s => s.Split(new string[] { "sec\\" }, StringSplitOptions.None)[1].Split(new string[] { "20" }, StringSplitOptions.None)[0] == scenarioName.Replace(" ", string.Empty));

                        Console.WriteLine("tcr.Id: " + tcr.Id);
                        if (testNamesFromScreents.ToList().Contains(tcr.AutomatedTestName.Split('.').Last().ToLower()))
                        {
                            Console.WriteLine("recognize Test: " + tcr.AutomatedTestName.Split('.').Last().ToLower());
                            using (var client = new HttpClient())
                            {
                                string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", tfsToken)));
                                client.BaseAddress = new Uri(tfsURL);  //url of our account
                                client.DefaultRequestHeaders.Accept.Clear();
                                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
                                var screentsShotPerTest = onlyScreenshots.Where(s => s.Split(new string[] { "sec\\" }, StringSplitOptions.None)[1].Split(new string[] { "20" }, StringSplitOptions.None)[0].ToLower() == tcr.AutomatedTestName.Split('.').Last().ToLower());

                                foreach (var screenshot in screentsShotPerTest)
                                {
                                    Console.WriteLine("screentsShotPerTest: " + screenshot);
                                    var post = new PostImageTfs()
                                    {
                                        Stream         = Convert.ToBase64String(File.ReadAllBytes(screenshot)),
                                        AttachmentType = "GeneralAttachment",
                                        Comment        = "screenshot of error",
                                        FileName       = screenshot.Split(new string[] { "sec\\" }, StringSplitOptions.None)[1]
                                    };
                                    Console.WriteLine("tcr.TestRun.Id: " + tcr.TestRun.Id);
                                    Console.WriteLine("tcr.Id: " + tcr.Id);
                                    Console.WriteLine("screenshot.Split(new string[] { DateTime.Now.Year.ToString() }, StringSplitOptions.None)[2] " + screenshot.Split(new string[] { DateTime.Now.Year.ToString() }, StringSplitOptions.None)[2]);

                                    var test = new StringContent($"{{\"stream\": \"{post.Stream}\",\"fileName\": \"{post.FileName}\",\"comment\": \"{post.Comment}\",\"attachmentType\": \"{post.AttachmentType}\"}}", Encoding.UTF8, "application/json");

                                    HttpResponseMessage response = client.PostAsync("/DefaultCollection/" + projectName + "/_apis/test/runs/" + tcr.TestRun.Id + "/results/" + tcr.Id + "/attachments?api-version=2.0-preview.1", test).Result;
                                    Console.WriteLine("response: " + response.StatusCode);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Connect to TFS - this may ask the user for credentials, depending on the status of the connection
        /// </summary>
        /// <returns></returns>
        public async Task Connect()
        {
            /*
             * eg: https://company.visualstudio.com/defaultcollection/_apis/projects?api-version=1.0
             *
             * // Create instance of VssConnection using AD Credentials for AD backed account
             * VssConnection connection = new VssConnection(new Uri(collectionUri), new VssAadCredential());
             *
             * // VssCredentials - NTLM against an on-prem server
             * VssConnection connection = new VssConnection(new Uri(tfsUri), new VssCredentials());
             *
             * // VssConnection - VS sign in prompt
             * VssConnection connection = new VssConnection(new Uri(collectionUri), new VssClientCredentials());
             *
             */

            var tfsUri = _configManager.TfsDefaultCollectionUrl;

            if (tfsUri == null)
            {
                return;
            }

            // Use VS client credentails, including default windows credential store for caching
            VssClientCredentialStorage storage = new VssClientCredentialStorage();
            var creds = new VssClientCredentials();

            creds.Storage = storage;

            // attempt to connect
            try
            {
                _currentConnection = new VssConnection(tfsUri, creds);
                await _currentConnection.ConnectAsync(VssConnectMode.Automatic);
            }
            catch (TaskCanceledException)
            {
                //todo - set some application state to reflect not logged in status
                return;
            }
            catch (VssServiceException)
            {
                // something bad happened - can't do a lot here...
                return;
            }

            if (_currentConnection.HasAuthenticated)
            {
                // update app with logged in credentials, if present.
                var details = new UserDetails();

                details.DisplayName = _currentConnection.AuthorizedIdentity?.DisplayName;
                string connectedAccount = null;
                if (_currentConnection.AuthorizedIdentity?.Properties?.TryGetValue("Account", out connectedAccount) ==
                    true)
                {
                    details.Account = connectedAccount;
                }
                _configManager.SetUserDetails(details);

                // get an REST wrapper for the build APIs
                _BuildClient = await _currentConnection.GetClientAsync <Microsoft.TeamFoundation.Build.WebApi.BuildHttpClient>();
            }
        }
예제 #14
0
 internal TfsBuildHelper(Uri tpcUrl)
 {
     this.connection = new VssConnection(tpcUrl, new VssClientCredentials(true));
     this.client     = connection.GetClient <BuildHttpClient>();
 }
예제 #15
0
        static void Main(string[] args)
        {
            OptionSet option_set = new OptionSet()
                                   .Add("?|help|h", "Prints out the options.", option => { help = option != null; })
                                   .Add("su|source-url=", "Set the source VSTS account URL (https://[sourcerepo].visualstudio.com)", option => sourceUrl = option)
                                   .Add("sp|source-project=", "Set the source VSTS project", option => sourceProject = option)
                                   .Add("sr|source-repository=", "Set the source VSTS repository path. (ex: $/SourceRepo)", option => sourceRepo = option)
                                   .Add("du|destination-url=", "Set the destination VSTS account URL (https://[destrepo].visualstudio.com)", option => destinationUrl = option)
                                   .Add("dp|destination-project=", "Set the destination VSTS project", option => destinationProject = option)
                                   .Add("dr|destination-repository=", "Set the destination VSTS repository path. (ex: $/DestinationRepo)", option => destinationRepo = option);

            try
            {
                option_set.Parse(args);
            }
            catch (Exception ex)
            {
                LogGenericException(ex, "Error on commandline parse");
            }
            if (help)
            {
                ShowHelp(usage, option_set);
            }

            if (string.IsNullOrEmpty(sourceUrl))
            {
                Console.Write("Enter the source account url (https://<<account>>.visualstudio.com/): ");
                sourceUrl = Console.ReadLine();
            }
            if (string.IsNullOrEmpty(sourceProject))
            {
                Console.Write("Enter the source project: ");
                sourceProject = Console.ReadLine();
            }
            if (string.IsNullOrEmpty(sourceRepo))
            {
                Console.Write("Enter the source repository ($/MYSOURCEREPO): ");
                sourceRepo = Console.ReadLine();
            }

            if (string.IsNullOrEmpty(destinationUrl))
            {
                Console.Write("Enter the destination account url (https://<<account>>.visualstudio.com/): ");
                destinationUrl = Console.ReadLine();
            }
            if (string.IsNullOrEmpty(destinationProject))
            {
                Console.Write("Enter the destination project: ");
                destinationProject = Console.ReadLine();
            }
            if (string.IsNullOrEmpty(destinationRepo))
            {
                Console.Write("Enter the source repository ($/MYDESTREPO): ");
                destinationRepo = Console.ReadLine();
            }

            string sourceAccount      = $"{sourceUrl}DefaultCollection";
            string destinationAccount = $"{destinationUrl}DefaultCollection";

            // Interactively ask the user for credentials

            VssCredentials sourceCredentials = new VssClientCredentials();

            sourceCredentials.Storage = new VssClientCredentialStorage();

            VssCredentials destinationCredentials = new VssClientCredentials();

            destinationCredentials.Storage = new VssClientCredentialStorage();

            BuildHttpClient     sourceBuildClient          = null;
            BuildHttpClient     destinationBuildClient     = null;
            ProjectHttpClient   destinationProjectClient   = null;
            TaskAgentHttpClient destinationTaskAgentClient = null;
            TfvcHttpClient      destinationTfvcClient      = null;

            try
            {
                Console.WriteLine($"Creating VSTS connections and clients.");
                Console.WriteLine();
                // Connect to VSTS Source and Destination
                VssConnection sourceConnection = new VssConnection(new Uri(sourceAccount), sourceCredentials);
                Console.WriteLine($"Authorized acccount {sourceUrl} as {sourceConnection.AuthorizedIdentity.DisplayName} <{sourceConnection.AuthorizedIdentity.Descriptor.Identifier}>");
                VssConnection destinationConnection = new VssConnection(new Uri(destinationAccount), destinationCredentials);
                Console.WriteLine($"Authorized acccount {destinationUrl} as {destinationConnection.AuthorizedIdentity.DisplayName} <{sourceConnection.AuthorizedIdentity.Descriptor.Identifier}>");
                Console.WriteLine();
                // Get a number of HttpClients to read and write data
                Console.WriteLine("Creating source build client.");
                sourceBuildClient = sourceConnection.GetClient <BuildHttpClient>();
                Console.WriteLine("Creating destination build client.");
                destinationBuildClient = destinationConnection.GetClient <BuildHttpClient>();
                Console.WriteLine("Creating destination project client.");
                destinationProjectClient = destinationConnection.GetClient <ProjectHttpClient>();
                Console.WriteLine("Creating destination task agent client.");
                destinationTaskAgentClient = destinationConnection.GetClient <TaskAgentHttpClient>();
                Console.WriteLine("Creating destination TFVC client.");
                destinationTfvcClient = destinationConnection.GetClient <TfvcHttpClient>();
                Console.WriteLine();
            }
            catch (AggregateException ex)
            {
                string message = "Error creating connections.";
                LogAggregateException(ex, message);
            }
            catch (Exception ex)
            {
                string message = "Error creating connections.";
                LogGenericException(ex, message);
            }

            List <BuildDefinition> sourceBuildDefs              = null;
            TeamProject            destinationProjectObject     = null;
            Dictionary <string, TaskAgentQueue> agentDictionary = null;

            try
            {
                sourceBuildDefs = sourceBuildClient.GetFullDefinitionsAsync(project: sourceProject).Result;
            }
            catch (AggregateException ex)
            {
                string message = "Error retreiving objects from source.";
                LogAggregateException(ex, message);
            }
            catch (Exception ex)
            {
                string message = "Error retreiving objects from source.";
                LogGenericException(ex, message);
            }

            try
            {
                destinationProjectObject = destinationProjectClient.GetProject(destinationProject).Result;
                var projectAgentQueues = destinationTaskAgentClient.GetAgentQueuesAsync(project: destinationProject).Result;
                agentDictionary = projectAgentQueues.ToDictionary(k => k.Name);
            }
            catch (AggregateException ex)
            {
                string message = "Error retreiving objects from destination.";
                LogAggregateException(ex, message);
            }
            catch (Exception ex)
            {
                string message = "Error retreiving objects from destination.";
                LogGenericException(ex, message);
            }

            foreach (var item in sourceBuildDefs)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    item.Name = item.Name + DateTime.Now.ToUnixEpochTime();
                }

                item.Project    = destinationProjectObject;
                item.AuthoredBy = null; // Remove any author to avoid errors in transfer

                FixTriggerRepositories(item);
                UpdateAgentPool(agentDictionary, item);
                ConvertRepositoryPath(item);

                try
                {
                    Console.WriteLine($"Adding build definition: {item.Name}");
                    var itemOut = destinationBuildClient.CreateDefinitionAsync(item).Result;
                }
                catch (AggregateException ex)
                {
                    LogAggregateException(ex, $"Error creating build {item.Name} on {destinationAccount}");
                }
                catch (Exception ex)
                {
                    LogGenericException(ex, $"Error creating build {item.Name} on {destinationAccount}");
                }
            }
            if (hasErrors)
            {
                ExitWithErrors();
            }
            ExitSuccess();
        }
예제 #16
0
        static void Main(string[] args)
        {
            var client          = new BuildHttpClient(new Uri("https://devdiv.visualstudio.com"), new VssBasicCredential("", GetSecret("vslsnap-vso-auth-token").Result));
            int buildsProcessed = 0;

            var definitions = new List <BuildDefinitionReference>();

            definitions.AddRange(client.GetDefinitionsAsync(project: "DevDiv", name: "Roslyn-Signed-Legacy-15.6AndEarlier").Result);
            definitions.AddRange(client.GetDefinitionsAsync(project: "DevDiv", name: "Roslyn-Signed").Result);
            definitions.AddRange(client.GetDefinitionsAsync(project: "DevDiv", name: "TestImpact-Signed").Result);

            foreach (var definition in definitions)
            {
                var folderName = definition.Name == "Roslyn-Signed-Legacy-15.6AndEarlier" ? "Roslyn-Signed" : definition.Name;

                string dropBase = $@"\\cpvsbuild\drops\roslyn\{folderName}";

                var builds = client.GetBuildsAsync(definition.Project.Id, definitions: new[] { definition.Id }, deletedFilter: QueryDeletedOption.IncludeDeleted).Result;

                foreach (var build in builds)
                {
                    if (build.Status == BuildStatus.Completed)
                    {
                        string dropPath = Path.Combine(dropBase, Path.GetFileName(build.SourceBranch), "Release", build.BuildNumber);

                        if (Directory.Exists(dropPath))
                        {
                            bool deleted = build.Deleted;

                            if (!deleted)
                            {
                                // HACK: if your retention policy says to keep the build record (but delete everything else),
                                // you can't rely on build.Deleted.
                                var logs      = client.GetBuildLogsAsync(definition.Project.Id, build.Id).Result;
                                var artifacts = client.GetArtifactsAsync(definition.Project.Id, build.Id).Result;

                                if (logs == null && artifacts.Count == 0)
                                {
                                    deleted = true;
                                }
                            }

                            if (deleted)
                            {
                                buildsProcessed++;
                                Console.WriteLine($"Deleting {dropPath}...");
                                try
                                {
                                    Directory.Delete(dropPath, recursive: true);
                                }
                                catch (UnauthorizedAccessException)
                                {
                                    Console.WriteLine("ACCESS EXCEPTION!");
                                }
                                catch (DirectoryNotFoundException e)
                                {
                                    Console.WriteLine(e.Message);
                                }
                                catch (IOException e)
                                {
                                    Console.WriteLine(e.ToString());
                                }
                            }
                        }
                    }
                }

                /*
                 * // Also clean up any now empty branch folders
                 * foreach (var branchFolder in new DirectoryInfo(dropBase).GetDirectories())
                 * {
                 *  var releaseFolder = branchFolder.GetDirectories("Release").SingleOrDefault();
                 *
                 *  if (releaseFolder != null)
                 *  {
                 *      releaseFolder.DeleteIfEmpty();
                 *  }
                 *
                 *  branchFolder.DeleteIfEmpty();
                 * }
                 */
            }

            Console.WriteLine($"Builds processed: {buildsProcessed}");
        }
예제 #17
0
        private async Task DownloadArtifactAsync(
            IExecutionContext executionContext,
            ServerBuildArtifact buildArtifact,
            ArtifactDefinition artifactDefinition,
            string localFolderPath,
            BuildHttpClient buildClient,
            XamlBuildHttpClient xamlBuildClient,
            DefinitionType definitionType,
            int buildId)
        {
            var downloadFolderPath = Path.Combine(localFolderPath, buildArtifact.Name);
            var buildArtifactDetails = artifactDefinition.Details as BuildArtifactDetails;
            if ((buildArtifact.Resource.Type == null && buildArtifact.Id == 0) // bug on build API Bug 378900
                || string.Equals(buildArtifact.Resource.Type, WellKnownArtifactResourceTypes.FilePath, StringComparison.OrdinalIgnoreCase))
            {
                executionContext.Output("Artifact Type: FileShare");
                string fileShare;
                if (buildArtifact.Id == 0)
                {
                    fileShare = new Uri(buildArtifact.Resource.DownloadUrl).LocalPath;
                }
                else
                {
                    fileShare = new Uri(Path.Combine(buildArtifact.Resource.DownloadUrl, buildArtifact.Name)).LocalPath;
                    if (!Directory.Exists(fileShare))
                    {
                        // download path does not exist, log and fall back
                        var parenthPath = new Uri(buildArtifact.Resource.DownloadUrl).LocalPath;
                        executionContext.Output(StringUtil.Loc("RMArtifactNameDirectoryNotFound", fileShare, parenthPath));
                        fileShare = parenthPath;
                    }
                }

                if (!Directory.Exists(fileShare))
                {
                    // download path does not exist, raise exception
                    throw new ArtifactDownloadException(StringUtil.Loc("RMArtifactDirectoryNotFoundError", fileShare));
                }

                executionContext.Output(StringUtil.Loc("RMDownloadingArtifactFromFileShare", fileShare));

                var fileShareArtifact = new FileShareArtifact();
                await fileShareArtifact.DownloadArtifactAsync(executionContext, HostContext, artifactDefinition, fileShare, downloadFolderPath);
            }
            else if (string.Equals(buildArtifact.Resource.Type, WellKnownArtifactResourceTypes.Container, StringComparison.OrdinalIgnoreCase))
            {
                executionContext.Output("Artifact Type: ServerDrop");

                // TODO:Get VssBinFetchclient and get away from zipstream downloader
                Stream contentStream;
                
                if (definitionType == DefinitionType.Xaml)
                {
                    contentStream = await xamlBuildClient.GetArtifactContentZipAsync(buildArtifactDetails.Project, buildId, buildArtifact.Name);
                }
                else
                {
                    contentStream = await buildClient.GetArtifactContentZipAsync(buildArtifactDetails.Project, buildId, buildArtifact.Name);
                }
                

                var zipStreamDownloader = HostContext.GetService<IZipStreamDownloader>();
                string artifactRootFolder = StringUtil.Format("/{0}", buildArtifact.Name);
                await zipStreamDownloader.DownloadFromStream(contentStream, artifactRootFolder, buildArtifactDetails.RelativePath, downloadFolderPath);
            }
            else
            {
                executionContext.Warning(StringUtil.Loc("RMArtifactTypeNotSupported", buildArtifact.Resource.Type));
            }
        }
예제 #18
0
        private async Task DownloadArtifactAsync(
            IExecutionContext executionContext,
            ServerBuildArtifact buildArtifact,
            ArtifactDefinition artifactDefinition,
            string localFolderPath,
            BuildHttpClient buildClient,
            XamlBuildHttpClient xamlBuildClient,
            DefinitionType definitionType,
            int buildId)
        {
            var downloadFolderPath   = Path.Combine(localFolderPath, buildArtifact.Name);
            var buildArtifactDetails = artifactDefinition.Details as BuildArtifactDetails;

            if ((buildArtifact.Resource.Type == null && buildArtifact.Id == 0) || // bug on build API Bug 378900
                string.Equals(buildArtifact.Resource.Type, WellKnownArtifactResourceTypes.FilePath, StringComparison.OrdinalIgnoreCase))
            {
                executionContext.Output("Artifact Type: FileShare");
                string fileShare;
                if (buildArtifact.Id == 0)
                {
                    fileShare = new Uri(buildArtifact.Resource.DownloadUrl).LocalPath;
                }
                else
                {
                    fileShare = new Uri(Path.Combine(buildArtifact.Resource.DownloadUrl, buildArtifact.Name)).LocalPath;
                    if (!Directory.Exists(fileShare))
                    {
                        // download path does not exist, log and fall back
                        var parenthPath = new Uri(buildArtifact.Resource.DownloadUrl).LocalPath;
                        executionContext.Output(StringUtil.Loc("RMArtifactNameDirectoryNotFound", fileShare, parenthPath));
                        fileShare = parenthPath;
                    }
                }

                if (!Directory.Exists(fileShare))
                {
                    // download path does not exist, raise exception
                    throw new ArtifactDownloadException(StringUtil.Loc("RMArtifactDirectoryNotFoundError", fileShare));
                }

                executionContext.Output(StringUtil.Loc("RMDownloadingArtifactFromFileShare", fileShare));

                var fileShareArtifact = new FileShareArtifact();
                await fileShareArtifact.DownloadArtifactAsync(executionContext, HostContext, artifactDefinition, fileShare, downloadFolderPath);
            }
            else if (string.Equals(buildArtifact.Resource.Type, WellKnownArtifactResourceTypes.Container, StringComparison.OrdinalIgnoreCase))
            {
                executionContext.Output("Artifact Type: ServerDrop");

                // TODO:Get VssBinFetchclient and get away from zipstream downloader
                Stream contentStream;

                if (definitionType == DefinitionType.Xaml)
                {
                    contentStream = await xamlBuildClient.GetArtifactContentZipAsync(buildArtifactDetails.Project, buildId, buildArtifact.Name);
                }
                else
                {
                    contentStream = await buildClient.GetArtifactContentZipAsync(buildArtifactDetails.Project, buildId, buildArtifact.Name);
                }


                var    zipStreamDownloader = HostContext.GetService <IZipStreamDownloader>();
                string artifactRootFolder  = StringUtil.Format("/{0}", buildArtifact.Name);
                await zipStreamDownloader.DownloadFromStream(contentStream, artifactRootFolder, buildArtifactDetails.RelativePath, downloadFolderPath);
            }
            else
            {
                executionContext.Warning(StringUtil.Loc("RMArtifactTypeNotSupported", buildArtifact.Resource.Type));
            }
        }