Ambientes por trabalho no Jenkins com virtualenv

Ambientes por trabalho no Jenkins com virtualenv

Estou tentando usar virtualenvpara gerenciar programaticamente ambientes Python para cada trabalho em um servidor Jenkins, implementado por meio de umBiblioteca Compartilhadaextensão para ativar ambientes por trabalho. Por exemplo:

/vars/activateEnvironment.groovy:

def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {

    sh """
    mkdir ${env}
    virtualenv ${env}
    source ${env}/bin/activate
    """
}

Script de pipeline, no qual o virtualenv-scriptsrepositório contém o arquivo acima:

@Library('virtualenv-scripts') _

pipeline {
    agent any
    stages {
        stage("Test") {
            steps {
                activateEnvironment()
                sh 'which pip'
                sh 'echo \$PATH'
            }
        }
    }
}

Executando este script de pipeline, obtenho a seguinte saída:

[Pipeline] sh
[example-pipeline] Running shell script
+ echo /sbin:/usr/sbin:/bin:/usr/bin
/sbin:/usr/sbin:/bin:/usr/bin
[Pipeline] sh
[example-pipeline] Running shell script
+ which pip
/bin/pip

Eu tentei usaresta respostapara fazer o Jenkins usar um shell de login, mas que ainda recarrega o ambiente a cada shchamada.

eu também viesta respostao que exigiria a colagem de texto extra sempre que uma shetapa fosse usada em um pipeline - o que não é o ideal.

Existe uma boa maneira de manter o ambiente entre shos comandos? Como alternativa, existe uma maneira melhor de obter ambientes por trabalho com virtualenv? Obrigado por toda ajuda/sugestões!

Responder1

Eu tive o mesmo problema. Depois de conversar com alguns administradores veteranos do Jenkins, esta é a solução que cheguei:

def runCommandInMyEnvironment(cmd) {
  sh "setup_environment_command; source ./some/file; ${cmd}"
}

pipeline {
  agent any
  stages {
    stage("My Stage") {
      steps {
        runCommandInMyEnvironment('first_command')
        runCommandInMyEnvironment('second_command')
        // and so on
      }
    }
  }
}

Não é bonito e pode atrapalhar um pouco a saída do console, mas também é a maneira mais confiável de fazer isso.

Outra abordagem seria analisar a saída de algum comando e dividi-la em um monte de variáveis ​​de ambiente e depois passá-las para um withEnvbloco, mas esta pode ser uma abordagem muito complicada e não confiável.

De qualquer forma, como você mencionou, o Jenkins não oferece suporte a ambientes persistentes sem withEnv, então, em última análise, não há uma maneira realmente boa ou limpa de fazer isso.

Pode haver uma maneira melhor de usar virtualenvs com Jenkins, mas nunca escrevi um trabalho do Jenkins que execute tarefas em um virtualenv, então não posso dizer. Háeste plug-in, masoutra resposta stackoverflowsugere que a abordagem que dei nesta resposta é o método preferido para trabalhar com virtualenvs no Jenkins.

informação relacionada