-
Notifications
You must be signed in to change notification settings - Fork 586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2148: Add dotnet nuget push command and arguments #2229
Changes from 10 commits
c4afb75
ab77b6a
d4eae30
7170367
7024c21
3dc8147
4820c2f
eaaf2f1
b480598
7fcbd65
500272d
026954c
abf2615
45a26d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,18 @@ type NugetSymbolPackage = | |
/// Build a symbol package using the nuspec file | ||
| Nuspec = 2 | ||
|
||
type ToolOptions = | ||
{ ToolPath : string | ||
Command : string | ||
WorkingDir : string | ||
IsFullFramework : bool } | ||
|
||
static member Create toolPath command workingDir isFullFramework = | ||
{ ToolPath = toolPath | ||
Command = command | ||
WorkingDir = workingDir | ||
IsFullFramework = isFullFramework } | ||
|
||
/// Nuget parameter type | ||
type NuGetParams = | ||
{ ToolPath : string | ||
|
@@ -315,40 +327,113 @@ let private pack parameters nuspecFile = | |
parameters.Version outputPath nuspecFile packageAnalysis defaultExcludes includeReferencedProjects properties basePath | ||
|> execute | ||
|
||
/// push package (and try again if something fails) | ||
let rec private publish parameters = | ||
TraceSecrets.register parameters.AccessKey "<NuGetKey>" | ||
TraceSecrets.register parameters.SymbolAccessKey "<NuGetSymbolKey>" | ||
// Newer NuGet requires source to be always specified, so if PublishUrl is empty, | ||
// ignore symbol source - the produced source is broken anyway. | ||
let normalize str = if String.isNullOrEmpty str then None else Some str | ||
let source = match parameters.PublishUrl |> normalize, parameters.SymbolPublishUrl |> normalize with | ||
| None, _ -> "" | ||
| Some source, None -> sprintf "-source %s" source | ||
| Some source, Some symSource -> sprintf "-source %s -SymbolSource %s -SymbolApiKey %s" | ||
source symSource parameters.SymbolAccessKey | ||
|
||
let args = sprintf "push \"%s\" %s %s" (parameters.OutputPath @@ packageFileName parameters |> Path.getFullName) | ||
parameters.AccessKey source | ||
Trace.tracefn "%s %s in WorkingDir: %s Trials left: %d" parameters.ToolPath args | ||
(Path.getFullName parameters.WorkingDir) parameters.PublishTrials | ||
try | ||
let result = | ||
let tracing = Process.shouldEnableProcessTracing() | ||
try | ||
Process.setEnableProcessTracing false | ||
Process.execSimple ((fun info -> | ||
{ info with | ||
FileName = parameters.ToolPath | ||
WorkingDirectory = Path.getFullName parameters.WorkingDir | ||
Arguments = args }) >> Process.withFramework) parameters.TimeOut | ||
finally Process.setEnableProcessTracing tracing | ||
if result <> 0 then | ||
sprintf "Error during NuGet push. %s %s" parameters.ToolPath args | ||
|> TraceSecrets.guardMessage | ||
|> failwith | ||
with exn when parameters.PublishTrials > 0 -> | ||
publish { parameters with PublishTrials = parameters.PublishTrials - 1 } | ||
/// dotnet nuget push command options | ||
type NuGetPushParams = | ||
{ /// Disables buffering when pushing to an HTTP(S) server to reduce memory usage. | ||
DisableBuffering: bool | ||
/// The API key for the server | ||
ApiKey: string option | ||
/// Doesn't push symbols (even if present). | ||
NoSymbols: bool | ||
/// Doesn't append "api/v2/package" to the source URL. | ||
NoServiceEndpoint: bool | ||
/// Specifies the server URL. This option is required unless DefaultPushSource config value is set in the NuGet config file. | ||
Source: string option | ||
/// The API key for the symbol server. | ||
SymbolApiKey: string option | ||
/// Specifies the symbol server URL. | ||
SymbolSource: string option | ||
/// Specifies the timeout for pushing to a server. | ||
Timeout: TimeSpan option | ||
/// Number of times to retry pushing the package | ||
PushTrials: int} | ||
|
||
static member Create() = | ||
{ DisableBuffering = false | ||
ApiKey = None | ||
NoSymbols = false | ||
NoServiceEndpoint = false | ||
Source = None | ||
SymbolApiKey = None | ||
SymbolSource = None | ||
Timeout = None | ||
PushTrials = 5 } | ||
|
||
type NuGetParams with | ||
member internal x.NuGetPushOptions = | ||
let normalize str = if String.isNullOrEmpty str then None else Some str | ||
|
||
{ DisableBuffering = false | ||
ApiKey = normalize x.AccessKey | ||
NoSymbols = false | ||
NoServiceEndpoint = false | ||
Source = normalize x.PublishUrl | ||
SymbolApiKey = normalize x.SymbolAccessKey | ||
SymbolSource = normalize x.SymbolPublishUrl | ||
Timeout = Some x.TimeOut | ||
PushTrials = x.PublishTrials } | ||
|
||
member internal x.ToolOptions = ToolOptions.Create x.ToolPath "push" x.WorkingDir true | ||
member internal x.Nupkg = (x.OutputPath @@ packageFileName x |> Path.getFullName) | ||
|
||
let private toPushCliArgs param = | ||
let ifTrue x b = | ||
if b then Some x | ||
else None | ||
|
||
[ | ||
param.ApiKey | ||
param.DisableBuffering |> ifTrue "-DisableBuffering" | ||
param.NoSymbols |> ifTrue "-NoSymbols" | ||
param.NoServiceEndpoint |> ifTrue "-NoServiceEndpoint" | ||
param.Source |> Option.map (sprintf "-Source %s") | ||
param.SymbolApiKey |> Option.map (sprintf "-SymbolApiKey %s") | ||
param.SymbolSource |> Option.map (sprintf "-SymbolSource %s") | ||
param.Timeout |> Option.map string |> Option.map (sprintf "-Timeout %s") | ||
] | ||
|> List.choose id | ||
|> String.concat " " | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you use the proper APIs for this ( |
||
|
||
module Private = | ||
/// For internal use | ||
let rec push (options : ToolOptions) (parameters : NuGetPushParams) (toCliArgs : NuGetPushParams -> string) nupkg = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this only currently handles
Personally I'd lean to something along the second option, but if there are good reasons to do it differently I'm all ears. Note that I'm not proposing to implement all options in this PR, but whatever we decide to release should be extendible later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The second option sounds like a good idea so I'll not reuse this in the |
||
parameters.ApiKey |> Option.iter (fun key -> TraceSecrets.register key "<NuGetKey>") | ||
parameters.SymbolApiKey |> Option.iter (fun key -> TraceSecrets.register key "<NuGetSymbolKey>") | ||
|
||
let args = sprintf "%s \"%s\" %s" options.Command nupkg (toCliArgs parameters) | ||
|
||
sprintf "%s %s in WorkingDir: %s Trials left: %d" options.ToolPath args (Path.getFullName options.WorkingDir) parameters.PushTrials | ||
|> TraceSecrets.guardMessage | ||
|> Trace.trace | ||
|
||
try | ||
let result = | ||
let tracing = Process.shouldEnableProcessTracing() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we really want to disable tracing we should use the corresponding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, I just copied some other code in the same module. I can just remove it I guess. |
||
try | ||
Process.setEnableProcessTracing false | ||
|
||
CreateProcess.fromRawCommandLine options.ToolPath args | ||
|> CreateProcess.withWorkingDirectory options.WorkingDir | ||
|> CreateProcess.withTimeout (parameters.Timeout |> Option.defaultValue (TimeSpan.FromMinutes 5.0)) | ||
|> (fun p -> | ||
if options.IsFullFramework then | ||
p |> CreateProcess.withFramework | ||
else | ||
p) | ||
|> Proc.run | ||
|
||
finally Process.setEnableProcessTracing tracing | ||
|
||
if result.ExitCode <> 0 then | ||
sprintf "Error during NuGet push. %s %s" options.ToolPath args | ||
|> TraceSecrets.guardMessage | ||
|> failwith | ||
|
||
with _ when parameters.PushTrials > 0 -> | ||
push options { parameters with PushTrials = parameters.PushTrials - 1 } toCliArgs nupkg | ||
|
||
let private publish (parameters : NuGetParams) = | ||
Private.push parameters.ToolOptions parameters.NuGetPushOptions toPushCliArgs parameters.Nupkg | ||
|
||
/// push package to symbol server (and try again if something fails) | ||
let rec private publishSymbols parameters = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add short docs for this or mark it
internal
/private
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make it internal, since I'm not reusing it in the DotNet module anymore.