From 5126d1ce11ddb835679053f01e090bb04e38877c Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Thu, 4 Mar 2021 13:30:27 +0100
Subject: [PATCH] fix(gitea): check version for addReviewers (#8980)

---
 .../__snapshots__/gitea-helper.spec.ts.snap   | 15 ++++++++++
 lib/platform/gitea/gitea-helper.spec.ts       | 11 +++++++
 lib/platform/gitea/gitea-helper.ts            |  6 ++++
 lib/platform/gitea/index.md                   |  2 +-
 lib/platform/gitea/index.spec.ts              | 30 +++++++++++++++++--
 lib/platform/gitea/index.ts                   | 10 +++++++
 6 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
index bf1ff386c2..f9c896a82a 100644
--- a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
+++ b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
@@ -561,6 +561,21 @@ Array [
 ]
 `;
 
+exports[`platform/gitea/gitea-helper getVersion should call /api/v1/version endpoint 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate",
+      "host": "gitea.renovatebot.com",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://gitea.renovatebot.com/api/v1/version",
+  },
+]
+`;
+
 exports[`platform/gitea/gitea-helper mergePR should call /api/v1/repos/[repo]/pulls/[pull]/merge endpoint 1`] = `
 Array [
   Object {
diff --git a/lib/platform/gitea/gitea-helper.spec.ts b/lib/platform/gitea/gitea-helper.spec.ts
index 77f3f3f23a..2e74e94955 100644
--- a/lib/platform/gitea/gitea-helper.spec.ts
+++ b/lib/platform/gitea/gitea-helper.spec.ts
@@ -157,6 +157,17 @@ describe('platform/gitea/gitea-helper', () => {
     });
   });
 
+  describe('getVersion', () => {
+    it('should call /api/v1/version endpoint', async () => {
+      const version = '1.13.01.14.0+dev-754-g5d2b7ba63';
+      httpMock.scope(baseUrl).get('/version').reply(200, { version });
+
+      const res = await ght.getVersion();
+      expect(httpMock.getTrace()).toMatchSnapshot();
+      expect(res).toEqual(version);
+    });
+  });
+
   describe('searchRepos', () => {
     it('should call /api/v1/repos/search endpoint', async () => {
       httpMock
diff --git a/lib/platform/gitea/gitea-helper.ts b/lib/platform/gitea/gitea-helper.ts
index 8026280f41..5d07710d2b 100644
--- a/lib/platform/gitea/gitea-helper.ts
+++ b/lib/platform/gitea/gitea-helper.ts
@@ -200,6 +200,12 @@ export async function getCurrentUser(
   return res.body;
 }
 
+export async function getVersion(options?: GiteaHttpOptions): Promise<string> {
+  const url = 'version';
+  const res = await giteaHttp.getJson<{ version: string }>(url, options);
+  return res.body.version;
+}
+
 export async function searchRepos(
   params: RepoSearchParams,
   options?: GiteaHttpOptions
diff --git a/lib/platform/gitea/index.md b/lib/platform/gitea/index.md
index 0640319046..6d61fac37e 100644
--- a/lib/platform/gitea/index.md
+++ b/lib/platform/gitea/index.md
@@ -2,4 +2,4 @@
 
 ## Unsupported platform features/concepts
 
-- **Adding reviewers to PRs not supported**: While Gitea supports a basic implementation for supporting PR reviews, no API support has been implemented so far.
+- **Adding reviewers to PRs not supported**: Gitea older that v1.14.0 doesn't have the required API to support this.
diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts
index be9ceeafe1..1c9e57ff00 100644
--- a/lib/platform/gitea/index.spec.ts
+++ b/lib/platform/gitea/index.spec.ts
@@ -12,8 +12,14 @@ import { logger as _logger } from '../../logger';
 import { BranchStatus, PrState } from '../../types';
 import * as _git from '../../util/git';
 import { setBaseUrl } from '../../util/http/gitea';
+import { PlatformResult } from '../types';
 import * as ght from './gitea-helper';
 
+/**
+ * latest tested gitea version.
+ */
+const GITEA_VERSION = '1.14.0+dev-754-g5d2b7ba63';
+
 describe('platform/gitea', () => {
   let gitea: Platform;
   let helper: jest.Mocked<typeof import('./gitea-helper')>;
@@ -164,6 +170,12 @@ describe('platform/gitea', () => {
     setBaseUrl('https://gitea.renovatebot.com/api/v1');
   });
 
+  function initFakePlatform(version = GITEA_VERSION): Promise<PlatformResult> {
+    helper.getCurrentUser.mockResolvedValueOnce(mockUser);
+    helper.getVersion.mockResolvedValueOnce(version);
+    return gitea.initPlatform({ token: 'abc' });
+  }
+
   function initFakeRepo(
     repo?: Partial<ght.Repo>,
     config?: Partial<RepoParams>
@@ -1295,21 +1307,35 @@ describe('platform/gitea', () => {
 
   describe('addReviewers', () => {
     it('should assign reviewers', async () => {
-      expect.assertions(2);
+      expect.assertions(3);
+      await initFakePlatform();
       const mockPR = mockPRs[0];
       await expect(
         gitea.addReviewers(mockPR.number, ['me', 'you'])
       ).resolves.not.toThrow();
 
       expect(helper.requestPrReviewers).toHaveBeenCalledTimes(1);
+      expect(logger.warn).not.toHaveBeenCalled();
+    });
+    it('should should do nothing if version to old', async () => {
+      expect.assertions(3);
+      const mockPR = mockPRs[0];
+      await expect(
+        gitea.addReviewers(mockPR.number, ['me', 'you'])
+      ).resolves.not.toThrow();
+
+      expect(helper.requestPrReviewers).not.toHaveBeenCalled();
+      expect(logger.warn).not.toHaveBeenCalled();
     });
     it('catches errors', async () => {
-      expect.assertions(1);
+      expect.assertions(2);
       const mockPR = mockPRs[0];
+      await initFakePlatform();
       helper.requestPrReviewers.mockRejectedValueOnce(null);
       await expect(
         gitea.addReviewers(mockPR.number, ['me', 'you'])
       ).resolves.not.toThrow();
+      expect(logger.warn).toHaveBeenCalled();
     });
   });
 
diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts
index bdbe2b31e4..49fd954094 100644
--- a/lib/platform/gitea/index.ts
+++ b/lib/platform/gitea/index.ts
@@ -1,5 +1,6 @@
 import URL from 'url';
 import is from '@sindresorhus/is';
+import { lt } from 'semver';
 import {
   REPOSITORY_ACCESS_FORBIDDEN,
   REPOSITORY_ARCHIVED,
@@ -51,6 +52,7 @@ interface GiteaRepoConfig {
 const defaults = {
   hostType: PLATFORM_TYPE_GITEA,
   endpoint: 'https://gitea.com/api/v1/',
+  version: '0.0.0',
 };
 
 let config: GiteaRepoConfig = {} as any;
@@ -191,6 +193,7 @@ const platform: Platform = {
       gitAuthor = `${user.full_name || user.username} <${user.email}>`;
       botUserID = user.id;
       botUserName = user.username;
+      defaults.version = await helper.getVersion({ token });
     } catch (err) {
       logger.debug(
         { err },
@@ -792,6 +795,13 @@ const platform: Platform = {
 
   async addReviewers(number: number, reviewers: string[]): Promise<void> {
     logger.debug(`Adding reviewers '${reviewers?.join(', ')}' to #${number}`);
+    if (lt(defaults.version, '1.14.0')) {
+      logger.debug(
+        { version: defaults.version },
+        'Adding reviewer not yet supported.'
+      );
+      return;
+    }
     try {
       await helper.requestPrReviewers(config.repository, number, { reviewers });
     } catch (err) {
-- 
GitLab