Esta página aborda a hermeticidade, os benefícios do uso de builds herméticos e estratégias para identificar comportamentos não herméticos nos seus builds.
Visão geral
Quando recebe o mesmo código-fonte de entrada e a mesma configuração de produto, um sistema de build hermético sempre retorna a mesma saída isolando o build de mudanças no sistema host.
Para isolar o build, os builds herméticos são insensatos às bibliotecas e e outros softwares instalados na máquina host local ou remota. Elas dependem versões específicas de ferramentas de build, como compiladores, e dependências, como bibliotecas. Isso torna o processo de build independente, já que não depende de serviços externos ao ambiente de build.
Os dois aspectos importantes da hermeticidade são:
- Isolamento: os sistemas de build herméticos tratam as ferramentas como código-fonte. Eles fazem o download de cópias de ferramentas e gerenciam o armazenamento e o uso em árvores de arquivos gerenciadas. Isso cria um isolamento entre a máquina host e o usuário local, incluindo versões instaladas de idiomas.
- Identidade da origem: os sistemas de build herméticos tentam garantir a semelhança da de entrada. Os repositórios de código, como o Git, identificam conjuntos de mutações de código com um código hash exclusivo. Os sistemas de compilação herméticos usam esse hash para identificar alterações em a entrada do build.
Vantagens
Os principais benefícios das construções herméticas são:
- Velocidade: a saída de uma ação pode ser armazenada em cache, e a ação não precisa ser executada novamente, a menos que as entradas mudem.
- Execução paralela: para entradas e saídas específicas, o sistema de build pode criar um gráfico de todas as ações para calcular a execução eficiente e paralela. O sistema de build carrega as regras e calcula um gráfico de ações e gera hash para pesquisar no cache.
- Vários builds: você pode construir vários builds herméticos no mesmo máquina, cada uma criada com diferentes ferramentas e versões.
- Reprodutibilidade: os builds herméticos são bons para a solução de problemas porque você conhece as condições exatas que produziram o build.
Como identificar a não hermética
Se você estiver se preparando para mudar para o Bazel, a migração será mais fácil se você melhorar a hermeticidade dos builds atuais com antecedência. Algumas fontes comuns de não hermética nos builds são:
- Processamento arbitrário em arquivos
.mk
- Ações ou ferramentas que criam arquivos de forma não determinista, geralmente envolvendo IDs de build ou carimbos de data/hora
- Binários do sistema que diferem entre hosts (como binários
/usr/bin
, valores absolutos caminhos, compiladores C++ do sistema para configuração automática de regras C++ nativas). - Gravação na árvore de origem durante o build. Isso impede que a mesma árvore de origem seja usada para outro destino. O primeiro build grava na árvore de origem, corrigindo a árvore de origem para o destino A. Então, tentar construir o alvo B pode falhar.
Solução de problemas de builds não herméticos
Começando com a execução local, os problemas que afetam as ocorrências em cache local revelam ações não herméticas.
- Garanta builds sequenciais nulos: se você executar
make
e receber um build bem-sucedido, executar o build novamente não deve recriar nenhum destino. Se você executar cada etapa de build duas vezes ou em sistemas diferentes, compare um hash do conteúdo do arquivo e receba resultados diferentes. O build não é reproduzível. - Execute etapas para depurar acertos de cache local em várias máquinas de cliente em potencial para garantir que você detecte todos os casos de vazamento do ambiente do cliente nas ações.
- Execute uma versão dentro de um contêiner do Docker que não contenha nada além do árvore de origem verificada e uma lista explícita de ferramentas de host. Falhas na construção e as mensagens de erro vão identificar dependências implícitas do sistema.
- Descubra e corrija problemas de hermeticidade usando regras de execução remota.
- Ative o sandbox restrito no nível por ação, já que as ações em um build podem ter estado e afetar o build ou a saída.
- Regras do espaço de trabalho
que os desenvolvedores adicionem dependências a espaços de trabalho externos,
rica o suficiente para permitir que
o processamento arbitrário ocorra no processo. É possível
receber um registro de algumas ações potencialmente não herméticas nas regras do espaço de trabalho do Bazel
adicionando a flag
--experimental_workspace_rules_log_file=PATH
ao comando do Bazel.
Hermeticidade com o Bazel
Para mais informações sobre como outros projetos tiveram sucesso usando builds herméticos com o Bazel, consulte estas palestras do BazelCon:
- Como criar sistemas em tempo real com o Bazel (SpaceX)
- Execução remota e cache remoto do Bazel (Uber e TwoSigma)
- Builds mais rápidos com execução remota e armazenamento em cache
- Fusão do Bazel: builds incrementais mais rápidos
- Execução remota vs. execução local
- Melhoria da usabilidade do armazenamento em cache remoto (IBM)
- Como criar carros autônomos com o Bazel (BMW)
- Como construir carros autoguiados com Bazel + perguntas e respostas (GM Cruise)