1
1
/*---------------------------------------------------------------------------------------------
2
- * Copyright (C) 2023-2024 Posit Software, PBC. All rights reserved.
2
+ * Copyright (C) 2023-2025 Posit Software, PBC. All rights reserved.
3
3
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
@@ -88,13 +88,11 @@ async function executeCommand(command: string, stdin?: string):
88
88
* Downloads the specified version of Ark and replaces the local binary.
89
89
*
90
90
* @param version The version of Ark to download.
91
- * @param githubPat A Github Personal Access Token with the appropriate rights
91
+ * @param githubPat An optional Github Personal Access Token with the appropriate rights
92
92
* to download the release.
93
- * @param gitCredential Whether the PAT originated from the `git credential` command.
94
93
*/
95
94
async function downloadAndReplaceArk ( version : string ,
96
- githubPat : string ,
97
- gitCredential : boolean ) : Promise < void > {
95
+ githubPat : string | undefined ) : Promise < void > {
98
96
99
97
try {
100
98
const headers : Record < string , string > = {
@@ -115,51 +113,6 @@ async function downloadAndReplaceArk(version: string,
115
113
116
114
const response = await httpsGetAsync ( requestOptions as any ) as any ;
117
115
118
- // Special handling for PATs originating from `git credential`.
119
- if ( gitCredential && response . statusCode === 200 ) {
120
- // If the PAT hasn't been approved yet, do so now. This stores the credential in
121
- // the system credential store (or whatever `git credential` uses on the system).
122
- // Without this step, the user will be prompted for a username and password the
123
- // next time they try to download Ark.
124
- const { stdout, stderr } =
125
- await executeCommand ( 'git credential approve' ,
126
- `protocol=https\n` +
127
- `host=github.com\n` +
128
- `path=/repos/posit-dev/ark/releases\n` +
129
- `username=\n` +
130
- `password=${ githubPat } \n` ) ;
131
- console . log ( stdout ) ;
132
- if ( stderr ) {
133
- console . warn ( `Unable to approve PAT. You may be prompted for a username and ` +
134
- `password the next time you download Ark.` ) ;
135
- console . error ( stderr ) ;
136
- }
137
- } else if ( gitCredential && response . statusCode > 400 && response . statusCode < 500 ) {
138
- // This handles the case wherein we got an invalid PAT from `git credential`. In this
139
- // case we need to clean up the PAT from the credential store, so that we don't
140
- // continue to use it.
141
- const { stdout, stderr } =
142
- await executeCommand ( 'git credential reject' ,
143
- `protocol=https\n` +
144
- `host=github.com\n` +
145
- `path=/repos/posit-dev/ark/releases\n` +
146
- `username=\n` +
147
- `password=${ githubPat } \n` ) ;
148
- console . log ( stdout ) ;
149
- if ( stderr ) {
150
- console . error ( stderr ) ;
151
- throw new Error ( `The stored PAT returned by 'git credential' is invalid, but\n` +
152
- `could not be removed. Please manually remove the PAT from 'git credential'\n` +
153
- `for the host 'github.com'` ) ;
154
- }
155
- throw new Error ( `The PAT returned by 'git credential' is invalid. Ark cannot be\n` +
156
- `downloaded.\n\n` +
157
- `Check to be sure that your Personal Access Token:\n` +
158
- '- Has the `repo` scope\n' +
159
- '- Is not expired\n' +
160
- '- Has been authorized for the "posit-dev" organization on Github (Configure SSO)\n' ) ;
161
- }
162
-
163
116
let responseBody = '' ;
164
117
165
118
response . on ( 'data' , ( chunk : any ) => {
@@ -290,17 +243,16 @@ async function main() {
290
243
return ;
291
244
}
292
245
293
- // We need a Github Personal Access Token (PAT) to download Ark. Because this is sensitive
294
- // information, there are a lot of ways to set it. We try the following in order:
246
+ // We can optionally use a Github Personal Access Token (PAT) to download
247
+ // Ark. Because this is sensitive information, there are a lot of ways to
248
+ // set it. We try the following in order:
295
249
296
250
// (1) The GITHUB_PAT environment variable.
297
251
// (2) The POSITRON_GITHUB_PAT environment variable.
298
252
// (3) The git config setting 'credential.https://api.github.com.token'.
299
- // (4) The git credential store.
300
253
301
254
// (1) Get the GITHUB_PAT from the environment.
302
255
let githubPat = process . env . GITHUB_PAT ;
303
- let gitCredential = false ;
304
256
if ( githubPat ) {
305
257
console . log ( 'Using Github PAT from environment variable GITHUB_PAT.' ) ;
306
258
} else {
@@ -323,48 +275,11 @@ async function main() {
323
275
`'credential.https://api.github.com.token'.` ) ;
324
276
}
325
277
} catch ( error ) {
326
- // We don't care if this fails; we'll try `git credential` next .
278
+ // We don't care if this fails; we'll without a PAT .
327
279
}
328
280
}
329
281
330
- // (4) If no GITHUB_PAT is set, try to get it from git credential.
331
- if ( ! githubPat ) {
332
- // Explain to the user what's about to happen.
333
- console . log ( `Attempting to retrieve a Github Personal Access Token from git in order\n` +
334
- `to download Ark ${ packageJsonVersion } . If you are prompted for a username and\n` +
335
- `password, enter your Github username and a Personal Access Token with the\n` +
336
- `'repo' scope. You can read about how to create a Personal Access Token here: \n` +
337
- `\n` +
338
- `https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens\n` +
339
- `\n` +
340
- `If you don't want to set up a Personal Access Token now, just press Enter twice to set \n` +
341
- `a blank value for the password. Ark will not be downloaded, but you will still be\n` +
342
- `able to run Positron without R support.\n` +
343
- `\n` +
344
- `You can set a PAT later by running yarn again and supplying the PAT at this prompt,\n` +
345
- `or by running 'git config credential.https://api.github.com.token YOUR_GITHUB_PAT'\n` ) ;
346
- const { stdout, stderr } =
347
- await executeCommand ( 'git credential fill' ,
348
- `protocol=https\n` +
349
- `host=github.com\n` +
350
- `path=/repos/posit-dev/ark/releases\n` ) ;
351
-
352
- gitCredential = true ;
353
- // Extract the `password = ` line from the output.
354
- const passwordLine = stdout . split ( '\n' ) . find (
355
- ( line : string ) => line . startsWith ( 'password=' ) ) ;
356
- if ( passwordLine ) {
357
- githubPat = passwordLine . split ( '=' ) [ 1 ] ;
358
- console . log ( `Using Github PAT returned from 'git credential'.` ) ;
359
- }
360
- }
361
-
362
- if ( ! githubPat ) {
363
- throw new Error ( `No Github PAT was found. Unable to download Ark ${ packageJsonVersion } .\n` +
364
- `You can still run Positron without R support.` ) ;
365
- }
366
-
367
- await downloadAndReplaceArk ( packageJsonVersion , githubPat , gitCredential ) ;
282
+ await downloadAndReplaceArk ( packageJsonVersion , githubPat ) ;
368
283
}
369
284
370
285
main ( ) . catch ( ( error ) => {
0 commit comments