glab-setup-git-identity 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +66 -4
- package/package.json +1 -1
- package/src/cli.js +49 -2
- package/src/index.js +83 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 006215b: Fix Docker/server support and glab --jq compatibility
|
|
8
|
+
- Fix README.md manual commands to use pipe to jq instead of --jq flag
|
|
9
|
+
- Add "Authentication in Docker/Server Environments" section to README
|
|
10
|
+
- Enhance CLI with helpful headless auth instructions
|
|
11
|
+
- Fix src/index.js to parse JSON in JavaScript for better glab version compatibility
|
|
12
|
+
- Optimize getGitLabUserInfo to use a single API call
|
|
13
|
+
|
|
3
14
|
## 0.6.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -13,16 +13,24 @@ A tool to setup git identity based on current GitLab user.
|
|
|
13
13
|
Instead of manually running:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
# Authenticate with GitLab (interactive mode - no extra flags)
|
|
17
|
+
glab auth login
|
|
18
|
+
|
|
19
|
+
# Or for non-interactive mode with a token:
|
|
20
|
+
# glab auth login --hostname gitlab.com --git-protocol https --token YOUR_TOKEN
|
|
21
|
+
|
|
17
22
|
glab auth git-credential # For HTTPS authentication helper
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
# Get user info (requires jq to be installed)
|
|
25
|
+
USERNAME=$(glab api user | jq -r '.username')
|
|
26
|
+
EMAIL=$(glab api user | jq -r '.email')
|
|
21
27
|
|
|
22
28
|
git config --global user.name "$USERNAME"
|
|
23
29
|
git config --global user.email "$EMAIL"
|
|
24
30
|
```
|
|
25
31
|
|
|
32
|
+
> **Note for manual commands**: The commands above require `jq` to be installed (`apt install jq` or `brew install jq`). The `glab api` command does not have a built-in `--jq` flag - you must pipe output to the external `jq` tool.
|
|
33
|
+
|
|
26
34
|
You can simply run:
|
|
27
35
|
|
|
28
36
|
```bash
|
|
@@ -163,7 +171,61 @@ The tool runs `glab auth login` automatically, followed by configuring git to us
|
|
|
163
171
|
If automatic authentication fails, you can run the commands manually:
|
|
164
172
|
|
|
165
173
|
```bash
|
|
166
|
-
glab auth login
|
|
174
|
+
glab auth login
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Authentication in Docker/Server Environments (Headless)
|
|
178
|
+
|
|
179
|
+
When running in Docker containers or on remote servers without a browser, `glab auth login` will display a URL to open but fail to launch a browser:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
Failed opening a browser at https://gitlab.com/oauth/authorize?...
|
|
183
|
+
Encountered error: exec: "xdg-open": executable file not found in $PATH
|
|
184
|
+
Try entering the URL in your browser manually.
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**To complete authentication in headless environments:**
|
|
188
|
+
|
|
189
|
+
1. **Copy the authorization URL** displayed by glab and open it in your local browser
|
|
190
|
+
2. Complete the GitLab OAuth flow in your browser
|
|
191
|
+
3. You'll be redirected to a URL like: `http://localhost:7171/auth/redirect?code=...&state=...`
|
|
192
|
+
4. **Use `curl` to send the redirect URL back to glab**:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Method 1: Using screen (recommended for Docker)
|
|
196
|
+
# Terminal 1: Start glab auth in screen
|
|
197
|
+
screen -S glab-auth
|
|
198
|
+
glab auth login
|
|
199
|
+
# Press Ctrl+A, D to detach from screen
|
|
200
|
+
|
|
201
|
+
# Terminal 2: After completing OAuth in browser, send the redirect URL
|
|
202
|
+
curl -L "http://localhost:7171/auth/redirect?code=YOUR_CODE&state=YOUR_STATE"
|
|
203
|
+
|
|
204
|
+
# Return to screen to see auth completion
|
|
205
|
+
screen -r glab-auth
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Method 2: Using SSH port forwarding (for remote servers)
|
|
210
|
+
# On your local machine, forward the callback port:
|
|
211
|
+
ssh -L 7171:localhost:7171 user@remote-server
|
|
212
|
+
|
|
213
|
+
# Then on the server, run glab auth login
|
|
214
|
+
# The OAuth redirect will go through the SSH tunnel to your local machine
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Alternatively, use token-based authentication** (recommended for CI/CD and automation):
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Generate a Personal Access Token at:
|
|
221
|
+
# https://gitlab.com/-/profile/personal_access_tokens
|
|
222
|
+
# Required scopes: api, write_repository
|
|
223
|
+
|
|
224
|
+
# Then authenticate non-interactively:
|
|
225
|
+
glab auth login --hostname gitlab.com --token YOUR_TOKEN
|
|
226
|
+
|
|
227
|
+
# Or with this tool:
|
|
228
|
+
glab-setup-git-identity --token YOUR_TOKEN
|
|
167
229
|
```
|
|
168
230
|
|
|
169
231
|
### Successful Run
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -260,6 +260,40 @@ async function handleAlreadyAuthenticated() {
|
|
|
260
260
|
return true;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Print headless authentication instructions
|
|
265
|
+
*/
|
|
266
|
+
function printHeadlessAuthInstructions() {
|
|
267
|
+
console.log('');
|
|
268
|
+
console.log('=== Authentication in Docker/Server Environments ===');
|
|
269
|
+
console.log('');
|
|
270
|
+
console.log(
|
|
271
|
+
'If you see a browser URL but cannot open it, follow these steps:'
|
|
272
|
+
);
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log('1. Copy the authorization URL displayed above');
|
|
275
|
+
console.log('2. Open it in your local browser and complete the OAuth flow');
|
|
276
|
+
console.log(
|
|
277
|
+
'3. You will be redirected to: http://localhost:7171/auth/redirect?code=...&state=...'
|
|
278
|
+
);
|
|
279
|
+
console.log('4. Use curl to send that redirect URL back to glab:');
|
|
280
|
+
console.log('');
|
|
281
|
+
console.log(
|
|
282
|
+
' curl -L "http://localhost:7171/auth/redirect?code=YOUR_CODE&state=YOUR_STATE"'
|
|
283
|
+
);
|
|
284
|
+
console.log('');
|
|
285
|
+
console.log('Alternatively, use token-based authentication:');
|
|
286
|
+
console.log('');
|
|
287
|
+
console.log('1. Generate a Personal Access Token at:');
|
|
288
|
+
console.log(` https://${config.hostname}/-/profile/personal_access_tokens`);
|
|
289
|
+
console.log(' Required scopes: api, write_repository');
|
|
290
|
+
console.log('');
|
|
291
|
+
console.log('2. Re-run with your token:');
|
|
292
|
+
console.log(` glab-setup-git-identity --token YOUR_TOKEN`);
|
|
293
|
+
console.log('');
|
|
294
|
+
console.log('================================================');
|
|
295
|
+
}
|
|
296
|
+
|
|
263
297
|
/**
|
|
264
298
|
* Handle case when not authenticated
|
|
265
299
|
* @returns {Promise<boolean>} True if login succeeded
|
|
@@ -268,14 +302,27 @@ async function handleNotAuthenticated() {
|
|
|
268
302
|
console.log('GitLab CLI is not authenticated. Starting authentication...');
|
|
269
303
|
console.log('');
|
|
270
304
|
|
|
305
|
+
// Print headless instructions before attempting auth
|
|
306
|
+
// This helps users in Docker/server environments know what to do
|
|
307
|
+
printHeadlessAuthInstructions();
|
|
308
|
+
console.log('');
|
|
309
|
+
|
|
271
310
|
const loginSuccess = await runGlabAuthLogin(getAuthOptions());
|
|
272
311
|
|
|
273
312
|
if (!loginSuccess) {
|
|
274
313
|
console.log('');
|
|
275
|
-
console.log('Authentication failed. Please try
|
|
314
|
+
console.log('Authentication failed. Please try one of the following:');
|
|
315
|
+
console.log('');
|
|
316
|
+
console.log('Option 1: Interactive login');
|
|
317
|
+
console.log(' glab auth login');
|
|
318
|
+
console.log('');
|
|
319
|
+
console.log('Option 2: Token-based login (recommended for headless)');
|
|
276
320
|
console.log(
|
|
277
|
-
` glab auth login --hostname ${config.hostname} --
|
|
321
|
+
` glab auth login --hostname ${config.hostname} --token YOUR_TOKEN`
|
|
278
322
|
);
|
|
323
|
+
console.log('');
|
|
324
|
+
console.log('Option 3: Use this tool with a token');
|
|
325
|
+
console.log(` glab-setup-git-identity --token YOUR_TOKEN`);
|
|
279
326
|
return false;
|
|
280
327
|
}
|
|
281
328
|
|
package/src/index.js
CHANGED
|
@@ -330,6 +330,9 @@ export async function isGlabAuthenticated(options = {}) {
|
|
|
330
330
|
/**
|
|
331
331
|
* Get GitLab username from authenticated user
|
|
332
332
|
*
|
|
333
|
+
* Note: This function parses the JSON response in JavaScript rather than using
|
|
334
|
+
* glab's --jq flag, as the --jq flag is not available in all glab versions.
|
|
335
|
+
*
|
|
333
336
|
* @param {Object} options - Options
|
|
334
337
|
* @param {string} options.hostname - GitLab hostname (optional)
|
|
335
338
|
* @param {boolean} options.verbose - Enable verbose logging
|
|
@@ -342,7 +345,7 @@ export async function getGitLabUsername(options = {}) {
|
|
|
342
345
|
|
|
343
346
|
log.debug('Getting GitLab username...');
|
|
344
347
|
|
|
345
|
-
const args = ['api', 'user'
|
|
348
|
+
const args = ['api', 'user'];
|
|
346
349
|
if (hostname) {
|
|
347
350
|
args.push('--hostname', hostname);
|
|
348
351
|
}
|
|
@@ -353,7 +356,23 @@ export async function getGitLabUsername(options = {}) {
|
|
|
353
356
|
throw new Error(`Failed to get GitLab username: ${result.stderr}`);
|
|
354
357
|
}
|
|
355
358
|
|
|
356
|
-
|
|
359
|
+
// Parse JSON response in JavaScript (glab's --jq flag is not available in all versions)
|
|
360
|
+
let userData;
|
|
361
|
+
try {
|
|
362
|
+
userData = JSON.parse(result.stdout.trim());
|
|
363
|
+
} catch (parseError) {
|
|
364
|
+
throw new Error(
|
|
365
|
+
`Failed to parse GitLab user data: ${parseError.message}. Raw output: ${result.stdout}`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const username = userData.username;
|
|
370
|
+
if (!username) {
|
|
371
|
+
throw new Error(
|
|
372
|
+
'No username found in GitLab user data. Please ensure your GitLab account has a username.'
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
357
376
|
log.debug(`GitLab username: ${username}`);
|
|
358
377
|
|
|
359
378
|
return username;
|
|
@@ -362,6 +381,9 @@ export async function getGitLabUsername(options = {}) {
|
|
|
362
381
|
/**
|
|
363
382
|
* Get primary email from GitLab user
|
|
364
383
|
*
|
|
384
|
+
* Note: This function parses the JSON response in JavaScript rather than using
|
|
385
|
+
* glab's --jq flag, as the --jq flag is not available in all glab versions.
|
|
386
|
+
*
|
|
365
387
|
* @param {Object} options - Options
|
|
366
388
|
* @param {string} options.hostname - GitLab hostname (optional)
|
|
367
389
|
* @param {boolean} options.verbose - Enable verbose logging
|
|
@@ -374,7 +396,7 @@ export async function getGitLabEmail(options = {}) {
|
|
|
374
396
|
|
|
375
397
|
log.debug('Getting GitLab primary email...');
|
|
376
398
|
|
|
377
|
-
const args = ['api', 'user'
|
|
399
|
+
const args = ['api', 'user'];
|
|
378
400
|
if (hostname) {
|
|
379
401
|
args.push('--hostname', hostname);
|
|
380
402
|
}
|
|
@@ -385,7 +407,17 @@ export async function getGitLabEmail(options = {}) {
|
|
|
385
407
|
throw new Error(`Failed to get GitLab email: ${result.stderr}`);
|
|
386
408
|
}
|
|
387
409
|
|
|
388
|
-
|
|
410
|
+
// Parse JSON response in JavaScript (glab's --jq flag is not available in all versions)
|
|
411
|
+
let userData;
|
|
412
|
+
try {
|
|
413
|
+
userData = JSON.parse(result.stdout.trim());
|
|
414
|
+
} catch (parseError) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
`Failed to parse GitLab user data: ${parseError.message}. Raw output: ${result.stdout}`
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const email = userData.email;
|
|
389
421
|
|
|
390
422
|
if (!email) {
|
|
391
423
|
throw new Error(
|
|
@@ -401,6 +433,10 @@ export async function getGitLabEmail(options = {}) {
|
|
|
401
433
|
/**
|
|
402
434
|
* Get GitLab user information (username and primary email)
|
|
403
435
|
*
|
|
436
|
+
* Note: This function makes a single API call and parses both username and email
|
|
437
|
+
* from the response, which is more efficient than calling getGitLabUsername and
|
|
438
|
+
* getGitLabEmail separately.
|
|
439
|
+
*
|
|
404
440
|
* @param {Object} options - Options
|
|
405
441
|
* @param {string} options.hostname - GitLab hostname (optional)
|
|
406
442
|
* @param {boolean} options.verbose - Enable verbose logging
|
|
@@ -408,10 +444,49 @@ export async function getGitLabEmail(options = {}) {
|
|
|
408
444
|
* @returns {Promise<{username: string, email: string}>} User information
|
|
409
445
|
*/
|
|
410
446
|
export async function getGitLabUserInfo(options = {}) {
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
447
|
+
const { hostname, verbose = false, logger = console } = options;
|
|
448
|
+
const log = createDefaultLogger({ verbose, logger });
|
|
449
|
+
|
|
450
|
+
log.debug('Getting GitLab user information...');
|
|
451
|
+
|
|
452
|
+
const args = ['api', 'user'];
|
|
453
|
+
if (hostname) {
|
|
454
|
+
args.push('--hostname', hostname);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const result = await $`glab ${args}`.run({ capture: true });
|
|
458
|
+
|
|
459
|
+
if (result.code !== 0) {
|
|
460
|
+
throw new Error(`Failed to get GitLab user info: ${result.stderr}`);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Parse JSON response in JavaScript (glab's --jq flag is not available in all versions)
|
|
464
|
+
let userData;
|
|
465
|
+
try {
|
|
466
|
+
userData = JSON.parse(result.stdout.trim());
|
|
467
|
+
} catch (parseError) {
|
|
468
|
+
throw new Error(
|
|
469
|
+
`Failed to parse GitLab user data: ${parseError.message}. Raw output: ${result.stdout}`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const username = userData.username;
|
|
474
|
+
const email = userData.email;
|
|
475
|
+
|
|
476
|
+
if (!username) {
|
|
477
|
+
throw new Error(
|
|
478
|
+
'No username found in GitLab user data. Please ensure your GitLab account has a username.'
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (!email) {
|
|
483
|
+
throw new Error(
|
|
484
|
+
'No email found on GitLab account. Please set a primary email in your GitLab settings.'
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
log.debug(`GitLab username: ${username}`);
|
|
489
|
+
log.debug(`GitLab primary email: ${email}`);
|
|
415
490
|
|
|
416
491
|
return { username, email };
|
|
417
492
|
}
|