From 9eef9f60676caf4d61d9a1273b2755bcb5c63f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Sun, 26 May 2024 12:37:35 +0200 Subject: [PATCH] feat: use get-github-auth-token instead of gh auth token (#1533) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## PR Checklist - [x] Addresses an existing open issue: fixes #1532 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Swaps out `gh auth token` with `await getGitHubAuthToken()`. Doesn't fully remove the dependency on `gh`. 💖 --- package.json | 1 + pnpm-lock.yaml | 12 ++++++++++++ src/shared/options/getGitHub.test.ts | 23 +++++++++++++++-------- src/shared/options/getGitHub.ts | 15 +++++++-------- src/steps/uninstallPackages.ts | 1 + 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index febbbcea6..4838f9ea4 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "all-contributors-for-repository": "^0.2.1", "chalk": "^5.3.0", "execa": "^9.0.0", + "get-github-auth-token": "^0.1.0", "git-remote-origin-url": "^4.0.0", "git-url-parse": "^14.0.0", "js-yaml": "^4.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 009933bfe..fd110938a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: execa: specifier: ^9.0.0 version: 9.1.0 + get-github-auth-token: + specifier: ^0.1.0 + version: 0.1.0 git-remote-origin-url: specifier: ^4.0.0 version: 4.0.0 @@ -2366,6 +2369,10 @@ packages: get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-github-auth-token@0.1.0: + resolution: {integrity: sha512-ENm+A39AV0X4+Ls1jiCvmqx+C8hSYTv4d5hV9Ks+EL+gx9a0P9pYYpRE1k2ExwRT3EFQabGXF1Rkdp5FIsLkiw==} + engines: {node: '>=18'} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -2441,10 +2448,12 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -3743,6 +3752,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@5.0.7: @@ -6903,6 +6913,8 @@ snapshots: get-func-name@2.0.2: {} + get-github-auth-token@0.1.0: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 diff --git a/src/shared/options/getGitHub.test.ts b/src/shared/options/getGitHub.test.ts index 10dd11cf6..3cbe3a2a8 100644 --- a/src/shared/options/getGitHub.test.ts +++ b/src/shared/options/getGitHub.test.ts @@ -2,11 +2,11 @@ import { describe, expect, it, vi } from "vitest"; import { getGitHub } from "./getGitHub.js"; -const mock$ = vi.fn(); +const mockGetGitHubAuthToken = vi.fn(); -vi.mock("execa", () => ({ - get $() { - return mock$; +vi.mock("get-github-auth-token", () => ({ + get getGitHubAuthToken() { + return mockGetGitHubAuthToken; }, })); @@ -25,17 +25,24 @@ vi.mock("octokit", () => ({ })); describe("getOctokit", () => { - it("throws an error when gh auth status fails", async () => { - mock$.mockRejectedValueOnce(new Error("Oh no!")); + it("throws an error when getGitHubAuthToken fails", async () => { + mockGetGitHubAuthToken.mockResolvedValue({ + error: "Oh no!", + succeeded: false, + }); await expect(getGitHub).rejects.toMatchInlineSnapshot( "[Error: GitHub authentication failed.]", ); }); - it("returns a new Octokit when gh auth status succeeds", async () => { + it("returns a new Octokit when getGitHubAuthToken succeeds", async () => { const auth = "abc123"; - mock$.mockResolvedValueOnce({}).mockResolvedValueOnce({ stdout: auth }); + + mockGetGitHubAuthToken.mockResolvedValue({ + succeeded: true, + token: auth, + }); const actual = await getGitHub(); diff --git a/src/shared/options/getGitHub.ts b/src/shared/options/getGitHub.ts index 13336901b..2a737955a 100644 --- a/src/shared/options/getGitHub.ts +++ b/src/shared/options/getGitHub.ts @@ -1,4 +1,4 @@ -import { $ } from "execa"; +import { getGitHubAuthToken } from "get-github-auth-token"; import { Octokit } from "octokit"; export interface GitHub { @@ -7,16 +7,15 @@ export interface GitHub { } export async function getGitHub(): Promise { - try { - await $`gh auth status`; - } catch (error) { + const auth = await getGitHubAuthToken(); + + if (!auth.succeeded) { throw new Error("GitHub authentication failed.", { - cause: (error as Error).message, + cause: auth.error, }); } - const auth = (await $`gh auth token`).stdout.trim(); - const octokit = new Octokit({ auth }); + const octokit = new Octokit({ auth: auth.token }); - return { auth, octokit }; + return { auth: auth.token, octokit }; } diff --git a/src/steps/uninstallPackages.ts b/src/steps/uninstallPackages.ts index 68e7ab4a7..ea22f9c0a 100644 --- a/src/steps/uninstallPackages.ts +++ b/src/steps/uninstallPackages.ts @@ -11,6 +11,7 @@ export async function uninstallPackages(offline: boolean | undefined) { "all-contributors-for-repository", "chalk", "execa", + "get-github-auth-token", "git-remote-origin-url", "git-url-parse", "lazy-value",