/// <summary> /// <p>Pushes a package to the server and publishes it.</p> /// <p>For more details, visit the <a href="https://docs.microsoft.com/en-us/dotnet/core/tools/">official website</a>.</p> /// </summary> /// <remarks> /// <p>This is a <a href="http://www.nuke.build/docs/authoring-builds/cli-tools.html#fluent-apis">CLI wrapper with fluent API</a> that allows to modify the following arguments:</p> /// <ul> /// <li><c><targetPath></c> via <see cref="DotNetNuGetPushSettings.TargetPath"/></li> /// <li><c>--api-key</c> via <see cref="DotNetNuGetPushSettings.ApiKey"/></li> /// <li><c>--disable-buffering</c> via <see cref="DotNetNuGetPushSettings.DisableBuffering"/></li> /// <li><c>--force-english-output</c> via <see cref="DotNetNuGetPushSettings.ForceEnglishOutput"/></li> /// <li><c>--no-service-endpoint</c> via <see cref="DotNetNuGetPushSettings.NoServiceEndpoint"/></li> /// <li><c>--no-symbols</c> via <see cref="DotNetNuGetPushSettings.NoSymbols"/></li> /// <li><c>--skip-duplicate</c> via <see cref="DotNetNuGetPushSettings.SkipDuplicate"/></li> /// <li><c>--source</c> via <see cref="DotNetNuGetPushSettings.Source"/></li> /// <li><c>--symbol-api-key</c> via <see cref="DotNetNuGetPushSettings.SymbolApiKey"/></li> /// <li><c>--symbol-source</c> via <see cref="DotNetNuGetPushSettings.SymbolSource"/></li> /// <li><c>--timeout</c> via <see cref="DotNetNuGetPushSettings.Timeout"/></li> /// </ul> /// </remarks> private (BlockingCollection <ILineOut>, int) DotNetNuGetPush(DotNetNuGetPushSettings toolSettings = null) { toolSettings = toolSettings ?? new DotNetNuGetPushSettings(); ProcessStartInfo processStartInfo = SlugCmdProcess.GetDefaultProcessSettings(); ToolSettingsToProcessInfoConverter.Convert(toolSettings, processStartInfo); SlugCmdProcess slugCmdProcess = new SlugCmdProcess("Dot Net Nuget Push", processStartInfo); slugCmdProcess.Execute(DotNetNugetPush_OutputProcessor); return(slugCmdProcess.Output, slugCmdProcess.ExitCode); }
/// <summary> /// Publishes a Nuget package to a nuget site. /// </summary> private void Publish_Nuget() { DotNetNuGetPushSettings settings = new DotNetNuGetPushSettings() { Source = CISession.NugetRepoURL, ApiKey = CISession.NugetAPIKey, SkipDuplicate = true, }; IReadOnlyCollection <AbsolutePath> nugetPackages = CISession.OutputDirectory.GlobFiles("*.nupkg"); foreach (AbsolutePath nugetPackage in nugetPackages) { if (nugetPackage.ToString().EndsWith("symbols.nupkg")) { continue; } bool pushedSuccessfully = false; StageCompletionStatusEnum stepStatus = StageCompletionStatusEnum.NotStarted; try { settings.TargetPath = nugetPackage; (BlockingCollection <ILineOut> nugetOutput, int exitCode) = DotNetNuGetPush(settings); StageOutput.AddRange(nugetOutput); ControlFlow.Assert(exitCode == 0, "Process DotNetBuild failed"); if (nugetOutput.Count > 0) { // Look for skipped message. foreach (ILineOut outputLine in nugetOutput) { if (outputLine.Text.Contains("already exists at feed")) { stepStatus = StageCompletionStatusEnum.Warning; string msg = @"A nuget package <" + Path.GetFileName(nugetPackage) + "> with this name and version already exists. " + "Assuming this is due to you re-running the publish after a prior error that occurred after the push to Nuget was successful. " + "Will carry on as though this push was successful. " + "Otherwise, if this should have been a new update, then you will need to make another commit and re-publish"; Logger.Warn(msg); } else if (outputLine.Text.Contains("package was pushed")) { pushedSuccessfully = true; stepStatus = StageCompletionStatusEnum.Success; } } } } catch (ProcessException pe) { stepStatus = StageCompletionStatusEnum.Failure; if (!CISession.NugetRepoURL.Contains("nuget.org")) { Logger.Warn( "The nuget Push process threw an error. Since you are using a service other than Nuget this may be a service outage with the site or it might mean the version of the library you are pushing already exists. You will need to perform a manual check to determine which it is."); } else { throw; } } if (pushedSuccessfully) { string fileName = Path.GetFileName(nugetPackage); fileName = fileName.TrimEnd(".symbols.nupkg"); fileName = fileName.TrimEnd(".nupkg"); fileName = fileName.TrimEnd("." + CISession.VersionInfo.SemVersionAsString); fileName = fileName.ToLower(); // Loop thru projects looking for that assembly name foreach (SlugCIProject project in CISession.Projects) { if (project.AssemblyName.ToLower() == fileName || project.PackageId.ToLower() == fileName) { // TODO - Remove - not needed anylonger. // For Tool Deployed projects, we need to copy the current version out to the deploy folder /* * if ( project.Deploy == SlugCIDeployMethod.Tool ) { * AbsolutePath deployFile = CISession.DeployCopyPath / project.Name / CISession.PublishTarget.ToString() / "Version.json"; * ToolVersionJSON toolVersionJSON = new ToolVersionJSON() {ToolVersion = CISession.VersionInfo.SemVersionAsString}; * string json = JsonSerializer.Serialize<ToolVersionJSON>(toolVersionJSON, ToolVersionJSON.SerializerOptions()); * File.WriteAllText(deployFile, json); * } */ project.Results.PublishedSuccess = true; break; } } } // Set stage status based upon Step Status SetInprocessStageStatus(stepStatus); } }
async Task <IEnumerable <Output> > PushPackages() { var outputs = Enumerable.Empty <Output>(); const int rateLimit = 300; var allFiles = Packages.Select((x, i) => new { Index = i, Value = x }) .GroupBy(x => x.Index / rateLimit) .Select(x => x.Select(v => v.Value).ToList()) .ToList(); var first = true; Logger.Info($"Searching for packages in \"{RootDirectory / "build" / "output_packages"}\"..."); foreach (var files in allFiles) { if (first) { first = false; } else { await Task.Delay(TimeSpan.FromHours(1)); } if (!NugetFeed.Contains("nuget.org")) { var srcSettings = new DotNetNuGetAddSourceSettings().SetName("Silk-PushPackages").SetSource(NugetFeed); if (NugetUsername is not null || NugetPassword is not null) { if (NugetUsername is null || NugetPassword is null) { ControlFlow.Fail ( "Both \"NugetUsername\" and \"NugetPassword\" must be specified if either are used." ); } srcSettings = srcSettings.SetUsername(NugetUsername).SetPassword(NugetPassword); } outputs = outputs.Concat(DotNetNuGetAddSource(srcSettings)); } foreach (var pushSettings in files.Select ( file => { var x = new DotNetNuGetPushSettings() .SetNoServiceEndpoint(NugetNoServiceEndpoint) .EnableSkipDuplicate() .SetSource(NugetFeed.Contains("nuget.org") ? "nuget.org" : "Silk-PushPackages") .SetTargetPath(file); if (NugetApiKey is not null) { x = x.SetApiKey(NugetApiKey); } return(x); } )) { outputs = outputs.Concat(DotNetNuGetPush(pushSettings)); } if (!NugetFeed.Contains("nuget.org")) { outputs = outputs.Concat(DotNet("dotnet nuget remove source \"Silk-PushPackages\"")); } } return(outputs); }