Integração contínua no Unity: como reduzir o tempo de montagem e economizar recursos + linha de pagamento como presente



Olá pessoal, estou em contato com Alexander Panov, especialista técnico da Pixonic. Na empresa, sou responsável por soluções entre projetos e periféricos para projetos próximos e hoje quero compartilhar minha experiência e melhores práticas.

Plataformas de desenvolvimento e integração contínuos, ou CI / CD, agora são usadas em todos os lugares nos setores em que processos técnicos iterativos e que funcionam bem desempenham um papel decisivo. Neste artigo, falaremos sobre o CI / CD para implementar nossos projetos Unity para o desenvolvimento de jogos para dispositivos móveis: quais problemas encontramos, como conseguimos resolvê-los, quais melhorias alcançamos e como nossas montagens de pipeline são registradas.

Concordo imediatamente que usamos o TeamCity do JetBrains como servidor de CI, o GitHub como repositório de repositórios do Git e o Nexus para armazenar artefatos de montagem.

Então, enfrentamos os seguintes problemas:

  • Falta de um padrão comum para a criação de assemblies: quase todos os desenvolvedores tiveram acesso ao servidor TeamCity, como resultado dos scripts de assembly que foram escritos em diferentes linguagens de programação (BASH, PowerShell, Python), e a lógica era frequentemente duplicada;
  • Frota fraca: devido ao fato de que precisamos criar versões para iOS, tivemos que usar uma frota de carros do Mac mini. E como na Unity quase toda a montagem ocorre em uma única rosca, as montagens paralelas em uma máquina se mostraram problemáticas;
  • Um pouco de eficiência operacional depurada: devido à baixa produtividade de nosso suporte técnico, as montagens demoraram muito tempo;
  • Grandes filas aguardando montagem com um número suficiente de agentes do TeamCity;
  • Um pool de agentes separado para cada projeto: devido aos diferentes ambientes instalados nos dispositivos, bem como aos arquivos de configuração em conflito entre os projetos (arquivos de configuração do servidor de cache etc.), era impossível organizar um pool comum.

O que você fez como resultado?


  • Repositório para scripts de montagem

Primeiro, criamos um repositório único de scripts para assemblies no Python. O lançamento é realizado no ambiente de gerenciamento do ambiente virtual Pipenv com proxy de bibliotecas de terceiros em seu servidor para atualização rápida e controle de versão das bibliotecas necessárias. Assim, fornecemos um único ponto de entrada para montagens de todos os projetos existentes. Reescrevemos todos os scripts em Python, unificamos as configurações, levamos a um padrão comum e removemos duplicatas do código.

  • Nova frota de carros

Foi necessário reduzir o tempo de montagem, possivelmente reduzindo o número de dispositivos utilizados.

Inicialmente, tínhamos um farm de 13 mini computadores Mac, mas essa solução está longe de ser ótima: devido à peculiaridade das montagens no Unity, cerca de 80% do tempo de montagem será realizado em apenas um thread. Adicione a isso uma quantidade sólida de acesso de gravação ao disco rígido e concluímos que um Mac mini mal consegue lidar com 1-2 montagens simultâneas.

O resultado é a necessidade de revisar o hardware.

Ao pesquisar e comparar alternativas para assemblies Unity, observamos que os computadores baseados em AMD Ryzen, devido ao seu desempenho, permitem montar até 8 a 12 assemblies ao mesmo tempo, sem perda significativa de desempenho, em relação à qual foi decidido comprar quatro desses dispositivos com seis SSDs e instalar dois agentes por disco rígido.

Uma comparação de como foi e do que se tornou é apresentada na tabela.



Tempo médio de construção:



Além disso, organizamos a priorização da seleção de agentes do TeamCity para reduzir o tempo que a montagem passou na fila. Anteriormente, cada um dos nossos projetos tinha seu próprio pool de agentes e, devido à natureza multiplataforma dos jogos, o ambiente dependente do projeto não permitia a criação de um pool comum. Agora, após a reorganização do sistema, deixamos vários agentes atribuídos aos projetos, que são usados ​​para montagens automáticas, mas conseguimos adicionar vários agentes comuns para todos os projetos: eles são incluídos no trabalho quando todos os agentes anexados ao projeto desejado estão ocupados.

  • Biblioteca BuildPipeline para Unity

Eles iniciaram uma pequena biblioteca para o Unity, que possibilita definir builds em uma janela separada do editor do Unity e também tem a capacidade de executar build builds no modo batchmode. A partir da funcionalidade principal da biblioteca: permite adicionar e remover definições antes da montagem, desabilitar bibliotecas de terceiros ou arquivos específicos, adicionar etapas personalizadas de pré e pós-processamento, todas as suas configurações são armazenadas nos arquivos de configuração, além da possibilidade de herança.


A janela define na biblioteca BuildPipeline

Nosso pipeline atual CI / CD


Montagem PullRequest. Para cada confirmação:

  1. lançamento do Unity para verificar erros de compilação, definir atualizações e gerar soluções;
  2. executando testes;
  3. lançamento de um analisador estático: com sua ajuda, é realizada uma análise incremental nos arquivos afetados pelo PullRequest atual;
  4. Uma mensagem sobre o resultado da verificação, que é salva no GitHub.

Etapas de construção do projeto do Unity:

1. Instalando o Pipenv e executando scripts para construção no Python: atualizando e instalando bibliotecas Python de terceiros em nosso servidor (proxy do repositório pypi.org ) e, em seguida, executando o script de construção.

2. Preparação preliminar para a montagem da Unidade:

  • exclusão da pasta Biblioteca, Bundles, ativos seletivos (por máscara e / ou arquivos específicos), exclusão de soluções (arquivos .sln) - se necessário;
  • Gerando um arquivo de informações de montagem: nome da filial, número da montagem etc. - para uso posterior na compilação para depuração e teste;
  • configurando um servidor de cache do Unity para um projeto. Cada projeto tem o seu próprio. Cada desenvolvedor também possui um servidor de cache configurado para preenchimento mais rápido: quando um desenvolvedor adiciona um novo ativo, ele aparece automaticamente no servidor de cache e no servidor de construção - assim, a importação de ativos é muito mais rápida.

3. Executar o Unity para verificar erros de compilação, atualizar define e gerar soluções.

4. Execute testes e saia deles se houver erros - se necessário.

5. Lançamento do Unity BuildPipeline com a configuração necessária e parâmetros adicionais do projeto.

6. Para versões do Android / iOS - inicie o Gradle / Xcode:

  • Gradle - GradleWrapper;
  • Xcode - arquive o XcodeProject obtido após o Unity e copie-o para o Mac mini. Instale e atualize separadamente todos os certificados e arquivos de perfil de provisionamento necessários. Execute os comandos Limpar, Arquivar, Exportar.
  • No estágio de exportação, é possível separar a assinatura da compilação, o desenvolvedor e a AppStore. Dependendo do que coletamos, selecione a lista desejada, ou cada uma delas. Na saída, temos dois arquivos: Developer e Release - para instalação nos dispositivos de teste e para upload na AppStore, respectivamente.

7. Despejando construções coletadas e arquivos relacionados (logs, resultados de testes, .obb, manifesto para instalar aplicativos iOS, arquivos dsym etc.) no armazenamento de artefato, para montagens independentes - fazendo upload da construção coletada no armazenamento de archive.

8. Gerando uma página com um código QR para instalar a compilação, adicionando links do repositório e informações da compilação ao banco de dados para trabalhar mais com o aplicativo PixLauncher - falaremos sobre isso mais tarde.

9. Mensagem para Slack sobre o resultado da montagem: para quem iniciou a montagem, bem como para os canais necessários.


Essas mensagens chegam ao Slack

Passos adicionais


Como etapa final do plano, as compilações coletadas são distribuídas aos dispositivos para mais testes e upload na loja.

Para instalar versões em dispositivos, escrevemos um pequeno aplicativo para Android e iOS - PixLauncher. Nós o instalamos em todos os dispositivos em que existe a possibilidade de escolher uma versão do TeamCity. Por conveniência, você pode definir filtros nele - por exemplo, adicione uma configuração aos seus favoritos e execute ações com ela em um clique. No caso de compilações para Android, se necessário, o arquivo na resolução .obb é baixado automaticamente.

Além disso, organizamos a capacidade de instalar a compilação por meio de notificações push: adicionamos um plug-in auto-escrito ao servidor TeamCity, que permite selecionar os endereços MAC dos dispositivos conectados à rede local na página de compilação. Em seguida, uma notificação por push é enviada para esses dispositivos com um link para a instalação - dessa forma, agora é realizada em um clique.

Portanto, o aplicativo permitiu acelerar a pesquisa da compilação de controle de qualidade desejada pelo departamento e a instalação em dispositivos para posterior verificação.


Aparência do aplicativo PixLauncher para iOS

Por fim, o upload de compilações para as lojas


Depois de todas as ações executadas, a necessidade de um preenchimento garantido da compilação e meta-informações sobre o aplicativo para as partes se forma naturalmente.

Inicialmente, surgiram problemas principalmente com a AppStore:

  • preencher o portão é feito apenas a partir de um dispositivo MacOS;
  • Você deve enviar vídeos, capturas de tela e descrições de aplicativos em mais de 25 idiomas.

Isso levou a grandes perdas de tempo para preenchimento e falhas no download de arquivos para o painel de administração. Portanto, pensamos em automação de processos.

Como resultado, temos o seguinte:

  1. No Google Disk, adquirimos um tablet com uma descrição do aplicativo em todos os idiomas;
  2. Os vídeos e capturas de tela do aplicativo são organizados em pastas com uma determinada nomeação;
  3. No Teamcity, para selecionar uma compilação já montada, eles fizeram uma configuração dependente da compilação da versão;
  4. Por meio da API do GooglePlay e do iTMSTransporter for Apple, preencha as compilações e meta-informações sobre o aplicativo na loja para todos os idiomas necessários. Em caso de problemas (por exemplo, com uma rede) - fazemos várias tentativas e enviamos uma mensagem ao Slack com o texto do erro.


É assim que o upload da compilação para a AppStore se parece

Como resultado - alguns números


  • Agora, temos cerca de 400 montagens e até 60 instalações de builds em dispositivos por dia;
  • Existem 57 configurações diferentes de compilação no TeamCity;
  • Utilizamos 22 agentes TeamCity, enquanto é possível expandir sem uma perda significativa no desempenho para 48 agentes;
  • Existe a possibilidade de expansão horizontal da frota.

Source: https://habr.com/ru/post/pt484172/


All Articles