Jenkins + Unity: Automatiza el proceso de creación de tu aplicación Unity

En Geko, uno de nuestros clientes nos pidió que automatizaramos la compilación de su proyecto Unity, ya que hacerlo manualmente consume mucho tiempo que los desarrolladores podían dedicar a mejorar la aplicación, en lugar de generar los ejecutables. Primero, analizamos sus necesidades actuales y futuras ya que esto nos permitiría brindarles la mejor solución a corto/largo plazo.

 

Requisitos

  • Proceso automatizado
  • 5 plataformas principales ahora (iOS, Android, Windows, Linux, WebGL)
  • Posibilidad de compilar para otras plataformas en un futuro próximo (Nintendo, PlayStation, XBox, Stadia, etc.)
  • Flexibilidad para integrarse con otros servicios
  • Menor costo posible

 

Después de evaluar la infraestructura actual de la empresa y las ventajas y desventajas de utilizar servicios como Unity Builder, decidimos desarrollar los procesos de automatización en Jenkins. Al adoptar este enfoque, logramos todos los requisitos de la tarea, ya que Jenkins nos permitirá:

  • Automatizar los pasos necesarios para generar los ejecutables.
  • Generar ejecutables para todos las plataformas deseadas (5 plataformas principales y otras plataformas), actualmente en Unity Builder no es posible trabajar con las plataformas adicionales.
  • Lograr una mayor rentabilidad mediante el uso de nodos dinámicos que serán destruidos después de que finalice el proceso de ejecución. Unity Builds usa una estrategia similar, pero el costo total es un poco mayor.

 

Ahora que tenemos nuestro plan definido, pongámonos manos a la obra y preparemos nuestro archivo de Jenkins. En esta publicación hacemos las siguientes suposiciones:

  • Tienes una instancia de Jenkins y conocimientos básicos de algunos conceptos de Jenkins.
  • El sistema operativo del nodo donde se ejecutaran los trabajo es Windows.
  • Su máquina de trabajo tiene Android Studio instalado.
  • Su máquina trabajadora tiene Unity Hub instalado.
  • Tiene una licencia de Unity, pro o plus.

 

Plataforma Android

Configuración de Android Studio

Unity se apoya en las herramientas de Android Studio para generar las aplicaciones, por esa razón es importante tener instalado Android Studio (también puede instalarse solo el SDK) y agregar las versiones de la api que desea que admita su aplicación.
  • Abrir la configuración de Android Studio
android studio

 

  • Agregue las versiones de API (Niveles) que necesita que su aplicación soporte
android studio

 

Configuración de Unity Hub

Unity Hub es una herramienta de Unity que permite configurar un entorno de desarrollo de forma muy sencilla, estos son los pasos que debe seguir después de descargarlo e instalarlo:
  • Vaya a la sección de instalación en el panel izquierdo
unity hub
  • Haga clic en ADD y seleccione la versión recomendada
unity hub
  • Una vez instalada la versión de Unity, haga clic en los 3 puntos sobre la versión y seleccione Add Modules
unity hub
  • Instale Android Build Support y haga clic en Done

unity hub

 

Crear el Jenkinsfile

  • Primero necesitamos crear el archivo Jenkins que contendrá los pasos necesarios para generar nuestra compilación.
pipeline {
    // Definición de variables de entorno que se pueden usar a lo largo del trabajo
    environment {
    }
    // Opciones: agregar marca de tiempo a los logs de trabajos y limitar la cantidad de compilaciones que se deben mantener.
    options {
    }
    // Variables que modifican el comportamiento del trabajo
    parameters {
    }
    // Selector del agente que ejecutará el trabajo
    agent {
    }
    // Los pasos necesarios para generar la aplicación deseada
    stages {
    }
    // Cualquier acción que queramos realizar después de que todos los pasos hayan tenido éxito o hayan fallado
    post {
    }
}
  • A continuación, definamos nuestras variables ambientales, opciones de configuración, parámetros de compilación, agente de compilación y acciones post trabajo.
pipeline {
    // Definición de variables de entorno que se pueden usar a lo largo del trabajo
    environment {
        // Github data
        String gitUrl = "[email protected]:GekoCloud/unity_build_demo.git"
        String gitCredentials = "jenkins-private-key" // configura una credencial (PrivateKey) si tu repo es privado.
        
        // Unity
        UNITY_EXECUTABLE = "C:\\Path\\A\\TU\\Version\\Unity\\2020.3.16f1\\Editor\\Unity.exe"
        
        // Unity data
        UNITY_ID_EMAIL = credentials('jenkins-id-for-unity-email')
        UNITY_ID_PASSWORD = credentials('jenkins-id-for-unity-password')
        UNITY_ID_LICENSE = credentials('jenkins-id-for-unity-license')

        // Unity parametros
        BUILD_NAME = "Android-${currentBuild.number}"
        String buildTarget = "Android"
        String outputFolder = "CurrentBuild"

        // PARAMETERS DATA
        IS_DEVELOPMENT_BUILD = "${params.developmentBuild}"

        // Agregar mas variables de entorno
    }
    // Opciones: agregar marca de tiempo a los logs de trabajos y limitar la cantidad de compilaciones que se deben mantener.
    options {
        timestamps()
        buildDiscarder(logRotator(numToKeepStr: "10"))
    }
    // Variables que modifican el comportamiento del trabajo
    parameters {
        string(name: 'gitBranch', defaultValue: 'development', description: 'Set the branch.')
        booleanParam(name: 'developmentBuild', defaultValue: true, description: 'Choose the buildType.')
    }
    // Selector del agente que ejecutará el trabajo
    agent {
        node {
            // El nodo de Jenkins que se utilizará debe tener la etiqueta android
            label "android"
        }
    }
    // Los pasos necesarios para generar la aplicación deseada
    stages {
    }
    // Cualquier acción que queramos realizar después de que todos los pasos hayan tenido éxito o hayan fallado
    post {
        success {
            echo "Funcionó :)"
        }
        failure {
            echo "NO Funcionó :("
        }
    }
}
  • Ahora que tenemos una estructura general básica, definamos las diferentes etapas/pasos que nos permitirán crear la aplicación deseada.
    • Descargar el código de nuestra aplicación de nuestro repositorio de código.
   stage('Git Pull') {
        steps {
            echo "Git pull repo"
            script {
                try {
                    git url: "${gitUrl}", branch: "${gitBranch}", credentialsId: "${gitCredentials}"
                } catch (e) {
                    currentBuild.result = "FAILED"
                    echo "JOB FAILED: The selected branch does not exists."
                }
            }
        }
    }
Esto descargará el código de la aplicación definido en nuestras variables de entorno a la máquina del agente.

 

    • Activar nuestra licencia de Unity en la máquina.
   stage('Activate License') {
        steps {
            script {
                echo "Activate License..."
                bat '%UNITY_EXECUTABLE% -nographics -projectPath %CD% -quit -batchmode -username %UNITY_ID_EMAIL% -password %UNITY_ID_PASSWORD% -serial %UNITY_ID_LICENSE%'
            }
        }
    }
Para realizar compilaciones con línea de comandos, Unity requiere que se active una licencia pro o plus válida en la máquina antes de ejecutar los comandos de compilación.

 

    • Ejecutar el comando de compilación.
   stage('Build Application') {
        steps {
            script {
                echo "create Application output folder..."
                bat 'mkdir %outputFolder%'

                echo "Buld App..."
                bat '%UNITY_EXECUTABLE% -projectPath %CD% -quit -batchmode -nographics -buildTarget %buildTarget% -customBuildPath %CD%\\%outputFolder%\\ -customBuildName %BUILD_NAME% -executeMethod BuildCommand.PerformBuilds'
            }
        }
    }

El argumento -executeMethod BuildCommand.PerformBuilds, nos permite ejecutar funciones definidas en un script de C# (El archivo BuildCommand.cs debe estar ubicado en la carpeta Assets/Scripts/Editor de tu proyecto y puedes ver un ejemplo BuildCommand, que realizará las diferentes configuraciones que generalmente se realizan manualmente en la IDE de Unity. Para obtener más información sobre las opciones que se pueden configurar, visite la documentación de la api de unity.

    • Desactivar nuestra licencia de Unity en la máquina donde se ejecuta el trabajo de Jenkins.
   post {
        always {
            script {
                echo "Return License..."
                bat '%UNITY_EXECUTABLE% -nographics -quit -batchmode -returnlicense -username %UNITY_ID_EMAIL% -password %UNITY_ID_PASSWORD%'
            }
        }
    }

Esto solo es necesario si ejecuta sus cargas de trabajo en máquinas efímeras, ya que la licencia de unity no se libera automáticamente cuando se termina la máquina que ejecuta el trabajo. Además, esto no se ejecuta como una etapa porque necesitamos liberar la licencia si el trabajo falla o tiene éxito.

Una vez que haya terminado su Jenkinsfile (puede ver el archivo completo aqui: Jenkinsfile) y su script BuildCommand se haya agregado a su proyecto, puede crear un trabajo de pipeline en su instancia de Jenkins y apúntarlo a su Jenkinsfile. Nota: Dado que está publicación fue pensada como guía y no como una demo, es posible que deban realizarse algunos cambios para su proyecto específico.

Para resumir, Unity permite a los desarrolladores definir configuraciones de compilación al proporcionar una API de configuración muy extensa, mientras que Jenkins permite a los equipos de devops ejecutar estas compilaciones automatizadas en procesos de CI/CD, que adicionalmente pueden incluir todo tipo de pasos adicionales: subir a buckets S3, monitorear logs de compilación generados, etc. Si tiene problemas para configurar la infraestructura para ejecutar sus pipelines de compilación, contáctenos y podríamos ayudarte con eso 😁.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *