Jenkins & Bitbucket; cancelar a compilação anterior se a nova confirmação for feita no mesmo ramo?

7

Temos Jenkins executando testes de unidade quando são feitas confirmações em nosso repositório no Bitbucket. Isso é controlado pelo Bitbucket Plugin, ou seja, através de um webhook Bitbucket.

Atualmente, se uma confirmação for feita na Filial A, um teste de unidade será iniciado. Se enquanto esse trabalho estiver sendo executado, uma segunda confirmação for feita na Ramificação A, um segundo teste de unidade será iniciado, então agora existem dois testes de unidade na mesma ramificação, mas com um código ligeiramente diferente.

Nosso comportamento preferido é que o primeiro teste de confirmação seja abortado quando o segundo teste iniciar, de modo que apenas o teste de unidade mais recente esteja sendo executado. Isso pode ser alcançado?

Esclarecer; Como temos muitas ramificações, não podemos apenas impedir compilações simultâneas, cancelar a última assim que a próxima iniciar, etc. Qualquer que seja o método usado, deve verificar especificamente se a ramificação já possui um trabalho em execução, não se o trabalho em geral já está corrida.

Eu já vi alguns controles de gatilho para o Git, mas não o Bitbucket. Também encontrei um script para verificar se o trabalho já está em execução e cancelá-lo, se sim, mas como mencionado anteriormente, isso não se adequa ao nosso caso de uso. Estou esquecendo de algo?

Alex
fonte
Isso se torna muito mais fácil se você usar o plug-in Bitbucket Branch Source, pois cada ramo e PR de um repositório em um projeto Bitbucket teria seu próprio trabalho Jenkins, e a partir daí é trivialmente fácil verificar se um trabalho tem uma compilação mais recente em execução e abortar se assim for.
Jayhendren
Você encontrou alguma solução? Especialmente para bitbucket?
User43968

Respostas:

3

Nota: esta resposta vem do meu histórico de criação de soluções personalizadas, não é apenas uma configuração, que, se disponível, obviamente seria preferível. Mas talvez seja algo a considerar em contrário.

Você pode ensinar o script que executa a tarefa de teste de unidade a persistir em um estado de execução por ramificação.

Quando o script é iniciado, ele precisa obter o nome da ramificação de seus parâmetros de chamada. Ele obteria o estado persistente para a ramificação.

Se o estado estiver ausente ou not runningo running + job IDdefiniria, execute o teste de unidade e defina o estado para not running(ou exclua-o).

Se o estado estiver running + job ID, significa que outro teste de unidade já está em execução e você tem o ID da tarefa correspondente. O script pode então (normalmente?) Encerrar o trabalho já em execução por seu ID e substituí-lo, atualizando o estado para running + new job ID.

Mas o IMHO encerrar um trabalho em andamento (que pode estar muito próximo da conclusão) não é o ideal - deixa espaço para constantemente matar empregos e lançar novos para ser apenas, por sua vez, morto por trabalhos subsequentes - tudo sem realmente concluir deles.

Em vez disso, modificaria a lógica para:

  • deixe o trabalho em andamento sozinho e, em vez disso, apenas registre no estado persistente a pending job ID(um valor exclusivo, substituído para refletir o trabalho pendente mais recente enviado ou uma lista de todos os trabalhos pendentes, classificados pelo tempo de envio)
  • quando o trabalho em andamento é concluído, ele verifica os pending job IDvalores e, se houver, inicia o mais recente (ou o mais antigo, ou mesmo segue outra lógica de seleção, se estiver usando uma lista)

Essa abordagem evita o desperdício de recursos de teste de unidade e pode ser facilmente ajustada mesmo para mais de um, mas ainda recursos limitados.

Dan Cornilescu
fonte