
Hola a todos, estoy en contacto con Alexander Panov, un experto técnico de Pixonic. En la empresa, soy responsable de las soluciones entre proyectos y los periféricos cercanos al proyecto, y hoy quiero compartir mi experiencia y las mejores prácticas.
Las plataformas de desarrollo e integración continuos, o CI / CD, ahora se utilizan en todas partes en aquellas industrias donde los procesos técnicos iterativos y que funcionan bien desempeñan un papel decisivo. En este artículo, hablaremos sobre CI / CD para implementar nuestros proyectos de Unity para el desarrollo de juegos móviles: qué problemas encontramos, cómo logramos resolverlos, qué mejoras logramos y cómo se registran nuestras construcciones de ensamblaje de tuberías.
Acepte de inmediato que usamos TeamCity de
JetBrains como servidor CI, GitHub como repositorio de repositorios Git y Nexus para almacenar artefactos de ensamblaje.
Entonces, enfrentamos los siguientes problemas:
- Falta de un estándar común para crear ensamblados: casi todos los desarrolladores tenían acceso al servidor TeamCity, como resultado de lo cual los scripts de ensamblaje se escribieron en diferentes lenguajes de programación (BASH, PowerShell, Python), y la lógica a menudo se duplicaba;
- Flota débil: debido al hecho de que necesitamos construir compilaciones para iOS, tuvimos que usar una flota de autos de Mac mini. Y dado que en Unity casi todo el ensamblaje tiene lugar en un hilo, los ensamblajes en paralelo en una máquina resultaron ser problemáticos;
- Un poco de eficiencia operativa depurada: debido a la baja productividad de nuestro soporte técnico, los ensamblajes tardaron mucho tiempo;
- Grandes colas en espera de montaje con un número suficiente de agentes de TeamCity;
- Un grupo de agentes separado para cada proyecto: debido a los diferentes entornos instalados en los dispositivos, así como a los archivos de configuración en conflicto entre proyectos (archivos de configuración del servidor de caché, etc.), fue imposible organizar un grupo común.
¿Qué hiciste como resultado?
- Repositorio para scripts de ensamblaje
En primer lugar, creamos un único repositorio de scripts para ensamblados en Python. El lanzamiento se realiza en el entorno de administración del entorno virtual de Pipenv con bibliotecas de terceros en su servidor para una actualización rápida y control de versiones de las bibliotecas requeridas. Por lo tanto, proporcionamos un único punto de entrada para los ensamblajes de todos los proyectos existentes. Reescribimos todos los scripts en Python, unificamos las configuraciones, llevamos a un estándar común, eliminamos duplicados del código.
Era necesario reducir el tiempo de montaje, posiblemente reduciendo el número de dispositivos utilizados.
Inicialmente, teníamos una granja de 13 computadoras Mac mini, pero esta solución está lejos de ser óptima: debido a la peculiaridad de los ensamblajes en Unity, aproximadamente el 80% del tiempo de ensamblaje se realizará en un solo hilo. Agregue a esto una cantidad sólida de acceso de escritura al disco duro y obtenemos que una Mac mini apenas puede hacer frente a 1-2 ensamblajes simultáneos.
El resultado es la necesidad de revisar el hardware.
Durante la búsqueda y comparación de alternativas para los ensamblajes de Unity, notamos que las computadoras basadas en AMD Ryzen, debido a su rendimiento, permiten ensamblar hasta 8-12 ensamblajes simultáneamente sin una pérdida significativa de rendimiento, y por lo tanto, se decidió comprar cuatro dispositivos con seis SSD e instalar Dos agentes por disco duro.
Una comparación de cómo fue y qué se convirtió se da en la tabla.

Tiempo de construcción promedio:

Además, organizamos la priorización de la selección de agentes de TeamCity para reducir el tiempo que la asamblea pasó en la cola. Anteriormente, cada uno de nuestros proyectos tenía su propio grupo de agentes, y debido a la naturaleza multiplataforma de los juegos, el entorno dependiente del proyecto no permitía crear un grupo común. Ahora, después de la reorganización del sistema, dejamos una serie de agentes asignados a los proyectos, que se utilizan para ensamblajes automáticos, pero pudimos agregar varios agentes comunes para todos los proyectos: se incluyen en el trabajo cuando todos los agentes asociados con el proyecto deseado están ocupados.
- BuildPipeline Library para Unity
Comenzaron una pequeña biblioteca para Unity, que hace posible establecer compilaciones de compilación en una ventana del editor de Unity separada, y también tiene la capacidad de ejecutar compilaciones de compilación en modo de modo por lotes. Desde la funcionalidad de la biblioteca principal: le permite agregar y eliminar definiciones antes del ensamblaje, deshabilitar bibliotecas de terceros o archivos específicos, agregar pasos personalizados de procesamiento previo y posterior, todos sus ajustes se almacenan en archivos de configuración, también existe la posibilidad de su herencia.
La ventana define en la biblioteca BuildPipelineNuestra tubería actual CI / CD
Montaje PullRequest. Para cada confirmación:
- lanzar Unity para verificar errores de compilación, definir actualizaciones y generar soluciones;
- ejecutar pruebas;
- lanzamiento de un analizador estático: con su ayuda, se realiza un análisis incremental en los archivos afectados por el PullRequest actual;
- Un mensaje sobre el resultado de la verificación, que se guarda en GitHub.
Pasos de compilación del proyecto Unity:1. Instalar Pipenv y ejecutar scripts para compilar en Python: actualizar e instalar bibliotecas de Python de terceros desde nuestro servidor (proxy del repositorio
pypi.org ) y luego ejecutar el script de compilación.
2. Preparación preliminar para el montaje de la Unidad:
- eliminar la carpeta de la biblioteca, paquetes, activos selectivos (por máscara y / o archivos específicos), eliminar soluciones (archivos .sln), si es necesario;
- Generando un archivo de información de ensamblaje: nombre de sucursal, número de ensamblaje, etc. - para su uso posterior en la compilación para depuración y prueba;
- configurar un servidor de caché Unity para un proyecto. Cada proyecto tiene el suyo. Cada desarrollador también tiene un servidor de caché configurado para un llenado más rápido: cuando un desarrollador agrega un nuevo activo, aparecerá automáticamente en el servidor de caché y en el servidor de compilación, por lo que la importación de activos es mucho más rápida.
3. Ejecutando Unity para verificar si hay errores de compilación, la actualización define y genera soluciones.
4. Ejecute pruebas y salga de ellas si hay errores, si es necesario.
5. Lanzamiento de Unity BuildPipeline con la configuración necesaria y parámetros de proyecto adicionales.
6. Para compilaciones de Android / iOS: inicie Gradle / Xcode:
- Gradle - GradleWrapper;
- Xcode: archiva el XcodeProject obtenido después de Unity y cópialo en Mac mini. Instale y actualice por separado todos los certificados necesarios y los archivos de perfil de aprovisionamiento. Ejecute los comandos Limpiar, Archivar, Exportar.
- En la etapa de exportación, es posible separar la firma de la compilación, el desarrollador y la AppStore. Dependiendo de lo que recolectemos, seleccione el plist deseado o cada uno a su vez. En la salida, obtenemos dos archivos: Developer y Release: para la instalación en dispositivos de prueba y para cargarlos en la AppStore, respectivamente.
7. Verter compilaciones recopiladas y archivos relacionados (registros, resultados de pruebas, .obb, manifiesto para instalar aplicaciones iOS, archivos dsym, etc.) en el almacenamiento de artefactos, para ensamblados independientes: cargar la compilación recopilada en el almacenamiento de archivos.
8. Generando una página con un código QR para instalar la compilación, agregando enlaces desde el repositorio e información de construcción a la base de datos para seguir trabajando con la aplicación PixLauncher. Hablaremos de ello más adelante.
9. Mensaje a Slack sobre el resultado del ensamblaje: al que lo lanzó, así como a los canales necesarios.
Tales mensajes llegan a SlackPasos adicionales
Como paso final del plan, las compilaciones recopiladas se distribuyen a los dispositivos para realizar más pruebas y cargarlas en la tienda.
Para instalar compilaciones en dispositivos, escribimos una pequeña aplicación para Android e iOS: PixLauncher. Lo instalamos en cada dispositivo donde existe la posibilidad de elegir una compilación de TeamCity. Para mayor comodidad, puede establecer filtros en él; por ejemplo, agregar una configuración a sus favoritos y luego realizar acciones con un solo clic. En el caso de las compilaciones para Android, si es necesario, el archivo en resolución .obb se descarga automáticamente.
Además, organizamos la capacidad de instalar la compilación mediante notificaciones push: agregamos un complemento autoescrito al servidor TeamCity, que le permite seleccionar las direcciones MAC de los dispositivos conectados a la red local en la página de compilación. Luego, se envía una notificación push a estos dispositivos con un enlace a la instalación, de esta forma ahora se realiza con un solo clic.
Por lo tanto, la aplicación permitió acelerar la búsqueda de la compilación de control de calidad deseada por el departamento y la instalación en dispositivos para su posterior verificación.
Apariencia de la aplicación PixLauncher para iOSFinalmente, subir compilaciones a las tiendas
Después de todas las acciones realizadas, la necesidad de un llenado garantizado de la compilación y la metainformación sobre la solicitud a las partes se forma naturalmente.
Inicialmente, los problemas surgieron principalmente con la AppStore:
- completar la puerta se realiza solo desde un dispositivo MacOS;
- Debe cargar videos, capturas de pantalla y descripciones de aplicaciones en más de 25 idiomas.
Esto condujo a grandes pérdidas de tiempo para el llenado y bloqueos en la descarga de archivos al panel de administración. Por lo tanto, pensamos en la automatización de procesos.
Como resultado, tenemos lo siguiente:
- En Google Disk, tenemos una tableta con una descripción de la aplicación en todos los idiomas;
- Los videos y las capturas de pantalla de la aplicación están organizados en carpetas con un cierto nombre;
- En Teamcity, para seleccionar una compilación ya ensamblada, hicieron que una configuración dependiera de la compilación de lanzamiento;
- A través de la API de GooglePlay y iTMSTransporter para Apple, complete las compilaciones y la metainformación sobre la aplicación en la tienda para todos los idiomas necesarios. En caso de problemas (por ejemplo, con una red), hacemos varios intentos y enviamos un mensaje a Slack con el texto de error.
Así es como se carga la compilación en la AppStoreComo resultado, algunos números
- Ahora tenemos alrededor de 400 ensamblajes y hasta 60 instalaciones de compilaciones en dispositivos por día;
- Hay 57 configuraciones de compilación diferentes en TeamCity;
- Utilizamos 22 agentes de TeamCity, mientras que es posible expandirse sin una pérdida significativa en el rendimiento a 48 agentes;
- Existe la posibilidad de expansión horizontal de la flota.