Na era do CI / CD onipresente, somos confrontados com uma ampla gama de ferramentas relacionadas, incluindo sistemas de CI. No entanto, foi o GitLab que se tornou o mais próximo de nós, verdadeiramente “nativo”. Ele ganhou notável popularidade na indústria como um todo *. Os desenvolvedores do produto não ficaram para trás do crescente interesse em seu uso, deliciando regularmente a comunidade de desenvolvedores e engenheiros de DevOps com novas versões.
Mês do repositório GitLab e agregação de tagsGitLab é o caso quando o desenvolvimento ativo traz muitos recursos novos e interessantes. Se, para usuários em potencial, esse é apenas um dos fatores de escolha de uma ferramenta, para os existentes, a situação é a seguinte: se você não atualizou sua instalação do GitLab no mês passado, com grande probabilidade de perder algo interessante. Incluindo atualizações de segurança emergentes regularmente.Sobre os mais significativos - ou seja, exigido pelos nossos engenheiros e clientes do DevOps - inovações nas versões mais recentes da edição do GitLab para comunidade, e este artigo será discutido.* 5 , «GitLab», : «, GitHub?». — , Google Trends 5- «gitlab» . «» , . , , «» .№1: needs
Pensamento dependencies
- é disso que você precisa? Provavelmente, não fomos os únicos que cometeram o erro de atribuir essa diretiva ... É necessário listar os trabalhos anteriores, cujos artefatos serão necessários. São artefatos, e não dependência do desempenho da tarefa anterior.Suponha que aconteceu que em um estágio existam trabalhos que não são necessários para serem executados, mas, por alguma razão, não há possibilidade ou apenas desejo de levá-los para um estágio separado (a preguiça é o motor do progresso, mas não se deixa levar).Situação:
Como você pode ver, o estágio Deploy contém botões para implementar a produção e o estágio e os testes de selênio do trabalhopor algum motivo não é executado. É simples: ele espera até que todos os trabalhos do estágio anterior sejam concluídos com êxito. No entanto, na estrutura do mesmo pipeline, não precisamos implantar o estágio agora para executar os testes (ele foi bombeado anteriormente, não dentro da tag). O que fazer? Então venha para as necessidades de resgate !Listamos apenas os trabalhos anteriores necessários para executar nossos testes: needs:
- To production (Cluster 1)
- To production (Cluster 2)
... e obtemos um trabalho, que é chamado automaticamente depois que apenas os trabalhos listados são executados:
Convenientemente, certo? Mas uma vez eu esperava que a diretiva funcionasse dessa maneira dependencies
...No. 2: estende
Cansado de ler rolos .gitlab-ci.yaml
? Falta o princípio de reutilização de código? Então você já tentou e provavelmente trouxe o seu .gitlab-ci.yaml
para um estado como este:.base_deploy: &base_deploy
stage: deploy
script:
- my_deploy_command.sh
variables:
CLUSTER: "default-cluster"
MY_VAR: "10"
Deploy Test:
<<: *base_deploy
environment:
url: test.example.com
name: test
Deploy Production:
<<: *base_deploy
environment:
url: production.example.com
name: production
variables:
CLUSTER: "prod-cluster"
MY_VAR: "10"
Parece bom? No entanto, se você olhar de perto, algo chama sua atenção ... Por que mudamos a produção não apenas variables.CLUSTER
, mas também prescrevemos uma segunda vez variables.MY_VAR=10
? Essa variável deve ser retirada base_deploy
? Acontece que não deveria: o YAML funciona para que, redefinindo o que é recebido da âncora, não expanda o conteúdo dos campos correspondentes, mas o substitua . Portanto, somos forçados a listar as variáveis já conhecidas por nós no parágrafo correspondente.Sim, “expande” é a palavra certa: é exatamente assim que o recurso em questão é chamado. Extends
Eles nos permitem não apenas reescrever o campo, como acontece com a âncora, mas realizar uma fusão inteligente para ele:.base_deploy:
stage: deploy
script:
- my_deploy_command.sh
variables:
CLUSTER: "default-cluster"
MY_VAR: "10"
Deploy Production:
extends: .base_deploy
environment:
url: production.example.com
name: production
variables:
CLUSTER: "prod-cluster"
Aqui no trabalho final, Implantar produção, haverá uma variável MY_VAR
com um valor padrão e uma substituída CLUSTER
.Parece que isso é um pouco, mas imagine: você tem um base_deploy
e 20 circuitos implantados de maneira semelhante. Eles precisam ser transmitidos a outras pessoas cluster
, environment.name
preservando um certo conjunto de variáveis ou outros campos correspondentes ... Essa pequena satisfação nos permitiu reduzir a descrição da implantação de muitos circuitos de desenvolvimento em 2-3 vezes.No. 3: inclua
.gitlab-ci.yaml
ainda parece uma instrução dobrável para um aspirador de pó em 20 idiomas (dos quais você entende apenas o seu nativo), é difícil quando você precisa lidar com uma de suas seções sem mudar a aparência de trabalhos desconhecidos encontrados no caminho?Um amigo de longa data da programação ajudará include
:stages:
- test
- build
- deploy
variables:
VAR_FOR_ALL: 42
include:
- local: .gitlab/ci/test.yml
- local: .gitlab/ci/build.yml
- local: .gitlab/ci/deploy-base.yml
- local: .gitlab/ci/deploy-production.yml
Essa. Agora, estamos editando com ousadia a implantação na produção, enquanto os testadores estão ocupados modificando seu arquivo, que nem sequer podemos ver. Além disso, isso ajuda a evitar conflitos de mesclagem: nem sempre é divertido entender o código de outra pessoa.Mas e se conhecermos o pipeline de nossos 20 projetos, podemos explicar a lógica de cada trabalho a partir dele? Como isso nos ajudará? Para aqueles que alcançaram a iluminação na reutilização de código e para todos os que têm muitos projetos semelhantes, você pode:Uma dúzia do mesmo tipo de projetos com código diferente, mas implantados da mesma maneira - com facilidade e sem manter o IC atualizado em todos os repositórios!Um exemplo de uso prático include
também foi dado neste artigo .No. 4: somente / exceto refs
- Condições abrangentes, incluindo variáveis e alterações de arquivo.
- Como essa é uma família inteira de funções, algumas partes começaram a aparecer no GitLab 10.0, enquanto outras (por exemplo
changes
) começaram a aparecer na 11.4. - docs.gitlab.com/ce/ci/yaml/#onlyexcept-advanced
Às vezes, parece-me que este não é um canal que nos escuta, mas nós ele. Uma excelente ferramenta de gerenciamento está only
/ except
- agora integrada. O que isto significa?No caso mais simples (e talvez o mais agradável), pular etapas:Tests:
only:
- master
except:
refs:
- schedules
- triggers
variables:
- $CI_COMMIT_MESSAGE =~ /skip tests/
No trabalho de exemplo, ele é executado apenas na ramificação principal, mas não pode ser acionado por um agendamento ou acionamento (o GitLab compartilha chamadas e acionadores de API, embora essa seja essencialmente a mesma API). O trabalho não será executado se houver uma senha de ignorar testes na mensagem de confirmação . Por exemplo, um erro de digitação no README.md
projeto ou na documentação foi corrigido - por que esperar pelos resultados do teste?"Ei, 2020 está lá fora!" Por que devo explicar sempre à caixa de ferro que não é necessário executar testes ao alterar a documentação? ” E realmente: only:changes
permite executar testes ao alterar arquivos apenas em determinados diretórios. Por exemplo: only:
refs:
- master
- merge_requests
changes:
- "front/**/*"
- "jest.config.js"
- "package.json"
E para a ação inversa - ou seja, não corra - sim except:changes
.No. 5: regras
Esta diretiva é muito semelhante à anterior only:*
, mas com uma diferença importante: permite controlar o parâmetro when
. Por exemplo, se você não deseja remover completamente a possibilidade de iniciar um trabalho. Você pode simplesmente deixar o botão, que, se desejado, será chamado de forma independente, sem iniciar um novo pipeline ou sem confirmar.# 6: ambiente: auto_stop_in
Aprendemos sobre essa oportunidade logo antes da publicação do artigo e ainda não tivemos tempo suficiente para experimentá-lo na prática, mas essa é definitivamente “a mesma coisa” que era tão esperada em vários projetos.Você pode especificar um parâmetro nos ambientes GitLab on_stop
- é muito útil quando você deseja criar e excluir ambientes dinamicamente, por exemplo, para cada filial. O trabalho marcado com k on_stop
é executado, por exemplo, quando a mesclagem do MR está na ramificação mestre ou quando o MR é fechado (ou apenas clicando no botão), devido ao qual o ambiente desnecessário é excluído automaticamente.Tudo é conveniente, lógico, funciona ... se não for pelo fator humano. Muitos desenvolvedores mesclam MRs não clicando em um botão no GitLab, mas localmente via git merge
. Você pode entendê-los: é conveniente! Mas neste caso, a lógicaon_stop
não funciona, acumulamos um ambiente esquecido ... É aqui que os tão esperados vêm a calhar auto_stop_in
.Bônus: cabanas temporárias quando não há oportunidades suficientes
Apesar de todas essas (e muitas outras) funções novas e exigidas do GitLab, infelizmente, às vezes as condições para a realização de um trabalho são simplesmente impossíveis de serem descritas dentro da estrutura dos recursos disponíveis no momento.O GitLab não é perfeito, mas fornece as ferramentas básicas para construir um pipeline de sonhos ... se você estiver pronto para ir além do modesto DSL, mergulhando no mundo dos scripts. Aqui estão algumas soluções de nossa experiência, que de forma alguma pretendem ser ideologicamente corretas ou recomendadas, mas são apresentadas mais para demonstrar diferentes possibilidades com a falta de funcionalidade de API integrada.Solução alternativa nº 1: inicie dois trabalhos com um botão
script:
- >
export CI_PROD_CL1_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
jq '[.[] | select(.name == "Deploy (Cluster 1)")][0] | .id'`
- >
export CI_PROD_CL2_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
jq '[.[] | select(.name == "Deploy (Cluster 2)")][0] | .id'`
- >
curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL1_JOB_ID/play"
- >
curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL2_JOB_ID/play"
E por que não, se você realmente quer?Solução alternativa 2: transferência alterada nos arquivos MR rb para rubocop dentro da imagem
Rubocop:
stage: test
allow_failure: false
script:
...
- export VARFILE=$(mktemp)
- export MASTERCOMMIT=$(git merge-base origin/master HEAD)
- echo -ne 'CHANGED_FILES=' > ${VARFILE}
- if [ $(git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' | wc -w |awk '{print $1}') -gt 0 ]; then
git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' |tr '\n' ' ' >> ${VARFILE} ;
fi
- if [ $(wc -w ${VARFILE} | awk '{print $1}') -gt 1 ]; then
werf --stages-storage :local run rails-dev --docker-options="--rm --user app --env-file=${VARFILE}" -- bash -c /scripts/rubocop.sh ;
fi
- rm ${VARFILE}
Não há imagem dentro .git
, então tive que sair para verificar apenas os arquivos alterados.Nota: Essa não é uma situação muito padrão e uma tentativa desesperada de cumprir muitas condições do problema, cuja descrição não está incluída no escopo deste artigo.Solução nº 3: gatilho para iniciar trabalhos de outros repositórios ao implantar
before_script:
- |
echo '### Trigger review: infra'
curl -s -X POST \
-F "token=$REVIEW_TOKEN_INFRA" \
-F "ref=master" \
-F "variables[REVIEW_NS]=$CI_ENVIRONMENT_SLUG" \
-F "variables[ACTION]=auto_review_start" \
https://gitlab.example.com/api/v4/projects/${INFRA_PROJECT_ID}/trigger/pipeline
Parece que uma coisa tão simples e necessária (no mundo dos microsserviços) está lançando outro microsserviço em um circuito recém-criado como uma dependência. Mas, portanto, não é necessária uma chamada de API e um recurso já familiar (descrito acima): only:
refs:
- triggers
variables:
- $ACTION == "auto_review_start"
Notas:- O trabalho no acionador foi projetado para ser vinculado à passagem de uma variável para a API, da mesma forma que no exemplo 1. É mais lógico implementar isso na API com o nome do trabalho passado.
- Sim, a função está na versão comercial (EE) do GitLab, mas não a consideramos.
Conclusão
O GitLab tenta acompanhar as tendências, implementando gradualmente recursos agradáveis e procurados pela comunidade DevOps. Eles são bastante fáceis de usar e, quando os recursos básicos não são suficientes, eles sempre podem ser expandidos com scripts. E se percebermos que o suporte não é tão elegante e conveniente ... resta aguardar novos lançamentos do GitLab - ou ajudar o projeto com sua contribuição .PS
Leia também no nosso blog: