/
PushNuGetPackageOperation.cs
164 lines (150 loc) · 6.64 KB
/
PushNuGetPackageOperation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System.ComponentModel;
using System.Threading.Tasks;
using Inedo.Agents;
using Inedo.Diagnostics;
using Inedo.Documentation;
using Inedo.Extensibility;
using Inedo.Extensibility.Credentials;
using Inedo.Extensibility.Operations;
using Inedo.Extensibility.SecureResources;
using Inedo.Extensions.Credentials;
using Inedo.Extensions.SecureResources;
using Inedo.Web;
using UsernamePasswordCredentials = Inedo.Extensions.Credentials.UsernamePasswordCredentials;
namespace Inedo.Extensions.DotNet.Operations.NuGet
{
[ScriptNamespace("NuGet")]
[ScriptAlias("Push-Package")]
[DisplayName("Push NuGet Package")]
[Description("Publishes a NuGet package file to a NuGet package source.")]
[Note("When Username/Password are specified, it will be passed as \"Username:Password\" via the API Key.")]
[DefaultProperty(nameof(PackagePath))]
public sealed class PushNuGetPackageOperation : NuGetOperation
{
[Required]
[ScriptAlias("FilePath")]
[ScriptAlias("Package")]
[DisplayName("Path to .nupkg package file name")]
public string PackagePath { get; set; }
[ScriptAlias("To")]
[ScriptAlias("Source")]
[DisplayName("Package source")]
[SuggestableValue(typeof(SecureResourceSuggestionProvider<NuGetPackageSource>))]
public string PackageSource { get; set; }
[Category("Connection/Identity")]
[ScriptAlias("FeedUrl")]
[ScriptAlias("Url")]
[DisplayName("NuGet server URL")]
[PlaceholderText("Use server URL from package source")]
public string ApiEndpointUrl { get; set; }
[Category("Connection/Identity")]
[ScriptAlias("UserName")]
[DisplayName("User name")]
[PlaceholderText("Use user name from package source")]
public string UserName { get; set; }
[Category("Connection/Identity")]
[ScriptAlias("Password")]
[DisplayName("Password")]
[PlaceholderText("Use password from package source")]
public string Password { get; set; }
[Category("Connection/Identity")]
[ScriptAlias("ApiKey")]
[DisplayName("NuGet API Key")]
[PlaceholderText("Use API Key from package source")]
public string ApiKey { get; set; }
public override async Task ExecuteAsync(IOperationExecutionContext context)
{
var packagePath = context.ResolvePath(this.PackagePath);
if (string.IsNullOrEmpty(packagePath))
{
this.LogError("Missing required argument \"Package\".");
return;
}
var fileOps = await context.Agent.GetServiceAsync<IFileOperationsExecuter>();
if (!await fileOps.FileExistsAsync(packagePath))
{
this.LogError($"Package file {packagePath} not found.");
return;
}
if (!string.IsNullOrEmpty(this.PackageSource))
{
this.LogDebug($"Using package source: {this.PackageSource}");
var packageSource = (NuGetPackageSource)SecureResource.Create(this.PackageSource, (IResourceResolutionContext)context);
if (packageSource == null)
{
this.LogError($"Package source \"{this.PackageSource}\" not found, or is not a NuGetPackageSource.");
return;
}
this.ApiEndpointUrl = packageSource.ApiEndpointUrl;
if (!string.IsNullOrEmpty(packageSource.CredentialName))
{
this.LogDebug($"Using credentials: {packageSource.CredentialName}...");
var credentials = packageSource.GetCredentials((ICredentialResolutionContext)context);
if (credentials is TokenCredentials tokenCredentials)
{
this.ApiKey = AH.Unprotect(tokenCredentials.Token);
}
else if (credentials is UsernamePasswordCredentials usernameCredentials)
{
this.UserName = usernameCredentials.UserName;
this.Password = AH.Unprotect(usernameCredentials.Password);
}
else
{
this.LogError($"Package source \"{packageSource.CredentialName}\" not found, or is not a Token or UsernamePassword type.");
return;
}
}
}
if (this.ApiEndpointUrl == null)
{
this.LogError($"No Url was specified to push a package to; you must either set a package source or the argument.");
return;
}
if (!string.IsNullOrEmpty(this.UserName))
{
if (string.IsNullOrEmpty(this.Password))
this.LogWarning($"Username specified but password is blank.");
if (string.IsNullOrEmpty(this.ApiKey))
this.ApiKey = this.UserName + ":" + this.Password;
else
this.LogWarning($"ApiKey is specified, so Username/Password will be ignored");
}
var nugetInfo = await this.GetNuGetInfoAsync(context);
this.LogInformation($"Pushing package {packagePath}...");
if (nugetInfo.IsNuGetExe)
{
await this.ExecuteNuGetAsync(
context,
nugetInfo,
$"push \"{packagePath}\" -ApiKey \"{this.ApiKey}\" -Source \"{this.ApiEndpointUrl}\" -NonInteractive",
null,
$"push \"{packagePath}\" -ApiKey XXXXX -Source \"{this.ApiEndpointUrl}\" -NonInteractive"
);
}
else
{
await this.ExecuteNuGetAsync(
context,
nugetInfo,
$"nuget push \"{packagePath}\" --api-key \"{this.ApiKey}\" --source \"{this.ApiEndpointUrl}\"",
null,
$"nuget push \"{packagePath}\" --api-key XXXXX --source \"{this.ApiEndpointUrl}\""
);
}
}
protected override ExtendedRichDescription GetDescription(IOperationConfiguration config)
{
return new ExtendedRichDescription(
new RichDescription(
"Push NuGet package ",
new DirectoryHilite(config[nameof(this.PackagePath)])
),
new RichDescription(
"to ",
new Hilite(config[nameof(this.PackageSource)])
)
);
}
}
}