diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts index 6c7a301959c3f3c89cc3bba0ac04ba0aecbd0d9b..f6fb3ad3f3c03934ef103b54f25c50169d01450f 100644 --- a/lib/modules/platform/github/index.spec.ts +++ b/lib/modules/platform/github/index.spec.ts @@ -2338,6 +2338,94 @@ describe('modules/platform/github/index', () => { ]); }); + it('should skip automerge if GHE <3.3.0', async () => { + const scope = httpMock + .scope('https://github.company.com') + .head('/') + .reply(200, '', { 'x-github-enterprise-version': '3.1.7' }) + .get('/user') + .reply(200, { + login: 'renovate-bot', + }) + .get('/user/emails') + .reply(200, {}) + .post('/repos/some/repo/pulls') + .reply(200, { + number: 123, + }) + .post('/repos/some/repo/issues/123/labels') + .reply(200, []); + + initRepoMock(scope, 'some/repo'); + await github.initPlatform({ + endpoint: 'https://github.company.com', + token: '123test', + }); + hostRules.find.mockReturnValue({ + token: '123test', + }); + await github.initRepo({ + repository: 'some/repo', + } as any); + await github.createPr(prConfig); + + expect(logger.logger.debug).toHaveBeenNthCalledWith( + 10, + { prNumber: 123 }, + 'GitHub-native automerge: not supported on this GHE version. Requires >=3.3.0' + ); + }); + + it('should perform automerge if GHE >=3.3.0', async () => { + const scope = httpMock + .scope('https://github.company.com') + .head('/') + .reply(200, '', { 'x-github-enterprise-version': '3.3.5' }) + .get('/user') + .reply(200, { + login: 'renovate-bot', + }) + .get('/user/emails') + .reply(200, {}) + .post('/repos/some/repo/pulls') + .reply(200, { + number: 123, + }) + .post('/repos/some/repo/issues/123/labels') + .reply(200, []) + .post('/graphql') + .reply(200, { + data: { + repository: { + defaultBranchRef: { + name: 'main', + }, + nameWithOwner: 'some/repo', + autoMergeAllowed: true, + }, + }, + }); + + initRepoMock(scope, 'some/repo'); + await github.initPlatform({ + endpoint: 'https://github.company.com', + token: '123test', + }); + hostRules.find.mockReturnValue({ + token: '123test', + }); + await github.initRepo({ + repository: 'some/repo', + } as any); + await github.createPr(prConfig); + + expect(logger.logger.debug).toHaveBeenNthCalledWith( + 11, + { prNumber: 123 }, + 'GitHub-native automerge: success' + ); + }); + it('should set automatic merge', async () => { const scope = await mockScope(); scope.post('/graphql').reply(200, graphqlAutomergeResp); diff --git a/lib/modules/platform/github/index.ts b/lib/modules/platform/github/index.ts index 31a92292d3116f6aea27de61247bd005507be2f7..003d4f3cdf9d22ee3c51f9a7ec5a6f5cbcc53a28 100644 --- a/lib/modules/platform/github/index.ts +++ b/lib/modules/platform/github/index.ts @@ -269,7 +269,13 @@ export async function initRepo({ try { let infoQuery = repoInfoQuery; - if (platformConfig.isGhe) { + // GitHub Enterprise Server <3.3.0 doesn't support autoMergeAllowed and hasIssuesEnabled objects + if ( + platformConfig.isGhe && + // semver not null safe, accepts null and undefined + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + semver.satisfies(platformConfig.gheVersion!, '<3.3.0') + ) { infoQuery = infoQuery.replace(/\n\s*autoMergeAllowed\s*\n/, '\n'); infoQuery = infoQuery.replace(/\n\s*hasIssuesEnabled\s*\n/, '\n'); } @@ -1323,10 +1329,23 @@ async function tryPrAutomerge( prNodeId: string, platformOptions: PlatformPrOptions | undefined ): Promise<void> { - if (platformConfig.isGhe || !platformOptions?.usePlatformAutomerge) { + if (!platformOptions?.usePlatformAutomerge) { return; } + // If GitHub Enterprise Server <3.3.0 it doesn't support automerge + if (platformConfig.isGhe) { + // semver not null safe, accepts null and undefined + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + if (semver.satisfies(platformConfig.gheVersion!, '<3.3.0')) { + logger.debug( + { prNumber }, + 'GitHub-native automerge: not supported on this GHE version. Requires >=3.3.0' + ); + return; + } + } + if (!config.autoMergeAllowed) { logger.debug( { prNumber },