diff --git a/lib/modules/platform/github/__snapshots__/index.spec.ts.snap b/lib/modules/platform/github/__snapshots__/index.spec.ts.snap index ed91cf8007a916621b09238c66114e044c5a6de0..457144317a67cb798f78a01ca45178460f7ff4c5 100644 --- a/lib/modules/platform/github/__snapshots__/index.spec.ts.snap +++ b/lib/modules/platform/github/__snapshots__/index.spec.ts.snap @@ -118,6 +118,7 @@ Object { "endpoint": "https://ghe.renovatebot.com/", "gitAuthor": "undefined <user@domain.com>", "renovateUsername": "renovate-bot", + "token": "123test", } `; @@ -126,6 +127,7 @@ Object { "endpoint": "https://ghe.renovatebot.com/", "gitAuthor": "undefined <user@domain.com>", "renovateUsername": "renovate-bot", + "token": "123test", } `; @@ -134,6 +136,7 @@ Object { "endpoint": "https://api.github.com/", "gitAuthor": undefined, "renovateUsername": "renovate-bot", + "token": "123test", } `; @@ -142,6 +145,7 @@ Object { "endpoint": "https://api.github.com/", "gitAuthor": undefined, "renovateUsername": "renovate-bot", + "token": "123test", } `; @@ -150,6 +154,7 @@ Object { "endpoint": "https://api.github.com/", "gitAuthor": "undefined <user@domain.com>", "renovateUsername": "renovate-bot", + "token": "123test", } `; @@ -158,6 +163,7 @@ Object { "endpoint": "https://api.github.com/", "gitAuthor": "renovate@whitesourcesoftware.com", "renovateUsername": "renovate-bot", + "token": "123test", } `; diff --git a/lib/modules/platform/github/index.md b/lib/modules/platform/github/index.md index 7258171ecc0647f2c7d6d650ecc3b4f33bb9dc1f..8f4bac23a8e41925ce404a10d443e10613a24f2f 100644 --- a/lib/modules/platform/github/index.md +++ b/lib/modules/platform/github/index.md @@ -51,9 +51,15 @@ The [GitHub App associated email](https://github.community/t/logging-into-git-as It needs to have the user id _and_ the username followed by the `users.noreply.`-domain of either github.com or the GitHub Enterprise Server. A way to get the user id of a GitHub app is to [query the user API](https://docs.github.com/en/rest/reference/users#get-a-user) at `api.github.com/user/self-hosted-renovate[bot]` (github.com) or `github.enterprise.com/api/v3/uer/self-hosted-renovate[bot]` (GitHub Enterprise Server). -**`token:"x-access-token:${github-app-installation}"`** +**`token:"ghs_123exampletoken"`** -The token needs to be prefixed with `x-access-token` and be a [GitHub App Installation token](https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-an-installation). +You must use a [GitHub App Installation token](https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-an-installation). + +Previously, the token had to be prefixed with `x-access-token:`. +We recommend you replace any prefixed tokens with normal tokens. +We will drop support for prefixed tokens in the future. + +Any tokens that do not start with `ghs_` (for example tokens from GitHub Enterprise Server versions before version `3.2`) must be prefixed with `x-access-token:`. <!-- prettier-ignore --> !!! note diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts index f6fb3ad3f3c03934ef103b54f25c50169d01450f..8ecbbebf86eb559c67c58cbef519daae104699b2 100644 --- a/lib/modules/platform/github/index.spec.ts +++ b/lib/modules/platform/github/index.spec.ts @@ -50,7 +50,7 @@ describe('modules/platform/github/index', () => { describe('initPlatform()', () => { it('should throw if no token', async () => { await expect(github.initPlatform({} as any)).rejects.toThrow( - 'Init: You must configure a GitHub personal access token' + 'Init: You must configure a GitHub token' ); }); @@ -210,6 +210,34 @@ describe('modules/platform/github/index', () => { const repos = await github.getRepos(); expect(repos).toStrictEqual(['a/b', 'c/d']); }); + + it('should return an array of repos when using GitHub App Installation Token', async () => { + //Use Github App token + await github.initPlatform({ + endpoint: githubApiHost, + username: 'self-hosted-renovate[bot]', + gitAuthor: + 'Self-hosted Renovate Bot <123456+self-hosted-renovate[bot]@users.noreply.github.com>', + token: 'ghs_123test', + }); + httpMock + .scope(githubApiHost) + .get('/installation/repositories?per_page=100') + .reply(200, { + repositories: [ + { + full_name: 'a/b', + }, + { + full_name: 'c/d', + }, + null, + ], + }); + + const repos = await github.getRepos(); + expect(repos).toStrictEqual(['a/b', 'c/d']); + }); }); function initRepoMock( diff --git a/lib/modules/platform/github/index.ts b/lib/modules/platform/github/index.ts index b3503aad7a394f377aab79b1862680b096c466dd..1f5c20269dda83ef449e1ed28a30351fd5f5a245 100644 --- a/lib/modules/platform/github/index.ts +++ b/lib/modules/platform/github/index.ts @@ -116,14 +116,15 @@ export async function detectGhe(token: string): Promise<void> { export async function initPlatform({ endpoint, - token, + token: originalToken, username, gitAuthor, }: PlatformParams): Promise<PlatformResult> { + let token = originalToken; if (!token) { - throw new Error('Init: You must configure a GitHub personal access token'); + throw new Error('Init: You must configure a GitHub token'); } - + token = token.replace(/^ghs_/, 'x-access-token:ghs_'); platformConfig.isGHApp = token.startsWith('x-access-token:'); if (endpoint) { @@ -164,6 +165,7 @@ export async function initPlatform({ endpoint: platformConfig.endpoint, gitAuthor: gitAuthor ?? discoveredGitAuthor, renovateUsername, + token, }; return platformResult; diff --git a/lib/modules/platform/index.ts b/lib/modules/platform/index.ts index 889d5cc9eaa97f8f2f5a3e16f12f28664a9664d0..be1315a76b88360ad8d7fcd7260a230fcac76f16 100644 --- a/lib/modules/platform/index.ts +++ b/lib/modules/platform/index.ts @@ -59,6 +59,10 @@ export async function initPlatform(config: AllConfig): Promise<AllConfig> { // TODO: null check (#7154) matchHost: URL.parse(returnConfig.endpoint).hostname!, }; + // There might have been platform-specific modifications to the token + if (returnConfig.token) { + config.token = returnConfig.token; + } ( ['token', 'username', 'password'] as ('token' | 'username' | 'password')[] ).forEach((field) => { diff --git a/lib/modules/platform/types.ts b/lib/modules/platform/types.ts index b38b9b2084fdae839acdcda7333f637132120e67..9fffc1927da50856ec0b775d385e3c34ee58ab17 100644 --- a/lib/modules/platform/types.ts +++ b/lib/modules/platform/types.ts @@ -21,6 +21,7 @@ export interface PlatformParams { export interface PlatformResult { endpoint: string; renovateUsername?: string; + token?: string; gitAuthor?: string; }