5
5
using System ;
6
6
using System . Collections . Generic ;
7
7
using System . CommandLine ;
8
+ using System . Linq ;
8
9
using Microsoft . DotNet . VersionTools . Automation ;
9
10
using Octokit ;
10
11
using static Microsoft . DotNet . ImageBuilder . Commands . CliHelper ;
@@ -14,22 +15,23 @@ namespace Microsoft.DotNet.ImageBuilder.Commands
14
15
{
15
16
public class GitOptions : IGitHubFileRef
16
17
{
17
- public string AuthToken { get ; set ; } = string . Empty ;
18
18
public string Branch { get ; set ; } = string . Empty ;
19
19
public string Email { get ; set ; } = string . Empty ;
20
20
public string Owner { get ; set ; } = string . Empty ;
21
21
public string Path { get ; set ; } = string . Empty ;
22
22
public string Repo { get ; set ; } = string . Empty ;
23
23
public string Username { get ; set ; } = string . Empty ;
24
24
25
- public GitHubAuth ToGitHubAuth ( )
26
- {
27
- return new GitHubAuth ( AuthToken , Username , Email ) ;
28
- }
25
+ public Uri GetRepoUrl ( ) => new Uri ( $ "https://github.com/ { Owner } / { Repo } " ) ;
26
+
27
+ public GitHubAuthOptions GitHubAuthOptions { get ; set ; } = new GitHubAuthOptions ( ) ;
28
+ }
29
29
30
- public Credentials ToOctokitCredentials ( ) => new Credentials ( AuthToken ) ;
30
+ public record GitHubAuthOptions ( string AuthToken = "" , string PrivateKeyFilePath = "" )
31
+ {
32
+ public bool IsPrivateKeyAuth => ! string . IsNullOrEmpty ( PrivateKeyFilePath ) ;
31
33
32
- public Uri GetRepoUrl ( ) => new Uri ( $ "https://github.com/ { Owner } / { Repo } " ) ;
34
+ public bool HasCredentials => ! string . IsNullOrEmpty ( AuthToken ) || ! string . IsNullOrEmpty ( PrivateKeyFilePath ) ;
33
35
}
34
36
35
37
public class GitOptionsBuilder
@@ -47,7 +49,7 @@ public static GitOptionsBuilder BuildWithDefaults() =>
47
49
Build ( )
48
50
. WithUsername ( isRequired : true )
49
51
. WithEmail ( isRequired : true )
50
- . WithAuthToken ( isRequired : true )
52
+ . WithGitHubAuth ( )
51
53
. WithBranch ( )
52
54
. WithOwner ( )
53
55
. WithPath ( )
@@ -65,12 +67,6 @@ public GitOptionsBuilder WithEmail(
65
67
string description = "Email to use for GitHub connection" ) =>
66
68
AddSymbol ( "git-email" , nameof ( GitOptions . Email ) , isRequired , defaultValue , description ) ;
67
69
68
- public GitOptionsBuilder WithAuthToken (
69
- bool isRequired = false ,
70
- string ? defaultValue = null ,
71
- string description = "Auth token to use to connect to GitHub" ) =>
72
- AddSymbol ( "git-token" , nameof ( GitOptions . AuthToken ) , isRequired , defaultValue , description ) ;
73
-
74
70
public GitOptionsBuilder WithBranch (
75
71
bool isRequired = false ,
76
72
string ? defaultValue = null ,
@@ -95,23 +91,62 @@ public GitOptionsBuilder WithRepo(
95
91
string description = "Name of the GitHub repo to access" ) =>
96
92
AddSymbol ( "git-repo" , nameof ( GitOptions . Repo ) , isRequired , defaultValue , description ) ;
97
93
94
+ public GitOptionsBuilder WithGitHubAuth ( string ? description = null , bool isRequired = false )
95
+ {
96
+ description ??= "GitHub Personal Access Token (PAT) or private key file (.pem)" ;
97
+ description += " [token=<token> | private-key-file=<path to .pem file>]" ;
98
+
99
+ _options . Add ( CreateOption (
100
+ "github-auth" ,
101
+ nameof ( GitOptions . GitHubAuthOptions ) ,
102
+ "GitHub Personal Access Token (PAT) or private key file (.pem) [token=<token> | private-key-file=<path to .pem file>]" ,
103
+ parseArg : argumentResult =>
104
+ {
105
+ var dictionary = argumentResult . Tokens
106
+ . Select ( token => token . Value . ParseKeyValuePair ( '=' ) )
107
+ . ToDictionary ( ) ;
108
+
109
+ string token = dictionary . GetValueOrDefault ( "token" , "" ) ;
110
+ string privateKeyFile = dictionary . GetValueOrDefault ( "private-key-file" , "" ) ;
111
+
112
+ if ( isRequired && string . IsNullOrEmpty ( token ) && string . IsNullOrEmpty ( privateKeyFile ) )
113
+ {
114
+ throw new ArgumentException ( "GitHub token or private key file must be provided." ) ;
115
+ }
116
+
117
+ return new GitHubAuthOptions ( token , privateKeyFile ) ;
118
+ }
119
+ ) ) ;
120
+
121
+ return this ;
122
+ }
123
+
98
124
public IEnumerable < Option > GetCliOptions ( ) => _options ;
99
125
100
126
public IEnumerable < Argument > GetCliArguments ( ) => _arguments ;
101
127
102
- private GitOptionsBuilder AddSymbol < T > ( string alias , string propertyName , bool isRequired , T ? defaultValue , string description )
128
+ private GitOptionsBuilder AddSymbol < T > (
129
+ string alias ,
130
+ string propertyName ,
131
+ bool isRequired ,
132
+ T ? defaultValue ,
133
+ string description )
103
134
{
104
135
if ( isRequired )
105
136
{
106
137
_arguments . Add ( new Argument < T > ( propertyName , description ) ) ;
107
138
}
108
139
else
109
140
{
110
- _options . Add ( CreateOption < T > ( alias , propertyName , description , defaultValue is null ? default ! : defaultValue ) ) ;
141
+ _options . Add (
142
+ CreateOption (
143
+ alias ,
144
+ propertyName ,
145
+ description ,
146
+ defaultValue is null ? default ! : defaultValue ) ) ;
111
147
}
112
148
113
149
return this ;
114
150
}
115
151
}
116
152
}
117
- #nullable disable
0 commit comments