Как использовать регулярное выражение оболочки в jenkinsfile для конвейера jenkins? - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь заменить '/' из имени ветви Git на '_' в моем файле jenkinsfile, чтобы я мог пометить свой образ докера именем ветви. В bash приведенная ниже команда работает нормально

echo "${git_branch_name//\//_}"

Но при использовании вышеуказанной команды в jenkinsfile, как показано ниже, выдается ошибка.

    #!/usr/bin/env groovy

    def commit_id
    def imagetag
    def branch_name
    def git_branch_name
    node('Nodename') {

        stage('checkout') {
            checkout (scm).$Branch_Param
            sh "git rev-parse --short HEAD > .git/commit-id"
            commit_id = readFile('.git/commit-id').trim()
            sh "git rev-parse --abbrev-ref HEAD > .git/branch-name"
            git_branch_name = readFile('.git/branch-name').trim()
            branch_name= sh "echo ${git_branch_name//\//_}"
            sh "echo ${commit_id}"
            sh "echo ${branch_name}"
            sh "echo Current branch is ${branch_name}"
        }

    }

WorkflowScript: 15: end of line reached within a simple string 'x' or "x" or /x/;
   solution: for multi-line literals, use triple quotes '''x''' or """x""" or /x/ or $/x/$ @ line 15, column 28.
        sh "branch_name = echo ${git_branch_name//\//_}"

Что я здесь не так делаю? Должен ли я использовать Groovy регулярное выражение вместо оболочки? почему оболочка не интерпретируется правильно?

Спасибо

1 Ответ

0 голосов
/ 23 января 2019

Проблема в том, что вы просите Groovy интерпретировать выражение ${git_branch_name//\//_}, а не оболочку. Использование двойных кавычек вокруг строки, которую вы передаете шагу sh, является причиной этого. Поэтому, если вы вместо этого напишите следующее, эта первая ошибка исчезнет:

    sh 'echo ${git_branch_name//\\//_}' // <- Note the single-quotes

Как правило, всегда используйте одинарные кавычки, если только вам не нужно использовать Groovy's строковую интерполяцию (см. Самый последний echo внизу этого ответа).

Интересно, что когда я проводил тестирование, мне не понадобился шебанг (#!/bin/bash) для указания bash, как предлагают некоторые комментарии; этот ${variable//x/y} синтаксис замены работал в шаге sh как есть. Я думаю, что порожденный снаряд был bash. Я не знаю, так ли это всегда, или наша коробка Дженкинса была специально настроена таким образом.

Также обратите внимание, что вам нужно экранировать escape-последовательность ('\\/'), потому что вы передаете шагу sh строковый литерал в коде groovy. Если вы не добавите этот дополнительный обратный слеш, строка, передаваемая оболочке для интерпретации, будет echo ${git_branch_name////_}, чего она не поймет.

Но есть и другие проблемы. Во-первых, назначение вывода шага sh для branch_name, как вы делаете, означает, что branch_name всегда будет равно нулю. Чтобы получить стандартный вывод из строки шелл-кода, вам нужно передать дополнительный параметр returnStdout: true в sh:

branch_name = sh (
    script: 'echo ${git_branch_name//\\//_}',
    returnStdout: true
).trim ()     // You basically always need to use trim, because the
              // stdout will have a newline at the end

Для получения бонусных баллов мы можем заключить этот колл в замыкание . Я использую его достаточно часто, чтобы сделать это хорошей идеей.

// Get it? `sh` out, "shout!"
def shout = { cmd -> sh (script: cmd, returnStdout: true).trim () }

//...

branch_name = shout 'echo ${git_branch_name//\\//_}'

Но, наконец, главная проблема заключается в том, что bash (или какая-либо оболочка, которая на самом деле была создана) не имеет доступа к переменным groovy. Насколько он знает, echo ${git_branch_name} выводит пустую строку, и, следовательно, echo ${git_branch_name//\//_}.

У вас есть несколько вариантов. Вы можете пропустить создание .git/branch-name и сразу же вывести результат с заменой строки git rev-parse:

branch_name = shout 'name=$(git rev-parse --abbrev-ref HEAD) && echo ${name//\\//_}'

Или чтобы упростить дальнейшее использование функции замены строк в groovy, а не синтаксиса bash:

branch_name = shout ('git rev-parse --abbrev-ref HEAD').replace ('/', '_')

Лично я нахожу последнее немного более читабельным. YMMV. Итак, собрав все вместе, наконец:

#!groovy

def shout = { cmd -> sh (script: cmd, returnStdout: true).trim () }

// Note that I'm not declaring any variables up here. They're not needed.
// But you can if you want, just to clearly declare the environment for
// future maintainers.

node ('Nodename') {
    stage ('checkout') {
        checkout (scm).$Branch_Param
        commit_id = shout 'git rev-parse --short HEAD'
        branch_name = shout ('git rev-parse --abbrev-ref HEAD').replace ('/', '_')

        echo commit_id
        echo branch_name
        echo "The most recent commit on branch ${branch_name} was ${commit_id}"
    }
}
...