Artículos etiquetados con:tutorial
Cómo compilar aplicaciones Android con Jenkins

En tiempos de desarrollo de software mediante metodologías ágiles, Scrum e integración continua, donde todos los miembros de un equipo integran su código frecuentemente y pueden realizar varias subidas al día dependiendo de las tareas a desarrollar, resulta imprescindible el uso de herramientas que permitan conocer en todo momento el estado del producto, las diferentes versiones y el estado en que se encuentra.

Cada vez que se realiza una subida de código al repositorio, se realiza una integración que compila el código fuente y verifica que se ha realizado correctamente, obteniendo un ejecutable de la aplicación. Para este proceso, en SDOS nos hemos decantado por el uso de Jenkins, un software gratuito y Open Source escrito en Java y está basado en el proyecto Hudson.

 

¿POR QUÉ JENKINS?

Este sistema soporta herramientas de control de versiones como SVN o GIT y puede ejecutar proyectos basados en Ant y Maven, Gradle, etc. Además, al ser un proyecto Open Source, es el más utilizado por los desarrolladores, contando con una gran comunidad de desarrollo y soporte.

Pero Jenkins no es sólo una herramienta para el equipo de desarrollo, también sirve al equipo de QA: del mismo modo que posibilita la ejecución de test automáticos o incluso el uso de Sonarqube, justo después de cada compilación permite comprobar la calidad de la subida.

 

¿CÓMO USAR JENKINS CON ANDROID?

En el desarrollo Android, Jenkins puede servirnos para generar un .apk cada vez que realicemos una subida de código al repositorio, guardándola en un servidor FTP donde tendremos un listado de todas las versiones generadas.

En este post os contamos cómo completar todo el proceso. ¡Empezamos!

 

1. CREAR UN PROYECTO EN JENKINS

En primer lugar, creamos un nuevo Job en Jenkins.

Paso 1 para compilar un .apk en Jenkins

A continuación, seleccionamos un nuevo proyecto Freestyle para poder configurarlo según nuestras necesidades. Escribimos un nombre y hacemos clic en OK.

Paso 2 para compilar un .apk en Jenkins

 

2. CONFIGURAR LAS SECCIONES DEL JOB

GENERAL

En esta sección definiremos lo siguiente:

  • Proyect name y description. Es recomendable dar un nombre intuitivo al proyecto y una descripción concreta para saber qué Job estamos ejecutando:

Paso 3 para compilar un .apk en Jenkins

  • Cuándo se descargan los builds antiguos. Es importante definir un número máximo de build a guardar ya que no queremos sobrecargar la máquina ni llenar de ejecuciones nuestro Job. Como recomendación, nos quedaremos con las 10 últimas ejecuciones realizadas. Si por necesidad del proyecto necesitamos que sean más, podría aumentarse el número, pero debería ser sólo en casos puntuales.

Paso 4 para compilar un .apk en Jenkins

  • Parámetros para ejecutar el proyecto. En la parte general también definiremos los parámetros necesarios para ejecutar un Job. Para añadirlos tenemos que hacer clic en This project is parameterized y seleccionar un Choice Parameter. Los parámetros para la compilación de una app de Android serán los siguientes:
    • Type. Por defecto en Android siempre aparecen dos tipos, debug y release, pero pueden añadirse tipos personalizados. En nuestro caso añadiremos: Release, Preproduction y Debug.
    • Flavors. Un flavor define una versión customizada de la aplicación. Esto nos permite definir diferentes personalizaciones de la aplicación dependiendo de la variante que necesitemos. Por ejemplo, podríamos tener un flavor para una demo de la aplicación y otro con la aplicación completa de pago.
    • Git Parameter. Definiremos como parámetro la rama que queremos del repositorio concreto. Tendremos que definir un valor por defecto para las ejecuciones automáticas. Si tenemos muchas ramas en un mismo repositorio, podemos hacer un filtro por nombre de rama como, por ejemplo, .*_rc.* (todas las ramas que incluyen _rc, release candidate).

Paso 5 para compilar un .apk en Jenkins

Paso 6 para compilar un .apk en Jenkins

 

Puedes encontrar más información sobre los parámetros en este enlace.

 

SOURCE CODE MANAGEMENT

En esta sección definiremos el tipo de repositorio que queremos usar, en nuestro caso será Git.

Una vez que seleccionamos la opción de Git tenemos que añadir:

  • URL del repositorio. Dónde está guardado el código del proyecto.
  • Credenciales. Usaremos en usuario git previamente añadido en Jenkins.
  • Branch. Especificaremos la rama específica del proyecto que usaremos. Como ya la hemos elegido una con el parámetro Git Parameter, le pasamos el valor de ese parámetro con $Branch.

Paso 7 para compilar un .apk en Jenkins

 

BUILD TRIGGERS

En esta sección definiremos el tipo de activador que necesitamos para ejecutar el build. Si no añadimos ninguno, sólo se ejecutará cuando nosotros lo forcemos. Desde aquí también podemos:

  • Realizar una ejecución remota desde un script.
  • Realizar la ejecución de forma periódica, por ejemplo cada noche a las 00:00.
  • Realizar una ejecución cuando se produzca un push o un new merge request en el repositorio.

Por ahora lo dejaremos por defecto y lo ejecutaremos manualmente.

 

BUILD ENVIROMENT

En esta sección definiremos dos opciones:

  1. Borrar la carpeta del workspace antes de cada ejecución (para realizar una ejecución limpia).
  2. Añadir el timestamp a los logs para tener más información.

Paso 8 para compilar un .apk en Jenkins

 

BUILD

En la sección del Build añadiremos un Execute shell para ejecutar los siguientes comandos:

Paso 9 para compilar un .apk en Jenkins

  • chmod +x gradlew: da permisos de ejecución al fichero gradlew por si no los tiene (por defecto ya los tiene).
  • ./gradlew: ejecuta el fichero gradlew en la máquina donde está Jenkins que es un Linux (¡cuidado con este fichero!).
  • assemble: es la orden para compilar una aplicación Android.
  • $Flavor: flavour elegido para la ejecución. Ponemos $ para que se sustituya el valor del parámetro por el seleccionado del desplegable flavor en la sección general.
  • $Type: type elegido para la ejecución. Ponemos $ para que se sustituya el valor del parámetro por el seleccionado del desplegable type en la sección general.

 

POST-BUILD ACTIONS

Desde esta sección realizaremos principalmente tres acciones:

  • Guardar el artefacto generado. Guardaremos todos los ficheros .apk generados en la compilación del proyecto. Por defecto lo guardaremos en: **/*.apk

Paso 10 para compilar un .apk en Jenkins

  • Enviaremos el fichero .apk dentro de la carpeta /apks/ a un servidor FTP. En nuestro caso, tenemos un servidor llamado NAS1 en el que guardaremos el apk generado en una carpeta ya creada dentro del servidor.Nota: para configurar la conexión con un servidor FTP debemos ir a Manage Jenkins > Configure Jenkins > Publish over FTP, y añadir los datos correspondientes a nuestro servidor.

Paso 11 para compilar un .apk en Jenkins

  • Enviar correo cada vez que termine un Build utilizando la acción post-build Editable Email Notification. La configuración que tendremos será la siguiente:

Paso 12 para compilar un .apk en Jenkins

 

Puedes copiar el contenido del mensaje por defecto de este HTML:

Default Subject

[JENKINS- ${JOB_NAME} ] Result of Build $BUILD_NUMBER ${JOB_NAME} Project.

Default Content

<html>
 
<p> Hello. </p>
 
<p>This mail is auto-generated as part of the Jenkins execution of the project <b>${JOB_NAME}</b> </p>
 
<h2> BUILD DETAILS: </h2>
 
<p>
       <b>Project Name:</b> ${JOB_NAME} <br>
       <b>Build URL:</b> ${BUILD_URL} <br>
       <b> Build Number: </b> ${BUILD_NUMBER} <br>
       <b>Build Status: </b> ${BUILD_STATUS} <br>
       <b>Type: </b> $Type <br>
       <b>Flavor: </b> $Flavor <br>
       <b>Branch: </b> $Branch <br>
       <b>Download APK: </b> ${BUILD_URL}/lastSuccessfulBuild/artifact/apks/ <br>
       <b>Log: </b> The log file is attached into this e-mail. <br>
       <b>Log URL: </b> ${BUILD_URL}${JOB_NAME}/lastBuild/console <br>
       <b>Changes: </b> ${CHANGES, format="List of changes: <li><ul>[%a] %m </ul><ul> [Date:] %d </ul> <ul> [Revision:] %r </ul></li> <br>"} <br>
</p>
 
<p> Thank you & Regards. </p>
 
</html>

 

Esta template es genérica para cualquier proyecto ya que usa las siguientes variables:

  • ${JOB_NAME}. Nombre del Job en el Jenkins.
  • ${BUILD_URL}. URL exacta del Job.
  • ${BUILD_NUMBER}. Número de Build ejecutado.
  • ${BUILD_STATUS}. Estado en el que ha finalizado el Build.
  • $Type. Tipo seleccionado al ejecutar el Build.
  • $Flavor. Flavor seleccionado al ejecutar el Build.
  • $Branch. Branch seleccionada al ejecutar el Build, si no se ha elegido ninguna aparece el nombre de la branch por defecto definida.
  • ${CHANGES}. Muestra los cambios realizados en el commit que ha activado el Build.
    • %a: autor del commit.
    • %m: mensaje del commit.
    • %d: fecha del commit.
    • %r: número de commit.

 

Esto dará lugar a un email como el que se muestra a continuación. Obtenemos así el .apk generado de forma sencilla.

Paso 13 para compilar un .apk en Jenkins

 

Sin lugar a dudas, en los últimos años Jenkins se ha convertido en una herramienta indispensable en el desarrollo de software ágil ya que, además de automatizar el proceso de producción de artefactos, garantiza la calidad en cada uno de ellos tanto para el cliente como para el propio equipo.


Gestiona el versionado de los scripts de base de datos con Liquibase

Una de las asignaturas pendientes dentro del ciclo de vida de los proyectos es la gestión del versionado de los scripts de base de datos. En nuestra trayectoria, nos hemos encontrado con clientes que exigen una gestión compleja de cualquier tipo de cambio, pero siempre de forma manual, bajo documentos de procedimientos que no ayudan a una gestión ágil.

Para intentar dinamizar y controlar de forma sencilla estas modificaciones, hemos incluido en nuestro ecosistema de desarrollo la herramienta Liquibase. Aquí os dejamos un breve tutorial.

 

¿PARA QUÉ SIRVE?

Nos permite mantener el control de todos los cambios ejecutados sobre la base de datos, almacenando toda la información de los mismos (autor, fecha, cambio, etc.), asociando dichos cambios a los desarrollos realizados sobre la aplicación e integrándolos con el propio control de versiones del código fuente.

Por ejemplo: una rama de desarrollo tiene asociados sus correspondientes cambios de base de datos, lo cuales se integrarán con los demás cambios de otras ramas para permitir la unificación y generación de un solo script de base de datos sin que ello implique conflictos en el modelo de datos.

 

¿CÓMO FUNCIONA?

Su funcionamiento es sencillo y, sobre todo, compatible con múltiples arquitecturas de proyectos, siempre dependiendo de cómo se encuentre montado el proyecto. Básicamente actúa de la siguiente forma:

  1. Ejecución. Ya sea de forma manual (lanzando tú mismo la ejecución por comando Maven, Ant o por linea de comandos) o automática (Spring, Servlet, Hibernate, otros).
  2. Lectura de ficheros. Todos los cambios en base de datos los guardas en ficheros que Liquibase llama Changelogs, los cuales veremos más adelante. Estos ficheros son leídos durante la ejecución para determinar que cambios se deben aplicar en tu base de datos.
  3. Comparación con tu base de datos. Una vez Liquibase sepa qué cambios existen en tus changelogs, los cruza con su tabla interna llamada DATABASECHANGELOG, la principal tabla principal de versiones/cambios que se crea durante la primera ejecución. Así determina qué cambios debe aplicar y en qué versión se encuentra tu base de datos.
  4. Aplicación de cambios. Cuando tengas claros los cambios a aplicar, ejecútalos y actualiza la tabla de versiones/cambios. Si se produce algún error SQL durante la ejecución, mostrará el correspondiente mensaje y no actualizará la tabla de versiones/cambios.

 

¿QUÉ ES UN CHANGELOG?

Como ya hemos comentado, un changelog es un fichero que contiene todos los cambios que quieres aplicar en tu base de datos. Estos ficheros pueden ser XML (el más común), YAML, JSON o SQL. Aquí algunos ejemplos:

XML

<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
	<changeSet author="liquibase-docs" id="createTable-example">
    <createTable catalogName="cat"
            remarks="A String"
            schemaName="public"
            tableName="person"
            tablespace="A String">
        <column name="address" type="varchar(255)"/>
    </createTable>
</changeSet>
</databaseChangeLog>

 

YAML

databaseChangeLog:
changeSet:
  id: createTable-example
  author: liquibase-docs
  changes:
  - createTable:
      catalogName: cat
      columns:
      - column:
          name: address
          type: varchar(255)
      remarks: A String
      schemaName: public
      tableName: person
      tablespace: A String

 

JSON

{
    "databaseChangeLog": [
"changeSet": {
    "id": "createTable-example",
    "author": "liquibase-docs",
    "changes": [
      {
        "createTable": {
          "catalogName": "cat",
          "columns": [
            {
              "column": {
                "name": "address",
                "type": "varchar(255)"
            }]
          },
          "remarks": "A String",
          "schemaName": "public",
          "tableName": "person",
          "tablespace": "A String"
      }]
  }
    ]
}

 

SQL

--liquibase formatted sql

--changeset nvoxland:1
create table test1 (
    id int primary key,
    name varchar(255)
);
--rollback drop table test1;

--changeset nvoxland:2
insert into test1 (id, name) values (1, ‘name 1′);
insert into test1 (id, name) values (2, ‘name 2′);

--changeset nvoxland:3 dbms:oracle
create sequence seq_test;

 

¿QUÉ PUEDO INCLUIR DENTRO DE UN CHANGELOG?

Liquibase interpreta que cada cambio en la base de datos se encuentra determinado por los changeset’s. Éstos no son más que las etiquetas (distinguidas en los ejemplos anteriores) que utiliza la herramienta para determinar un cambio asociado a un autor.

Un changelog puede tener uno o varios changesets, todo depende de la forma en la que se quieran organizar los cambios.

Dentro de una etiqueta changeset puedes incluir prácticamente cualquier cambio en base de datos, para ello utiliza las etiquetas que proporciona. También puedes importar ficheros SQL dentro de tus propios changelogs, mediante la etiqueta <include>.

 

¿CÓMO PUEDO CONFIGURAR MI PROYECTO MAVEN?

Lo primero que se debes hacer es incluir el plugin en el fichero pom.xml que permitirá ejecutar Liquibase en el proyecto:

<plugin>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-maven-plugin</artifactId>
      <version>3.0.5</version>
      <configuration>
        <changeLogFile>src/main/resources/org/liquibase/db.changelog-master.xml</changeLogFile>
          <driver>oracle.jdbc.driver.OracleDriver</driver>
          <url>jdbc:oracle:thin:@tf-appserv-linux:1521:xe</url>
          <username>liquibaseTest</username>
          <password>pass</password>
        </configuration>
      <executions>
        <execution>
          <phase>process-resources</phase>
          <goals>
            <goal>update</goal>
          </goals>
        </execution>
      </executions></plugin>

 

Deberás tener en cuenta que desde el proyecto debes incluir la correspondiente librería JDBC que permita la conexión con la base de datos: mysql-connector-java, ojdbc14, etc.

Liquibase permite la conexión a tu base de datos por medio de un datasource definido en el entorno de Spring, pero ello obliga a que la ejecución se realice de forma automática en el arranque de la aplicación. Puedes encontrar más información en este enlace.

Lo siguiente será definir tu estructura de ficheros changelogs. Mientras dispongas de un fichero “máster” definido como fichero de inicio, Liquibase te da libertad completa a la hora de gestionar la organización de los ficheros. Sin embargo, y siguiendo la filosofía de control de versiones, existen buenas prácticas en este tema.

 

ESTRUCTURA DEL DIRECTORIO DE FUENTES JAVA

com
  example
    db
      changelog
        db.changelog-master.xml
        db.changelog-1.0.xml
        db.changelog-1.1.xml
        db.changelog-2.0.xml
      DatabasePool.java
      AbstractDAO.java

 

FICHERO DB.CHANGELOG-MASTER.XML

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

  <include file="com/example/db/changelog/db.changelog-1.0.xml"/> 
  <include file="com/example/db/changelog/db.changelog-1.1.xml"/> 
  <include file="com/example/db/changelog/db.changelog-2.0.xml"/> 
</databaseChangeLog>

 

FICHEROS DB.CHANGELOG-…

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog 
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"> 
  <changeSet author="authorName" id="changelog-1.0">
    <createTable tableName="TablesAndTables">
      <column name="COLUMN1" type="TEXT">
        <constraints nullable="true" primaryKey="false" unique="false"/>
      </column>
    </createTable>
  </changeSet>
</databaseChangeLog>

 

Una vez definidos tus ficheros, ya puedes lanzar la ejecución mediante el correspondiente comando maven:

mvn liquibase:update

 

¿Y SI YA TENGO UNA BASE DE DATOS EXISTENTE?

Liquibase permite la generación automática de todos los changelogs necesarios basándose en una base de datos ya existente. Para ello, debes descargar los ejecutables (línea de comandos) y lanzarlos mediante el siguiente comando:

liquibase --driver=oracle.jdbc.OracleDriver \
      --classpath=\path\to\classes:jdbcdriver.jar \
      --changeLogFile=com/example/db.changelog.xml \
      --url="jdbc:oracle:thin:@localhost:1521:XE" \
      --username=scott \
      --password=tiger \
      generateChangeLog

 

Una vez haya finalizado el proceso, deberás haber generado en la ruta indicada todos los ficheros changelogs asociados al modelo completo de tu base de datos: tablas, indices, claves ajenas, etc.

Actualmente el comando generateChangeLog tiene la limitación de no exportar los siguientes tipos de objetos concretos: stored procedures, functions, packages, triggers.

 

¿DISPONGO DE OTRAS OPCIONES DE CONFIGURACIÓN?

Como dijimos anteriormente, además de Maven, puedes configurar la ejecución de Liquibase tanto manual como automáticamente dependiendo de la estructura/tecnologías del proyecto. Si necesitas más información, consulta este enlace.

 

 ¿ALGUNA OTRA CARACTERÍSTICA DESTACABLE?

Podemos destacar la posibilidad de configuración mediante entornos (producción, test, etc.), el hecho de que es independiente de la base de datos (una vez definidos los ficheros se pueden ejecutar sobre todos los motores de base de datos soportados) y su repositorio de plugins que permiten completar su funcionalidad.

 

¿ALTERNATIVAS A LIQUIBASE?

En nuestro caso, nos hemos decantado por Liquibase principalmente por dos motivos: porque abarca prácticamente todo el ciclo de vida de la gestión de la configuración, y por la versatilidad que ofrece para cualquier arquitectura. No obstante, si estos argumentos no te convencen, te recomendamos que sondees estas alternativas:

  • Rails Migrations (Ruby on Rails)
  • DBVersion
  • dbvcs
  • BSourceTools
  • Teamwork (Oracle y SQL Server)
  • Optim Database Administrator (DB2)

 


Uso de cookies

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continúas navegando estas dando tu consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pincha el enlace para obtener más información.

ACEPTAR