public async void Should_Output_ReleaseNote() { // Given var options = new ReleaseOptions { MileStone = "v1.0.0", Owner = "root", Repository = "test" }; var dbContext = EnsureDbCreated(options); var service = new ReleaseService(dbContext, FakeConsole); // When var result = await service.Execute(options, new Mock <IGitHubClient>().Object); // Then Assert.Equal(0, result); Assert.Single(FakeConsole.Messages); Assert.Equal( @"As part of this release we had 3 issues closed. The highest priority among them is ""high"". ### Bug * Found a bug! #1 * Another bug #2 ### Enhancement * Some improvement on build #3 ", FakeConsole.Messages[0], ignoreLineEndingDifferences: true); Assert.Empty(FakeConsole.WarnMessages); Assert.Empty(FakeConsole.ErrorMessages); }
public async void PullRequest_Already_Exists() { // Given var options = new ReleaseOptions { CreatePullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test" }; var dbContext = EnsureDbCreated(options); var service = new ReleaseService(dbContext, FakeConsole); var gitbucketClient = new Mock <IGitHubClient>(); gitbucketClient .Setup(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>())) .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest> { new FakePullRequest(new FakeGitReference("develop"), new FakeGitReference("master")) })); // When var result = await service.Execute(options, gitbucketClient.Object); // Then Assert.Equal(1, result); Assert.Empty(FakeConsole.Messages); Assert.Single(FakeConsole.WarnMessages); Assert.Equal("A pull request already exists for root:develop.", FakeConsole.WarnMessages[0]); Assert.Empty(FakeConsole.ErrorMessages); }
private async Task <int> CreatePullRequest( ReleaseOptions options, List <Core.Models.Issue> issues, List <Core.Models.IssueLabel> issueLabels, string pullRequestSource, List <Core.Models.Label> labels, IGitHubClient gitBucketClient) { // Check if specified pull request already exists var pullRequests = await gitBucketClient.PullRequest.GetAllForRepository(options.Owner, options.Repository); if (pullRequests.Any(p => p.Head.Ref == options.Head && p.Base.Ref == options.Base)) { _console.WriteWarnLine($"A pull request already exists for {options.Owner}:{options.Head}."); return(await Task.FromResult(1)); } var releaseNote = CreateReleaseNote(issues, issueLabels, pullRequestSource, labels); try { // Create new pull request await gitBucketClient.PullRequest.Create( options.Owner, options.Repository, new NewPullRequest( title : options.Title ?? options.MileStone, head : options.Head, baseRef : options.Base) { Body = releaseNote, Draft = options.Draft, }); } catch (InvalidCastException) { // Ignore InvalidCastException because of escaped response. // https://github.com/gitbucket/gitbucket/issues/2306 } var allPRs = await gitBucketClient.PullRequest.GetAllForRepository(options.Owner, options.Repository); var latest = allPRs.OrderByDescending(p => p.Number).First(); // Add all labels which corresponding issues have. // If there is not the same name label, GitBucket creates one automatically. await gitBucketClient.Issue.Labels.AddToIssue( options.Owner, options.Repository, latest.Number, labels.Select(l => l.LabelName).ToArray()); _console.WriteLine($"A new pull request has been successfully created!"); return(await Task.FromResult(0)); }
private async Task <List <GitBucket.Core.Models.IssueLabel> > FindIssueLabels( ReleaseOptions options, IEnumerable <GitBucket.Core.Models.Issue> issues) { #pragma warning disable CA1304 // Specify CultureInfo // "String.Equals(String, StringComparison)" causes client side evaluation. // https://github.com/aspnet/EntityFrameworkCore/issues/1222 return(await _context.Set <GitBucket.Core.Models.IssueLabel>() .Where(l => l.UserName.ToLower() == options.Owner.ToLower()) .Where(l => l.RepositoryName.ToLower() == options.Repository.ToLower()) .Where(l => issues.Select(i => i.IssueId).Contains(l.IssueId)) .AsNoTracking() .ToListAsync()); }
private List <Core.Models.Label> FindLabels(ReleaseOptions options, List <IssueLabel> issueLabels) { #pragma warning disable CA1304 // Specify CultureInfo return(_context.Set <Core.Models.Label>() .Where(l => l.UserName.ToLower() == options.Owner.ToLower() && l.RepositoryName.ToLower() == options.Repository.ToLower() && issueLabels.Select(i => i.LabelId).Contains(l.LabelId)) .OrderBy(i => i.LabelId) .AsNoTracking() .ToList()); #pragma warning restore CA1304 // Specify CultureInfo }
public async Task <int> Execute(ReleaseOptions options, IGitHubClient gitBucketClient) { ArgumentNullException.ThrowIfNull(options); ArgumentNullException.ThrowIfNull(gitBucketClient); var pullRequestSource = options.FromPullRequest ? "pull requests" : "issues"; var issues = await FindIssuesRelatedToMileStone(options); if (!issues.Any()) { _console.WriteWarnLine($"There are no {pullRequestSource} related to \"{options.MileStone}\"."); return(await Task.FromResult(1)); } if (!options.Force && issues.Any(i => !i.Closed)) { _console.WriteWarnLine($"There are unclosed {pullRequestSource} in \"{options.MileStone}\"."); _console.WriteWarn("Do you want to continue?([Y]es/[N]o): "); var yesOrNo = _console.ReadLine(); if (!string.Equals(yesOrNo, "y", StringComparison.OrdinalIgnoreCase) && !string.Equals(yesOrNo, "yes", StringComparison.OrdinalIgnoreCase)) { return(await Task.FromResult(1)); } _console.WriteLine(""); } var issueLabels = await FindIssueLabels(options, issues); if (issues.Any(i => !issueLabels.Select(l => l.IssueId).Contains(i.IssueId))) { _console.WriteWarnLine($"There are issues which have no labels in \"{options.MileStone}\"."); return(await Task.FromResult(1)); } var labels = FindLabels(options, issueLabels); if (options.CreatePullRequest) { return(await CreatePullRequest(options, issues, issueLabels, pullRequestSource, labels, gitBucketClient)); } else { return(await OutputReleaseNote(issues, issueLabels, pullRequestSource, labels)); } }
public async void Milestone_Has_Issue_Without_Labels() { // Given var options = new ReleaseOptions { MileStone = "v1.0.0", Owner = "root", Repository = "test" }; var dbContextOptions = new DbContextOptionsBuilder <GitBucketDbContext>() .UseInMemoryDatabase(databaseName: "Milestone_Has_Issue_Without_Labels") .Options; var dbContext = new GitBucketDbContext(dbContextOptions); dbContext.Issues.Add(new Core.Models.Issue { Milestone = new Core.Models.Milestone { RepositoryName = options.Repository, Title = options.MileStone, UserName = options.Owner, }, RepositoryName = options.Repository, UserName = options.Owner, OpenedUserName = "******", Title = "Implement xxx feature", }); dbContext.SaveChanges(); var service = new ReleaseService(dbContext, FakeConsole); // When var result = await service.Execute(options, new Mock <IGitHubClient>().Object); // Then Assert.Equal(1, result); Assert.Single(FakeConsole.Messages); Assert.Equal("", FakeConsole.Messages[0]); Assert.Equal(3, FakeConsole.WarnMessages.Count); Assert.Equal("There are unclosed issues in \"v1.0.0\".", FakeConsole.WarnMessages[0]); Assert.Equal("Do you want to continue?([Y]es/[N]o): yes", FakeConsole.WarnMessages[1]); Assert.Equal("There are issues which have no labels in \"v1.0.0\".", FakeConsole.WarnMessages[2]); Assert.Empty(FakeConsole.ErrorMessages); }
private void ReleaseAllConfigurations(ICheckNotifier notifier, params ExtractionConfiguration[] extractionConfigurations) { var releasePipeline = _repos.CatalogueRepository.GetAllObjects <Pipeline>().FirstOrDefault(p => p?.Destination?.Class == typeof(BasicDataReleaseDestination).FullName); try { //cleanup any old releases var project = extractionConfigurations.Select(ec => ec.Project).Distinct().Single(); var folderProvider = new ReleaseFolderProvider(); var dir = folderProvider.GetFromProjectFolder(project); if (dir.Exists) { dir.Delete(true); } } catch (Exception ex) { notifier.OnCheckPerformed(new CheckEventArgs("Could not detect/delete release folder for extractions", CheckResult.Warning, ex)); return; } if (releasePipeline != null) { try { var optsRelease = new ReleaseOptions() { Configurations = extractionConfigurations.Select(ec => ec.ID).Distinct().ToArray(), Pipeline = releasePipeline.ID }; var runnerRelease = new ReleaseRunner(optsRelease); runnerRelease.Run(_repos, new ThrowImmediatelyDataLoadEventListener(), notifier, new GracefulCancellationToken()); } catch (Exception ex) { notifier.OnCheckPerformed(new CheckEventArgs("Could not Release ExtractionConfiguration (nevermind)", CheckResult.Warning, ex)); } } }
public NewProfileVM(ConfigurationVM config, Action <ProfileVM> postRun) { ReleaseOptions.AddRange(EnumExt.GetValues <GameRelease>()); this.WhenAnyValue(x => x.SelectedGame) .Subscribe(game => { if (game == null) { return; } var profile = new ProfileVM(config, game.Value) { Nickname = Nickname }; config.Profiles.AddOrUpdate(profile); postRun(profile); }) .DisposeWith(this); }
public async void Milestone_Has_No_PullRequest() { // Given var dbContextOptions = new DbContextOptionsBuilder <GitBucketDbContext>() .UseInMemoryDatabase(databaseName: "Milestone_Has_No_PullRequest") .Options; var dbContext = new GitBucketDbContext(dbContextOptions); var options = new ReleaseOptions { FromPullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test" }; var service = new ReleaseService(dbContext, FakeConsole); // When var result = await service.Execute(options, new Mock <IGitHubClient>().Object); // Then Assert.Equal(1, result); Assert.Empty(FakeConsole.Messages); Assert.Single(FakeConsole.WarnMessages); Assert.Empty(FakeConsole.ErrorMessages); Assert.Equal("There are no pull requests related to \"v1.0.0\".", FakeConsole.WarnMessages[0]); }
private static GitBucketDbContext EnsureDbCreated(ReleaseOptions options) { var dbContextOptions = new DbContextOptionsBuilder <GitBucketDbContext>() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .Options; var dbContext = new GitBucketDbContext(dbContextOptions); var milestone = new Core.Models.Milestone { RepositoryName = options.Repository, Title = options.MileStone, UserName = options.Owner, }; var highPriority = new Core.Models.Priority { Ordering = 0, PriorityName = "high", RepositoryName = options.Repository, UserName = options.Owner, Color = "red", }; var defaultPriority = new Core.Models.Priority { Ordering = 1, PriorityName = "default", RepositoryName = options.Repository, UserName = options.Owner, Color = "red", }; dbContext.Issues.AddRange(new List <Core.Models.Issue> { new Core.Models.Issue { Closed = true, IssueId = 1, Milestone = milestone, Priority = highPriority, RepositoryName = options.Repository, Title = "Found a bug!", UserName = options.Owner, OpenedUserName = "******", }, new Core.Models.Issue { Closed = true, IssueId = 2, Milestone = milestone, Priority = defaultPriority, RepositoryName = options.Repository, Title = "Another bug", UserName = options.Owner, OpenedUserName = "******", }, new Core.Models.Issue { Closed = true, IssueId = 3, Milestone = milestone, Priority = defaultPriority, RepositoryName = options.Repository, Title = "Some improvement on build", UserName = options.Owner, OpenedUserName = "******", }, new Core.Models.Issue { Closed = true, IssueId = 4, Milestone = milestone, Priority = defaultPriority, PullRequest = true, RepositoryName = options.Repository, Title = "Fix a bug", UserName = options.Owner, OpenedUserName = "******", } }); dbContext.IssueLabels.AddRange(new List <Core.Models.IssueLabel> { new Core.Models.IssueLabel { IssueId = 1, LabelId = 10, RepositoryName = options.Repository, UserName = options.Owner, }, new Core.Models.IssueLabel { IssueId = 2, LabelId = 10, RepositoryName = options.Repository, UserName = options.Owner, }, new Core.Models.IssueLabel { IssueId = 3, LabelId = 30, RepositoryName = options.Repository, UserName = options.Owner, }, new Core.Models.IssueLabel { IssueId = 4, LabelId = 10, RepositoryName = options.Repository, UserName = options.Owner, } }); dbContext.Labels.AddRange(new List <Core.Models.Label> { new Core.Models.Label { LabelId = 10, LabelName = "Bug", RepositoryName = options.Repository, UserName = options.Owner, Color = "red", }, new Core.Models.Label { LabelId = 30, LabelName = "Enhancement", RepositoryName = options.Repository, UserName = options.Owner, Color = "red", } }); dbContext.SaveChanges(); return(dbContext); }
public async void Should_Create_PullRequest_With_Different_Options() { // Given var options = new ReleaseOptions { Base = "release/v1.0.0", CreatePullRequest = true, FromPullRequest = true, Head = "master2", MileStone = "v1.0.0", Owner = "root", Repository = "test", Title = "Amazing PR", }; var dbContext = EnsureDbCreated(options); var service = new ReleaseService(dbContext, FakeConsole); var gitbucketClient = new Mock <IGitHubClient>(); gitbucketClient .SetupSequence(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>())) .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest> { new FakePullRequest(new FakeGitReference("improve-performance"), new FakeGitReference("master")) })) .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest> { new FakePullRequest(new FakeGitReference("improve-performance"), new FakeGitReference("master")), new FakePullRequest(new FakeGitReference("release/v1.0.0"), new FakeGitReference("master"), 2) })); var body = string.Empty; gitbucketClient .Setup(g => g.PullRequest.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <NewPullRequest>())) .Callback((string owner, string name, NewPullRequest newPullRequest) => body = newPullRequest.Body) .ThrowsAsync(new InvalidCastException("Ignore InvalidCastException because of escaped response.")); gitbucketClient.Setup(g => g.Issue.Labels.AddToIssue(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <string[]>())); // When var result = await service.Execute(options, gitbucketClient.Object); // Then Assert.Equal(0, result); gitbucketClient .Verify(g => g.PullRequest.Create( It.Is <string>(o => o == "root"), It.Is <string>(r => r == "test"), It.Is <NewPullRequest>(p => p.Title == "Amazing PR" && p.Head == "master2" && p.Base == "release/v1.0.0"))); Assert.Equal(@"As part of this release we had 1 pull requests closed. The highest priority among them is ""default"". ### Bug * Fix a bug #4 ", body, ignoreLineEndingDifferences: true); Assert.Single(FakeConsole.Messages); Assert.Equal("A new pull request has been successfully created!", FakeConsole.Messages[0]); Assert.Empty(FakeConsole.WarnMessages); Assert.Empty(FakeConsole.ErrorMessages); }
public async void Should_Create_Draft_PullRequest() { // Given var options = new ReleaseOptions { Draft = true, CreatePullRequest = true, MileStone = "v1.0.0", Owner = "root", Repository = "test" }; var dbContext = EnsureDbCreated(options); dbContext.PullRequests.AddRange(new List <Core.Models.PullRequest> { new Core.Models.PullRequest { UserName = "******", RepositoryName = "test", RequestBranch = "develop", Branch = "master", IssueId = 1, CommitIdFrom = "test", CommitIdTo = "test", RequestRepositoryName = "test", RequestUserName = "******" }, new Core.Models.PullRequest { UserName = "******", RepositoryName = "test", RequestBranch = "develop", Branch = "master", IssueId = 2, CommitIdFrom = "test", CommitIdTo = "test", RequestRepositoryName = "test", RequestUserName = "******" }, }); dbContext.SaveChanges(); var service = new ReleaseService(dbContext, FakeConsole); var gitbucketClient = new Mock <IGitHubClient>(); gitbucketClient .SetupSequence(g => g.PullRequest.GetAllForRepository(It.IsAny <string>(), It.IsAny <string>())) .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest>())) .ReturnsAsync(new ReadOnlyCollection <Octokit.PullRequest>(new List <Octokit.PullRequest> { new FakePullRequest(new FakeGitReference("develop"), new FakeGitReference("master"), 2) })); var body = string.Empty; bool?isDraft = null; gitbucketClient .Setup(g => g.PullRequest.Create(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <NewPullRequest>())) .Callback((string owner, string name, NewPullRequest newPullRequest) => { body = newPullRequest.Body; isDraft = newPullRequest.Draft; }) .ThrowsAsync(new InvalidCastException("Ignore InvalidCastException because of escaped response.")); gitbucketClient.Setup(g => g.Issue.Labels.AddToIssue(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <string[]>())); // When var result = await service.Execute(options, gitbucketClient.Object); // Then Assert.Equal(0, result); gitbucketClient .Verify(g => g.PullRequest.Create( It.Is <string>(o => o == "root"), It.Is <string>(r => r == "test"), It.Is <NewPullRequest>(p => p.Title == "v1.0.0" && p.Head == "develop" && p.Base == "master"))); Assert.Equal(@"As part of this release we had 3 issues closed. The highest priority among them is ""high"". ### Bug * Found a bug! #1 * Another bug #2 ### Enhancement * Some improvement on build #3 ", body, ignoreLineEndingDifferences: true); Assert.Single(FakeConsole.Messages); Assert.Equal("A new pull request has been successfully created!", FakeConsole.Messages[0]); Assert.Empty(FakeConsole.WarnMessages); Assert.Empty(FakeConsole.ErrorMessages); Assert.True(isDraft); }
public ReleaseRunner(ReleaseOptions options) : base(options) { _options = options; }
private async Task <List <GitBucket.Core.Models.Issue> > FindIssuesRelatedToMileStone(ReleaseOptions options) { // "String.Equals(String, StringComparison)" causes client side evaluation. // https://github.com/aspnet/EntityFrameworkCore/issues/1222 return(await _context.Set <GitBucket.Core.Models.Issue>() .Where(i => i.UserName.ToLower() == options.Owner.ToLower()) .Where(i => i.RepositoryName.ToLower() == options.Repository.ToLower()) .Where(i => i.Milestone !.Title.ToLower() == options.MileStone.ToLower()) .Where(i => i.PullRequest == options.FromPullRequest) .Include(i => i.Milestone) .Include(i => i.Priority) .AsNoTracking() .ToListAsync()); #pragma warning restore CA1304 // Specify CultureInfo }