public void CanGetHeadTipIdSha() { var headTipIdSha = vSut.HeadTipIdSha(MasterFolder); Assert.IsFalse(string.IsNullOrEmpty(headTipIdSha)); Assert.IsTrue(headTipIdSha.Length >= 40); }
public async Task <YesNoInconclusive> UpdateNugetPackagesInRepositoryAsync(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos) { using (SimpleLogger.BeginScope(SimpleLoggingScopeId.Create(nameof(UpdateNugetPackagesInRepositoryAsync), Guid.NewGuid().ToString()))) { SimpleLogger.LogInformation("Determining files with uncommitted changes"); var yesNoInconclusive = new YesNoInconclusive(); var files = GitUtilities.FilesWithUncommittedChanges(repositoryFolder); yesNoInconclusive.Inconclusive = files.Any(f => EndingsThatAllowReset.All(e => !f.EndsWith("." + e, StringComparison.InvariantCultureIgnoreCase))); yesNoInconclusive.YesNo = false; if (yesNoInconclusive.Inconclusive) { errorsAndInfos.Infos.Add("Not all files allow a reset"); SimpleLogger.LogInformation($"Returning {yesNoInconclusive}"); return(yesNoInconclusive); } SimpleLogger.LogInformation("Resetting repository"); GitUtilities.Reset(repositoryFolder, GitUtilities.HeadTipIdSha(repositoryFolder), errorsAndInfos); if (errorsAndInfos.AnyErrors()) { errorsAndInfos.Infos.Add("Could not reset"); SimpleLogger.LogInformation($"Returning {yesNoInconclusive}"); return(yesNoInconclusive); } SimpleLogger.LogInformation("Searching for project files"); var projectFileFullNames = Directory.GetFiles(repositoryFolder.SubFolder("src").FullName, "*.csproj", SearchOption.AllDirectories).ToList(); if (!projectFileFullNames.Any()) { errorsAndInfos.Infos.Add("No project files found"); SimpleLogger.LogInformation($"Returning {yesNoInconclusive}"); return(yesNoInconclusive); } foreach (var projectFileFullName in projectFileFullNames) { SimpleLogger.LogInformation($"Analyzing project file {projectFileFullName}"); var projectErrorsAndInfos = new ErrorsAndInfos(); if (!await UpdateNugetPackagesForProjectAsync(projectFileFullName, yesNoInconclusive.YesNo, projectErrorsAndInfos)) { continue; } yesNoInconclusive.YesNo = true; } if (yesNoInconclusive.YesNo) { errorsAndInfos.Infos.Add("No project was updated"); SimpleLogger.LogInformation($"Returning {yesNoInconclusive}"); return(yesNoInconclusive); } SimpleLogger.LogInformation("Resetting repository"); GitUtilities.Reset(repositoryFolder, GitUtilities.HeadTipIdSha(repositoryFolder), errorsAndInfos); SimpleLogger.LogInformation($"Returning {yesNoInconclusive}"); return(yesNoInconclusive); } }
public async Task <bool> HasPullRequestForThisBranchAndItsHeadTipAsync(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos) { var pullRequests = await GetPullRequestsAsync(repositoryFolder, "all", errorsAndInfos); var checkedOutBranch = vGitUtilities.CheckedOutBranch(repositoryFolder); var headTipIdSha = vGitUtilities.HeadTipIdSha(repositoryFolder); return(pullRequests.Any(p => p.Branch == checkedOutBranch && p.Sha == headTipIdSha)); }
private async Task AutoCommitAndPushAsync(string nugetFeedId, IFolder repositoryFolder, List <string> files, bool onlyIfNecessary, string commitMessage, bool noRebuildRequired, IErrorsAndInfos errorsAndInfos) { var branchName = GitUtilities.CheckedOutBranch(repositoryFolder); if (branchName != "master") { errorsAndInfos.Errors.Add(Properties.Resources.CheckedOutBranchIsNotMaster); return; } var headTipShaBeforePush = GitUtilities.HeadTipIdSha(repositoryFolder); GitUtilities.IdentifyOwnerAndName(repositoryFolder, out var owner, out _, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { errorsAndInfos.Errors.Add(Properties.Resources.OwnerAndNameNotFound); return; } var personalAccessTokensSecret = new PersonalAccessTokensSecret(); var personalAccessTokens = await SecretRepository.GetAsync(personalAccessTokensSecret, errorsAndInfos); var personalAccessToken = personalAccessTokens.FirstOrDefault(t => t.Owner == owner && t.Purpose == "AutoCommitPush"); if (personalAccessToken == null) { errorsAndInfos.Errors.Add(Properties.Resources.AutoCommitPushAccessTokenNotFound); return; } using var repo = new Repository(repositoryFolder.FullName); var remotes = repo.Network.Remotes.ToList(); if (remotes.Count != 1) { errorsAndInfos.Errors.Add(Properties.Resources.RemoteNotFoundOrNotUnique); return; } var remote = remotes[0]; files.ForEach(f => { // ReSharper disable once AccessToDisposedClosure Commands.Stage(repo, f); }); var checkFiles = GitUtilities.FilesWithUncommittedChanges(repositoryFolder); if (onlyIfNecessary && !checkFiles.Any()) { return; } if (checkFiles.Count != files.Count) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.NumberOfFilesWithUncommittedChangesHasChanged, string.Join(", ", files), string.Join(", ", checkFiles))); return; } var author = new Signature(personalAccessToken.TokenName, personalAccessToken.Email, DateTime.Now); var committer = author; repo.Commit(commitMessage, author, committer); var options = new PushOptions { CredentialsProvider = (_, _, _) => new UsernamePasswordCredentials { Username = owner, Password = personalAccessToken.Token } }; repo.Network.Push(remote, @"refs/heads/" + branchName, options); if (!noRebuildRequired) { return; } var pushedHeadTipShaRepository = PushedHeadTipShaRepository; if (!(await pushedHeadTipShaRepository.GetAsync(nugetFeedId, errorsAndInfos)).Contains(headTipShaBeforePush)) { return; } var headTipSha = GitUtilities.HeadTipIdSha(repositoryFolder); await pushedHeadTipShaRepository.AddAsync(nugetFeedId, headTipSha, errorsAndInfos); }
public async Task <IPackageToPush> FindPackageToPushAsync(string nugetFeedId, IFolder packageFolderWithBinaries, IFolder repositoryFolder, string solutionFileFullName, IErrorsAndInfos errorsAndInfos) { IPackageToPush packageToPush = new PackageToPush(); errorsAndInfos.Infos.Add(Properties.Resources.CheckingProjectVsSolution); var projectFileFullName = solutionFileFullName.Replace(".sln", ".csproj"); if (!File.Exists(projectFileFullName)) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.ProjectFileNotFound, projectFileFullName)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingProject); var project = ProjectFactory.Load(solutionFileFullName, projectFileFullName, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingNugetFeeds); var developerSettingsSecret = new DeveloperSettingsSecret(); var developerSettings = await SecretRepository.GetAsync(developerSettingsSecret, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } if (developerSettings == null) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.MissingDeveloperSettings, developerSettingsSecret.Guid + ".xml")); return(packageToPush); } var nugetFeedsSecret = new SecretNugetFeeds(); var nugetFeeds = await SecretRepository.GetAsync(nugetFeedsSecret, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.IdentifyingNugetFeed); var nugetFeed = nugetFeeds.FirstOrDefault(f => f.Id == nugetFeedId); if (nugetFeed == null) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.UnknownNugetFeed, nugetFeedId, nugetFeedsSecret.Guid + ".xml")); return(packageToPush); } if (!nugetFeed.IsAFolderToResolve()) { var nugetConfigFileFullName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\NuGet\" + "nuget.config"; packageToPush.ApiKey = NugetConfigReader.GetApiKey(nugetConfigFileFullName, nugetFeed.Id, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } } errorsAndInfos.Infos.Add(Properties.Resources.IdentifyingFeedUrl); var source = await nugetFeed.UrlOrResolvedFolderAsync(FolderResolver, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } packageToPush.FeedUrl = source; if (string.IsNullOrEmpty(packageToPush.FeedUrl)) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.IncompleteDeveloperSettings, developerSettingsSecret.Guid + ".xml")); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.SearchingLocalPackage); var localPackageRepository = new FindLocalPackagesResourceV2(packageFolderWithBinaries.FullName); var localPackages = localPackageRepository.GetPackages(new NullLogger(), CancellationToken.None).Where(p => !p.Identity.Version.IsPrerelease).ToList(); if (!localPackages.Any()) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.NoPackageFilesFound, packageFolderWithBinaries.FullName)); return(packageToPush); } var latestLocalPackageVersion = localPackages.Max(p => p.Identity.Version.Version); errorsAndInfos.Infos.Add(string.Format(Properties.Resources.FoundLocalPackage, latestLocalPackageVersion)); errorsAndInfos.Infos.Add(Properties.Resources.SearchingRemotePackage); var packageId = string.IsNullOrWhiteSpace(project.PackageId) ? project.RootNamespace : project.PackageId; var remotePackages = await NugetFeedLister.ListReleasedPackagesAsync(nugetFeedId, packageId, errorsAndInfos); if (errorsAndInfos.Errors.Any()) { return(packageToPush); } if (!remotePackages.Any()) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.NoRemotePackageFilesFound, packageToPush.FeedUrl, packageId)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.LoadingPushedHeadTipShas); var pushedHeadTipShas = await PushedHeadTipShaRepository.GetAsync(nugetFeedId, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(packageToPush); } var headTipIdSha = repositoryFolder == null ? "" : GitUtilities.HeadTipIdSha(repositoryFolder); if (!string.IsNullOrWhiteSpace(headTipIdSha) && pushedHeadTipShas.Contains(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.HeadTipShaHasAlreadyBeenPushed, headTipIdSha, nugetFeedId)); return(packageToPush); } var latestRemotePackageVersion = remotePackages.Max(p => p.Identity.Version.Version); errorsAndInfos.Infos.Add(string.Format(Properties.Resources.FoundRemotePackage, latestRemotePackageVersion)); if (latestRemotePackageVersion >= latestLocalPackageVersion) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.RemotePackageHasHigherOrEqualVersion, headTipIdSha)); return(packageToPush); } errorsAndInfos.Infos.Add(Properties.Resources.CheckingRemotePackageTag); var remotePackage = remotePackages.First(p => p.Identity.Version.Version == latestRemotePackageVersion); if (!string.IsNullOrEmpty(remotePackage.Tags) && !string.IsNullOrWhiteSpace(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.TagsAre, remotePackage.Tags)); var tags = remotePackage.Tags.Split(' ').ToList(); if (tags.Contains(headTipIdSha)) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.PackageAlreadyTaggedWithHeadTipSha, headTipIdSha)); return(packageToPush); } if (tags.Count != 1) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.RemotePackageContainsSeveralTags, tags)); return(packageToPush); } var tag = tags[0]; errorsAndInfos.Infos.Add(string.Format(Properties.Resources.CheckingIfThereAreChangedBinaries, headTipIdSha, tag)); var listerErrorsAndInfos = new ErrorsAndInfos(); var changedBinaries = ChangedBinariesLister.ListChangedBinaries(packageId, headTipIdSha, tag, listerErrorsAndInfos); if (listerErrorsAndInfos.AnyErrors()) { errorsAndInfos.Infos.AddRange(listerErrorsAndInfos.Infos); errorsAndInfos.Errors.AddRange(listerErrorsAndInfos.Errors); return(packageToPush); } if (!changedBinaries.Any()) { errorsAndInfos.Infos.Add(string.Format(Properties.Resources.NoBinariesHaveChanged)); return(packageToPush); } } errorsAndInfos.Infos.Add(Properties.Resources.PackageNeedsToBePushed); packageToPush.PackageFileFullName = packageFolderWithBinaries.FullName + @"\" + packageId + "." + latestLocalPackageVersion + ".nupkg"; packageToPush.Id = packageId; packageToPush.Version = latestLocalPackageVersion?.ToString(); if (File.Exists(packageToPush.PackageFileFullName)) { return(packageToPush); } errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FileNotFound, packageToPush.PackageFileFullName)); return(packageToPush); }