Esta questão se refere a trabalhar com um projeto Python + Poetry em um pipeline Jenkins e como manter o.venv/
CENÁRIO:
Eu tenho um trabalho do Jenkins Pipeline que aciona um projeto Python. O projeto usa poesia para criar um ambiente virtual em .venv dentro do espaço de trabalho. A cada execução de trabalho subsequente, ele reutilizará o .venv conforme o esperado, de modo que cada pacote pip não precise ser baixado novamente a cada execução (a menos que haja um diff no arquivo poet.lock). Tudo funciona como esperado.
Eu quero fazer uma alteração no Pipeline usando o Jenkins Workspace Cleanup Plugin, quero destruir os arquivos do espaço de trabalho, mas manter alguns arquivos, incluindo os arquivos de ambiente pip/poetry/venv . Isso é para permitir que ele reutilize pacotes pip da execução anterior ainda armazenados em .venv -- assim como faz no Pipeline de trabalho hoje.
O exemplo de arquivo de pipeline completo está na parte inferior deste post, mas aqui está um trecho da parte cleanWs() que adicionei ao pipeline existente:
post {
always {
cleanWs(
deleteDirs: true,
notFailBuild: true,
patterns: [
[pattern: '.venv', type: 'EXCLUDE'],
[pattern: '.venv/**', type: 'EXCLUDE']
]
)
}
}
AQUI ESTÁ A QUESTÃO:
Na primeira vez que o trabalho é executado, ele funciona perfeitamente e a limpeza do espaço de trabalho funciona conforme o esperado. O
.venv/
diretório é mantido conforme o esperado.(problema) Em execuções subsequentes do trabalho, o Poesia reinstalará todos os pacotes e não reutilizará o diretório .venv :
Creating virtualenv test in /data/jenkins_home/workspace/test-cleanup/.venv
-- Isso força um novo download completo de cada pacote, mesmo que.venv
já exista. Foi confirmado que/data/jenkins_home/workspace/test-cleanup/.venv
já existe antes da execução do trabalho.Aqui está a parte estranha: se eu for para o diretório do espaço de trabalho manualmente no servidor Jenkins e executar exatamente o mesmo comando
poetry install
, ele funcionará conforme o esperado,.venv
será reutilizado e todos os pacotes não serão reinstalados. Portanto, há algo específico sobre a maneira como ele é tratado em execução no trabalho que está fazendo com que ele queira recriar o diretório .venv.
NOTA que in-project = true
já está definido para Poesia. Portanto, ele sempre tentará usar .venv dentro do diretório de trabalho atual.
EXEMPLOS:
Aqui está um pipeline de exemplo simples que funciona conforme o esperado. Quando poetry install
a etapa é executada, ela não baixa novamente todos os pacotes toda vez que o trabalho é executado, apenas na primeira vez ou se houver uma diferença:
pipeline {
agent any
stages {
stage("Prep Build Environment") {
steps {
script {
scmVars = git branch: "main", poll: false, url: "[email protected]:my-org/private-repo.git"
}
sh "poetry install"
}
}
}
}
Aqui está o novo arquivo de pipeline Jenkinsfile com cleanWs()
adicionado. Depois que isso for adicionado, o projeto não reutilizará mais o .venv em cada execução, mesmo que ele ainda exista:
pipeline {
agent any
stages {
stage("Prep Build Environment") {
steps {
script {
scmVars = git branch: "main", poll: false, url: "[email protected]:my-org/private-repo.git"
}
sh "poetry install"
}
}
}
post {
always {
cleanWs(
deleteDirs: true,
notFailBuild: true,
patterns: [
[pattern: '.venv', type: 'EXCLUDE'],
[pattern: '.venv/**', type: 'EXCLUDE']
]
)
}
}
}
Normalmente, um Jenkins Pipeline limpa o espaço de trabalho no início de uma compilação, e é por isso que a pasta .venv existe após a execução da compilação, mas não ao executar a etapa virtualenv durante a próxima compilação.
Se você deseja armazenar em cache ou reter alguns arquivos entre compilações, a maneira mais confiável de fazer isso é armazenar esses arquivos fora do espaço de trabalho. Você precisa ser extremamente cuidadoso com isso, no entanto, porque a execução simultânea de compilações acessando os mesmos arquivos pode levar à contenção de recursos e condições de corrida e arquivos corrompidos.
A resposta rápida:
Adicione
[pattern: '.git/**', type: 'EXCLUDE']
à sua lista decleanWs()
padrões.Os arquivos do espaço de trabalho, inclusive
.venv/
, persistirão entre as execuções de trabalho.A resposta longa:
Portanto, o problema parece ser que o plugin git sobrecarrega o espaço de trabalho quando o
.git/
diretório está ausente (quando precisa fazer um clone completo). Eu não vejo esse comportamento documentado em qualquer lugar do que eu vi.Como a
cleanWs()
ação remove.git
, ela acionará esse "recurso" do plugin git.Adicionar o
.git/
diretório à lista de exclusão parece ter resolvido o problema original e permite que os outros arquivos persistam entre as compilações.Esse comportamento pode ser comprovado:
Etapas de pipeline que gravam um arquivo no espaço de trabalho e fazem check-out do repositório.
Depois que o trabalho for executado uma vez,
foo.txt
persistirá no espaço de trabalho:Remova
.git
os dados após a clonagem:Depois que o trabalho for executado uma vez,
foo.txt
agora estará ausente no início de cada execução de trabalho:Postagem final/sempre snippet de bloco. As instalações de poesia e o env virtual estão funcionando como esperado agora: