From e063c8f9317c0ad4ad0c67312a1aa66ef9bca91c Mon Sep 17 00:00:00 2001
From: Artur Frysiak <artur@frysiak.net>
Date: Wed, 27 Jan 2021 10:17:42 +0100
Subject: [PATCH] feat: handle GitLab push rule violation (#8416)

* feat: handle GitLab push rule violation

Closes #8414

* feat: handle GitLab push rule violation

* feat: handle GitLab push rule violation

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/util/git/index.ts       | 25 +++++++++++++++++++++++--
 lib/workers/branch/index.ts |  4 ++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index 4f6dd12c0c..bc27895b7f 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -10,6 +10,7 @@ import Git, {
 import { join } from 'upath';
 import { configFileNames } from '../../config/app-strings';
 import {
+  CONFIG_VALIDATION,
   REPOSITORY_CHANGED,
   REPOSITORY_DISABLED,
   REPOSITORY_EMPTY,
@@ -58,7 +59,7 @@ function checkForPlatformFailure(err: Error): void {
   if (process.env.NODE_ENV === 'test') {
     return;
   }
-  const platformFailureStrings = [
+  const externalHostFailureStrings = [
     'remote: Invalid username or password',
     'gnutls_handshake() failed',
     'The requested URL returned error: 5',
@@ -70,12 +71,32 @@ function checkForPlatformFailure(err: Error): void {
     'malformed object name',
     'TF401027:', // You need the Git 'GenericContribute' permission to perform this action
   ];
-  for (const errorStr of platformFailureStrings) {
+  for (const errorStr of externalHostFailureStrings) {
     if (err.message.includes(errorStr)) {
       logger.debug({ err }, 'Converting git error to ExternalHostError');
       throw new ExternalHostError(err, 'git');
     }
   }
+
+  const configErrorStrings = [
+    [
+      'GitLab: Branch name does not follow the pattern',
+      "Cannot push because branch name does not follow project's push rules",
+    ],
+    [
+      'GitLab: Commit message does not follow the pattern',
+      "Cannot push because commit message does not follow project's push rules",
+    ],
+  ];
+  for (const [errorStr, validationError] of configErrorStrings) {
+    if (err.message.includes(errorStr)) {
+      logger.debug({ err }, 'Converting git error to CONFIG_VALIDATION error');
+      const error = new Error(CONFIG_VALIDATION);
+      error.validationError = validationError;
+      error.validationMessage = err.message;
+      throw error;
+    }
+  }
 }
 
 function localName(branchName: string): string {
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index 43faf6cc17..a467aecb9a 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -3,6 +3,7 @@ import { DateTime } from 'luxon';
 import minimatch from 'minimatch';
 import { RenovateConfig } from '../../config';
 import {
+  CONFIG_VALIDATION,
   MANAGER_LOCKFILE_ERROR,
   PLATFORM_AUTHENTICATION_ERROR,
   PLATFORM_BAD_CREDENTIALS,
@@ -574,6 +575,9 @@ export async function processBranch(
     } else if (err.message?.includes('fatal: bad revision')) {
       logger.debug({ err }, 'Aborting job due to bad revision error');
       throw new Error(REPOSITORY_CHANGED);
+    } else if (err.message === CONFIG_VALIDATION) {
+      logger.debug('Passing config validation error up');
+      throw err;
     } else if (!(err instanceof ExternalHostError)) {
       logger.error({ err }, `Error updating branch: ${String(err.message)}`);
     }
-- 
GitLab