From cb3d75ec4e719a6c54d55d68ec135161a1c994aa Mon Sep 17 00:00:00 2001 From: Oleg Krivtsov <olegkrivtsov@gmail.com> Date: Wed, 24 Nov 2021 12:14:24 +0700 Subject: [PATCH] feat(platform/gitlab): confidential issues (#12728) --- docs/usage/configuration-options.md | 7 ++ lib/config/options/index.ts | 8 ++ lib/config/types.ts | 1 + .../gitlab/__snapshots__/index.spec.ts.snap | 93 ++++++++++++++++++- lib/platform/gitlab/index.spec.ts | 57 ++++++++++++ lib/platform/gitlab/index.ts | 3 + lib/platform/types.ts | 1 + .../repository/dependency-dashboard.ts | 1 + lib/workers/repository/error-config.ts | 1 + lib/workers/repository/process/deprecated.ts | 1 + 10 files changed, 169 insertions(+), 4 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 35580f5723..d71ff1f41c 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -377,6 +377,13 @@ Set to `null` (not recommended) to fully omit `--ignore-platform-reqs/--ignore-p This requires the Renovate image to be fully compatible with your Composer platform requirements in order for the Composer invocation to succeed, otherwise Renovate will fail to create the updated lock file. The Composer output should inform you about the reasons the update failed. +## confidential + +If enabled, all issues created by Renovate are set as confidential, even in a public repository. +**Note:** the Dependency Dashboard issue will also be confidential. +By default issues created by Renovate are visible to all users. +This option is applicable to GitLab only. + ## configWarningReuseIssue Renovate's default behavior is to reuse/reopen a single Config Warning issue in each repository so as to keep the "noise" down. diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 2321dbbc47..2d0d0bebb3 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1667,6 +1667,14 @@ const options: RenovateOptions[] = [ default: false, supportedPlatforms: ['gitlab'], }, + { + name: 'confidential', + description: + 'If enabled, issues created by Renovate are set as confidential.', + type: 'boolean', + default: false, + supportedPlatforms: ['gitlab'], + }, { name: 'reviewersSampleSize', description: 'Take a random sample of given size from reviewers.', diff --git a/lib/config/types.ts b/lib/config/types.ts index 470709ae7e..c1ca573ce6 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -27,6 +27,7 @@ export interface RenovateSharedConfig { manager?: string; commitMessage?: string; commitMessagePrefix?: string; + confidential?: boolean; draftPR?: boolean; enabled?: boolean; enabledManagers?: string[]; diff --git a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap index f12f50e878..35afb53a28 100644 --- a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap +++ b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap @@ -1190,6 +1190,41 @@ Array [ ] `; +exports[`platform/gitlab/index ensureIssue() creates confidential issue 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer 123test", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/undefined/issues?per_page=100&scope=created_by_me&state=opened", + }, + Object { + "body": Object { + "confidential": true, + "description": "new-content", + "labels": "", + "title": "new-title", + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer 123test", + "content-length": "81", + "content-type": "application/json", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "POST", + "url": "https://gitlab.com/api/v4/projects/undefined/issues", + }, +] +`; + exports[`platform/gitlab/index ensureIssue() creates issue 1`] = ` Array [ Object { @@ -1205,6 +1240,7 @@ Array [ }, Object { "body": Object { + "confidential": false, "description": "new-content", "labels": "", "title": "new-title", @@ -1213,7 +1249,7 @@ Array [ "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer 123test", - "content-length": "61", + "content-length": "82", "content-type": "application/json", "host": "gitlab.com", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", @@ -1239,6 +1275,7 @@ Array [ }, Object { "body": Object { + "confidential": false, "description": "new-content", "labels": "Renovate,Maintenance", "title": "new-title", @@ -1247,7 +1284,7 @@ Array [ "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer 123test", - "content-length": "81", + "content-length": "102", "content-type": "application/json", "host": "gitlab.com", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", @@ -1285,6 +1322,52 @@ Array [ ] `; +exports[`platform/gitlab/index ensureIssue() updates confidential issue 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer 123test", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/undefined/issues?per_page=100&scope=created_by_me&state=opened", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer 123test", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/undefined/issues/2", + }, + Object { + "body": Object { + "confidential": true, + "description": "newer-content", + "labels": "Renovate,Maintenance", + "title": "title-2", + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer 123test", + "content-length": "101", + "content-type": "application/json", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "PUT", + "url": "https://gitlab.com/api/v4/projects/undefined/issues/2", + }, +] +`; + exports[`platform/gitlab/index ensureIssue() updates issue 1`] = ` Array [ Object { @@ -1311,6 +1394,7 @@ Array [ }, Object { "body": Object { + "confidential": false, "description": "newer-content", "labels": "", "title": "title-2", @@ -1319,7 +1403,7 @@ Array [ "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer 123test", - "content-length": "61", + "content-length": "82", "content-type": "application/json", "host": "gitlab.com", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", @@ -1356,6 +1440,7 @@ Array [ }, Object { "body": Object { + "confidential": false, "description": "newer-content", "labels": "Renovate,Maintenance", "title": "title-2", @@ -1364,7 +1449,7 @@ Array [ "accept": "application/json", "accept-encoding": "gzip, deflate, br", "authorization": "Bearer 123test", - "content-length": "81", + "content-length": "102", "content-type": "application/json", "host": "gitlab.com", "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts index b4714de7ed..f269426ed3 100644 --- a/lib/platform/gitlab/index.spec.ts +++ b/lib/platform/gitlab/index.spec.ts @@ -890,6 +890,63 @@ describe('platform/gitlab/index', () => { expect(res).toBeNull(); expect(httpMock.getTrace()).toMatchSnapshot(); }); + + it('creates confidential issue', async () => { + httpMock + .scope(gitlabApiHost) + .get( + '/api/v4/projects/undefined/issues?per_page=100&scope=created_by_me&state=opened' + ) + .reply(200, [ + { + iid: 1, + title: 'title-1', + }, + { + iid: 2, + title: 'title-2', + }, + ]) + .post('/api/v4/projects/undefined/issues') + .reply(200); + const res = await gitlab.ensureIssue({ + title: 'new-title', + body: 'new-content', + confidential: true, + }); + expect(res).toBe('created'); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + + it('updates confidential issue', async () => { + httpMock + .scope(gitlabApiHost) + .get( + '/api/v4/projects/undefined/issues?per_page=100&scope=created_by_me&state=opened' + ) + .reply(200, [ + { + iid: 1, + title: 'title-1', + }, + { + iid: 2, + title: 'title-2', + }, + ]) + .get('/api/v4/projects/undefined/issues/2') + .reply(200, { description: 'new-content' }) + .put('/api/v4/projects/undefined/issues/2') + .reply(200); + const res = await gitlab.ensureIssue({ + title: 'title-2', + body: 'newer-content', + labels: ['Renovate', 'Maintenance'], + confidential: true, + }); + expect(res).toBe('updated'); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); }); describe('ensureIssueClosing()', () => { it('closes issue', async () => { diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index 97bb7e18cb..447e59dd4b 100644 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -862,6 +862,7 @@ export async function ensureIssue({ reuseTitle, body, labels, + confidential, }: EnsureIssueConfig): Promise<'updated' | 'created' | null> { logger.debug(`ensureIssue()`); const description = massageMarkdown(sanitize(body)); @@ -886,6 +887,7 @@ export async function ensureIssue({ title, description, labels: (labels || issue.labels || []).join(','), + confidential: confidential ?? false, }, } ); @@ -897,6 +899,7 @@ export async function ensureIssue({ title, description, labels: (labels || []).join(','), + confidential: confidential ?? false, }, }); logger.info('Issue created'); diff --git a/lib/platform/types.ts b/lib/platform/types.ts index 549d2368de..86768972bc 100644 --- a/lib/platform/types.ts +++ b/lib/platform/types.ts @@ -106,6 +106,7 @@ export interface EnsureIssueConfig { labels?: string[]; once?: boolean; shouldReOpen?: boolean; + confidential?: boolean; } export interface BranchStatusConfig { branchName: string; diff --git a/lib/workers/repository/dependency-dashboard.ts b/lib/workers/repository/dependency-dashboard.ts index ce2dfea6f2..7953327c40 100644 --- a/lib/workers/repository/dependency-dashboard.ts +++ b/lib/workers/repository/dependency-dashboard.ts @@ -356,6 +356,7 @@ export async function ensureDependencyDashboard( reuseTitle, body: issueBody, labels: config.dependencyDashboardLabels, + confidential: config.confidential, }); } } diff --git a/lib/workers/repository/error-config.ts b/lib/workers/repository/error-config.ts index c692ed4992..98601171f9 100644 --- a/lib/workers/repository/error-config.ts +++ b/lib/workers/repository/error-config.ts @@ -49,6 +49,7 @@ export async function raiseConfigWarningIssue( body, once, shouldReOpen: shouldReopen, + confidential: config.confidential, }); if (res === 'created') { logger.warn({ configError: error, res }, 'Config Warning'); diff --git a/lib/workers/repository/process/deprecated.ts b/lib/workers/repository/process/deprecated.ts index 53fdc99cf1..af36e8deca 100644 --- a/lib/workers/repository/process/deprecated.ts +++ b/lib/workers/repository/process/deprecated.ts @@ -63,6 +63,7 @@ export async function raiseDeprecationWarnings( title: issueTitle, body: issueBody, once: ensureOnce, + confidential: config.confidential, }); } } -- GitLab