lunes, 3 de julio de 2017

Automatización de despliegue de un compuesto con Maven

En esta entrada del blog vamos a dar una mirada a algunos arquetipos que tenemos disponibles para la creación de compuestos de SOA/BPM en Oracle SOA Suite 12c. También vamos a abordar las tareas necesarias para automatizar el despliegue de estos compuestos hacia la SOA-INFRA.

La versión particular que estoy utilizando es 12.2.1.0.0; sin embargo, esto se encuentra disponible en 12.1.3.0.0 y 12.2.1.2.0. Así que pueden usar cualquier release de Oracle SOA Suite 12c.

Pre-requisitos


Hay algunas tareas previas que debemos ejecutar para tener en nuestro repositorio local de Maven los elementos necesarios para desplegar aplicaciones de Oracle SOA Suite. Los pre-requisitos son los siguientes:

  1. Instalar y configurar Maven (por obvio que esto parezca, habrá quien piensa que es magia)
  2. Configurar Maven para la automatización y configuración de dependencias de proyectos de Oracle SOA Suite 12c. Esto incluye: instalar y configurar el plug-in para la sicronización de Maven, ejecutar el plug-in para la sincronización del Repositorio de Maven, poblar el repositorio de Maven. La documentación oficial de Oracle para realizar esto, la pueden encontrar aquí:
https://docs.oracle.com/middleware/1221/core/MAVEN/config_maven.htm#MAVEN8853

Una vez realizado esto, podemos continuar.

Creación de una aplicación y proyecto de Oracle SOA Suite, utilizando el arquetipo de Maven


Para nuestra comodidad, ya existe un arquetipo que podemos utilizar para crear la estructura inicial de nuestro proyecto. Basta con ejecutar el siguiente comando para crear en nuestro sistema de archivos, la estructura de carpeta de nuestro proyecto:

mvn archetype:generate -DarchetypeGroupId=com.oracle.soa.archetype -DarchetypeArtifactId=oracle-soa-application -DarchetypeVersion=12.2.1-1-0 -DarchetypeRepository=local

El arquetipo usado lo estoy buscando en mi repositorio local, debido a que no existe en el repositorio central de Maven. Es por esto que uno de los pasos previos es poblar el repositorio de Maven siguiendo los pasos de la documentación mencionados arriba.


El resultado de la ejecución, será la creación de las carpetas del proyecto en el sistema de archivos. En mi caso particular voy a crear una aplicación que me sirva para exponer un API para el procesamiento de órdenes de compra que usaré en un futuro para algunas demostraciones. Dentro de esa aplicación, crearé un proyecto para la primer capacidad del API, que me servirá para validar algunos datos del pago, previo al procesamiento de las órdenes de compra.

En la estructura de las carpetas podemos observar lo necesario para crear algunos elementos típicos de un compuesto SOA: Events, Schemas, Transformations, WSDLs, etcétera. Hasta aquí no hemos creado ninguna aplicación (JWS) ni proyecto (PRJ) de JDeveloper. Sólo hemos generado la estructura de nuestras carpetas.


El arquetipo nos crea dos archivos POM: uno de aplicación y otro de proyecto.

Ejecución de comandos de Maven


En este punto podemos empaquetar el proyecto que hemos creado. Esto nos generará un JAR (evidentemente vacío, pues no hemos puesto código dentro del mismo). Para empaquetar el proyecto, ejecutamos el siguiente comando debajo de la carpeta de nuestra aplicación:

mvn package

Si es la primera vez que hacemos esto, vamos a observar un warning como el siguiente. Esto es debido a que la expresión version ya está deprecada; en lugar de esto deberíamos usar project.version.


Corregir lo anterior es muy simple, únicamente debemos abrir el POM que se encuentra debajo del proyecto (generado automáticamente por el arquetipo) y ubicar la expresión en las propiedades de configuración del proyecto.


Entonces reemplazamos version por project.version y guardamos el POM del proyecto. Algo importante es que esto se encuentra en el POM del proyecto, NO en el POM de la aplicación.


Si ejecutamos de nuevo el comando para empaquetar el proyecto, observaremos que el warning ha desaparecido.


El proyecto ha compilado y el paquete se ha generado correctamente.


Para poder validar lo anterior, vamos de nuevo al sistema de archivos generado por el arquetipo. Notamos que se ha creado una carpeta adicional debajo de la carpeta del proyecto. Esta nueva carpeta se llama target. Dentro de ella tendremos el JAR (paquete) generado por Maven.


Import del proyecto en JDeveloper


Dado que el proyecto no tiene código aún, vamos a abrirlo en JDeveloper y agregar algo de funcionalidad. Para realizar esto damos un click en New > Import y veremos un asistente que nos permite importar proyectos de Maven a JDeveloper.


En el directorio raíz, vamos a seleccionar la carpeta donde creamos la aplicación. El archivo de configuración de Maven (settings.xml) se selecciona de manera automática, lo vamos a conservar así.

En la estructura de proyectos debemos elegir tanto el POM de la aplicación, como el POM del proyecto. El resultado de esto es que JDeveloper va a crear el archivo de aplicación (JWS) y el archivo del proyecto (PRJ) debajo de la misma estructura de archivos donde estamos trabajando. En caso de que deseemos colocar el código debajo de otra carpeta (por ejemplo tu propio workspace de JDeveloper), debemos seleccionar la opción: Also import source files into application (no es mi caso, yo quiero trabajar en el mismo directorio).


A continuación, JDeveloper nos pedirá algunos datos adicionales para crear la aplicación. Probablemente les salga una advertencia de sobreescritura del archivo de la aplicación (JWS), debemos aceptar sin miedo (no puede sobreescribirse un archivo que ni siquiera ha sido creado todavía).


Observamos que en nuestra estructura de archivos se ha creado el archivo de la aplicación de JDeveloper (JWS).


También se ha creado el archivo del proyecto (PRJ).


En JDeveloper, ahora podemos ver ambas cosas: aplicación y proyecto.


Implementación del compuesto


Ahora voy a agregar un poco de código al proyecto (aquí pueden implementar lo que ustedes quieran). En el caso de mi ejemplo, agregué lo siguiente:


  1. Creé un esquema para definir el modelo canónico de mi proceso de negocio.
  2. Creé un BPEL que realiza la validación de la información un pago.
  3. Dentro del BPEL coloqué una validación: si el monto de la orden es menor o igual a 1000.00, el pago es aceptado; en caso contrario, el pago es rechazado. Esto a través de XSL.
  4. Expuse el compuesto en dos interfaces: SOAP y REST (JSON/XML).

Hasta este punto, podríamos compilar y desplegar el código como lo hacemos en forma tradicional, de manera manual.


Parent POM: sar-common 


Para poder automatizar las tareas de empaquetado y despliegue del código es necesario utilizar el parent POM: sar-common. Este debería estar previamente instalado en nuestro repositorio local al momento de ejecutar los pre-requisitos.

En el POM de sar-common, debemos hacer algunas modificaciones para la conexión al servidor a donde deseamos desplegar los compuestos. Esto evitará que en cada proyecto debamos de colocar los datos del servidor, así como las credenciales de conexión.

El POM a modificar se encuentra debajo de la siguiente ruta:

.m2\repository\com\oracle\soa\sar-common\12.2.1-1-0

Aquí debemos modificar lo siguiente:


  1. Usuario y contraseña para la conexión al servidor
  2. URL del servidor
  3. Nombre del servidor
  4. Ruta del Middleware Home



Despliegue desde JDeveloper (usando Maven)


Para la automatización de empaquetado y despliegue del compuesto, vamos a utilizar el goal de Maven llamado: pre-integration-test. Este goal no se encuentra disponible por default en JDeveloper, por lo que debemos agregarlo.

Para agregar este goal damos click derecho sobre el POM del proyecto > Run Maven > Manage Goal Profiles. Esto nos abrirá la siguiente vista:


Click sobre la cruz de color verde > Add Phases > Seleccionar pre-integration-test.


Una vez realizado lo anterior, debemos tener la fase disponible en el menú contextual. Al ejecutar pre-integration-test, el compuesto será desplegado hacia la SOA-INFRA.


Despliegue desde línea de comandos (usando Maven)


Si deseamos desplegar el compuesto desde la línea de comandos, lo primero que debemos hacer es settear la variable de ambiente ORACLE_HOME hacia una instalación válida de JDeveloper. Después ejecutar el siguiente comando:

mvn pre-integration-test

El script de Maven compilará el código.


Posteriormente creará el paquete.


Finalmente realizará el despliegue al servidor.


Validación del compuesto en Enterprise Manager


Una vez desplegado el compuesto, podemos validar el despliegue en Enterprise Manager. Al navegar hacia la vista de compuestos desplegados, podemos observar que el compuesto ya se encuentra en el servidor.


Pruebas del compuesto


A continuación, podemos ejecutar algunas pruebas básicas para validar el funcionamiento del código.

La primer prueba la ejecutamos utilizando un monto total de la orden igual a 100.00. Esto deberá responder Autorizado, de acuerdo a la implementación del XSL.



Ahora ejecutamos una prueba con un monto total de la orden de 2000.00. El pago deberá ser Rechazado.



Finalmente, podemos validar que ambas instancias fueron creadas y completadas de manera exitosa.


Algunas conclusiones



  1. Es posible automatizar tareas de compilación, empaquetado y despliegue de compuestos de Oracle SOA Suite. Este puede ser un primer paso para la implementación de una estrategia de DevOps y Continuous Integration.
  2. Oracle proveé de un plug-in para configurar y poblar nuestro repositorio local de Maven con los elementos necesarios para tareas de automatización de despliegues.
  3. A través de Maven (y sus arquetipos) podemos crear la estructura inicial de un proyecto de Oracle SOA Suite.
  4. JDeveloper nos permite importar proyectos de Maven previamente creados con algún arquetipo.
  5. Es posible desplegar compuestos de Oracle SOA Suite, de manera automática, desde JDeveloper y desde la línea de comandos.
  6. El automatizar el despliegue de los proyectos de Oracle SOA Suite, no implica realizar cambios en la forma en que tradicionalmente desarrollamos. Simplemente facilita las tareas del desarrollador al automatizar algunas tareas comunes.

Referencias

En la siguiente referencia pueden encontrar un video que muestra los pasos ejecutados en ésta entrada:




jueves, 25 de mayo de 2017

Válvulas - File Adapter

Uso de válvulas en el File Adapter

Existe una funcionalidad de pre-procesamiento de archivos que podemos añadir al File Adapter de la Oracle SOA Suite. Personalmente no la conocía, pero me parece muy práctica y es por eso que decidí compartir esta entrada del blog.

El requerimiento es simple. Tal vez sea común trabajar con archivos de tipo CSV, posicionales, de texto plano, etc. En lo primero que pensamos para resolver una situación donde se involucren archivos es en el File Adapter.

Entre sus características están leer el archivo haciendo uso de streaming, utilizar un NXSD para transformar el contenido de manera nativa a XML, o simplemente no leer el contenido y transportar el archivo hacia algún sitio (file system, FTP).

En esta ocasión, la necesidad es un tanto "fuera de lo común": procesar un archivo de Excel.

Si bien el File Adapter no tiene entre sus capacidades nativas procesar un archivo de este tipo (me refiero a leer el contenido), tampoco es ciencia saber cómo resolver el problema. No existe una forma de transformar un archivo Excel mediante un NXSD.

Una de las opciones que puede pasar por nuestra cabeza es leer el archivo con el File Adapter (sin procesar el contenido) y posteriormente con una actividad Java Embedding procesar el contenido. Sin duda esta es una forma de abordar la solución.

Sin embargo, existe una manera más elegante de resolverlo: las válvulas y pipelines que se pueden crear para el File Adapter.

Flujo del File Adapter


El flujo que normalmente sigue el File Adapter para procesar un archivo de entrada, es el siguiente:

File System > (1) > File o FTP Adapter > (2) > Transformación (NXSD) > (3) > Proceso BPEL o Pipeline de OSB o Mediador

Donde:

(1) - El File Adapter lee el archivo o archivos de la ruta indicada
(2) - El contenido del archivo se traslada a un proceso de traducción donde mediante un NXSD transformamos el contenido a XML. El traductor publica el contenido hacia el SCA (tiempo de ejecución).
(3) - Finalmente, el SCA publica el contenido hacia el engine de servicio (BPEL, OSB, Mediator).

Flujo del File Adapter haciendo uso de Pipelines y Válvulas


En el caso de las válvulas y los pipelines, va a existir un paso intermedio, justo entre los pasos (1) y (2), el resto del flujo es el mismo.

De tal suerte que nuestro flujo de procesamiento quedaría como sigue:


File System >  (1) > File o FTP Adapter > (1A) > Pipeline > (1B) > Válvula > (1C) > File o FTP Adapter (2) > Transformación (NXSD) > (3) > Proceso BPEL o Pipeline de OSB o Mediador

Donde:

(1A) - El File Adapter va a trasladar el contenido hacia un Pipeline, que tiene asociadas válvulas de pre-procesamiento.
(1B) - El Pipeline va a ejecutar las válvulas de pre-procesamiento en el orden que nosotros indiquemos.
(1C) - La última válvula que se ejecute, va a devolver el control al Pipeline, y este a su vez va a devolver el contenido del archivo pre-procesado al FTP Adapter. A partir de ahí, el flujo es el mismo.

Implementación de la válvula


Implementar la válvula es relativamente simple. Vamos a necesitar dos proyectos: uno Java y un compuesto.

Proyecto Java


El proyecto Java contendrá básicamente el código fuente para la conversión de XLS a CSV. Para esto usamos, como dije antes, Apache POI.

La clase implementada es la siguiente:

package excelvalves;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Iterator;

import oracle.tip.pc.services.pipeline.AbstractValve;
import oracle.tip.pc.services.pipeline.InputStreamContext;
import oracle.tip.pc.services.pipeline.PipelineException;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class ExcelToCsv extends AbstractValve {

    public InputStreamContext execute(InputStreamContext inputStreamContext) throws IOException, PipelineException {
        System.out.println("The valve will begin executing the inputstream");
        // Get the input stream that is passed to the Valve
        InputStream originalInputStream = inputStreamContext.getInputStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        
        // Read workbook into HSSFWorkbook
        Workbook workbook = new HSSFWorkbook(originalInputStream);

        // Read worksheet into HSSFSheet
        Sheet datatypeSheet = workbook.getSheetAt(0);

        // To iterate over the rows
        Iterator<Row> iterator = datatypeSheet.iterator();

        //store the csv string
        StringBuffer data = new StringBuffer();
        
        int i = 0;

        //Loop through rows.
        while (iterator.hasNext()) {
            int j = 0;
            Row currentRow = iterator.next();
            Iterator<Cell> cellIterator = currentRow.iterator();
            while (cellIterator.hasNext()) {
                Cell currentCell = cellIterator.next();
                if (currentCell.toString().length() > 0 && i > 0) {
                    switch (currentCell.getCellType()) {
                    case Cell.CELL_TYPE_BOOLEAN:
                        data.append(currentCell.getBooleanCellValue() + ",");
                        break;

                    case Cell.CELL_TYPE_NUMERIC:
                        DateFormat df = new SimpleDateFormat("yyyyMMdd");
                        Date date = currentCell.getDateCellValue();
                        data.append(df.format(date) + ",");
                        break;

                    case Cell.CELL_TYPE_STRING:
                        data.append(currentCell.getStringCellValue() + ",");
                        break;

                    case Cell.CELL_TYPE_BLANK:
                        data.append("" + ",");
                        break;

                    default:
                        data.append(currentCell + ",");
                    }
                    if (j == 15) {
                        data.append('\n');
                    }
                }
                j++;
            }
            i++;
        }
        System.out.println("snippet from stream: " + data.toString());
        ByteArrayInputStream bin = new ByteArrayInputStream(data.toString().getBytes());
        inputStreamContext.setInputStream(bin);
        System.out.println("done processing the stream in the valve");
        return inputStreamContext;
    }

    @Override
    public void finalize(InputStreamContext inputStreamContext) {
        // TODO Implement this method
    }

    @Override
    public void cleanup() throws PipelineException, IOException {
        // TODO Implement this method


    }
}

Las librerías necesarias para el proyecto son las siguientes:


Lo siguiente es compilar, generar un perfil de despliegue y desplegar el proyecto en un JAR.


Proyecto SOA (compuesto)


Vamos a crear un compuesto con un File Adapter como servicio expuesto. En el asistente de configuración colocar lo siguiente:

Definir la interfaz posteriormente.


Mantener JNDI por default.


Seleccionar operación de lectura (no leer el contenido del archivo).


Leer cualquier archivo (*.*).


Frecuencia de lectura: 10 segundos.


Seleccionar el NXSD con el que convertiremos el CSV a XML.


Finalizar la configuración.


Una vez que tenemos el adaptador listo, vamos a crear el Pipeline. Para esto basta con crear un archivo XML nuevo (ExcelPipeline.xml), debajo de la carpeta SOA:



Este archivo XML va a definir el orden en que se van a ejecutar las válvulas. Aquí lo único que hay que colocar es el nombre de las clases que hemos creado en el proyecto Java (completamente calificadas): en mi caso excelvalves.ExcelToCsv, que fue el nombre que le puse a mi clase donde implementé la válvula. Aquí podemos agregar una o más, dependiendo de nuestras necesidades de implementación.


Finalmente, vamos a agregar en el archivo de configuración del adaptador (JCA), la referencia hacia el Pipeline: <property name="PipelineFile" value="ExcelPipeline.xml"/>




Después de esto, ligamos el adapter a un proceso BPEL. De tal suerte que nuestro compuesto queda de la siguiente forma:


Debajo de la carpeta SCA-INF/lib, debemos colocar el JAR generado de nuestra válvula (el que generamos en el proyecto Java).

Desplegamos el proyecto del compuesto a nuestra infraestructura y lo probamos colocando un archivo de Excel en la ruta que configuramos en nuestro File Adapter.

Deberá iniciarse una instancia y aparecer lo siguiente en nuestros logs:


En Enterprise Manager podremos ver que la instancia se ha ejecutado correctamente:


Los detalles de la traza:


En este caso el BPEL no hace otra cosa sino un assign de la entrada a una variable para posteriormente terminar:


Observamos que los datos provenientes del Excel han sido asignados de manera correcta a la variable:


Comprobamos que todo se haya realizado bien, comparando con los datos de nuestro archivo de Excel:


Resumen


  • Las válvulas pueden servir para pre y/o post procesamiento (archivos de entrada y/o de salida).
  • Las válvulas serán ejecutadas en el orden que definan dentro del pipeline.
  • El pipeline a usar se configura dentro del archivo JCA del adaptador.
  • El pipeline se define en un archivo XML.
  • Las clases de pre y/o post procesamiento se implementan en Java y reciben como entrada un InputStream.
  • Se pueden utilizar frameworks adicionales dentro de las clases Java que implementan la lógica de nuestras válvulas. En mi caso utilicé Apache POI para el procesamiento del archivo Excel (https://poi.apache.org/).
  • El JAR que contiene la implementación de las válvulas se debe incluir en el proyecto (compuesto, OSB) que lo utiliza. Para el caso de un compuesto, lo ponemos debajo de SCA-INF/lib.

jueves, 18 de mayo de 2017

GitHub + Git (SourceTree)

GitHub


Vamos a hacer una pequeña demostración de algunas de las capacidades que tiene GitHub para el control de versiones de código. GitHub es un sistema de almacenamiento de código para control de versiones y colaboración (definición comercial).

Esto es algo de lo que muchos de nosotros hacemos todos los días: colaborar con distintos equipos o compañeros, en uno o varios proyectos, pero al final hay código que pudiéramos compartir.

Es como cuando alguien se va de vacaciones y tienes que ocuparte de sus pendientes, necesitas su código. ¿Y si no te dejó el USB o el disco duro con la última versión? Eso es un poco obsoleto, lo más simple es usar Git para poder hacer esas tareas de colaboración.

Nuevo repositorio


Al grano. Previo a todo esto he creado una cuenta en https://github.com, igual que cuando crearon su cuenta en Twitter o Facebook. Una vez que tienen su usuario y contraseña, pueden entrar al portal y seguir estos pasos.

El primero de todos es crear un nuevo repositorio. Ese lugar en la nube donde van a almacenar todos sus artefactos.

Para esto basta con dar un click en el + que se muestra en la figura y seleccionar la opción para crear un nuevo repositorio.


Posteriormente, el sistema nos va a solicitar algunos datos del repositorio como nombre, descripción, si es público o privado y si queremos inicializarlo (poblarlo) con un archivo README. Al confirmar todo esto ya tendremos nuestro repositorio creado.



El repositorio se va a crear con una rama por default: master. Ésta va a ser la rama en la que se encuentra la última versión de nuestro código, la más actualizada.



Nuevo branch


Para incluir nueva funcionalidad, lo que deberíamos hacer es crear nuevos branches (sin actualizar directamente en master). En esos nuevos branches vamos a trabajar por separado, una vez que finalicemos, vamos a realizar un merge con master para incluir nuestros cambios. Cuando creamos un nuevo branch, tomaremos una foto (snapshot) de master en ese momento del tiempo. Todo el código que se encuentre en master, se copiará a nuestro nuevo branch.

En mi caso he incluido un branch llamado: branch-20170517. Aquí es donde voy a incluir mis cambios, sin alterar el master.

Basta con dar un click en el combo (justo a lado de master) y elegir la opción para crear una nueva rama o branch.


Una vez que he creado mi branch, puedo iniciar a trabajar los cambios que necesite. Para esto es muy importante asegurarnos que estamos realizando estos cambios en el branch que acabamos de crear, no en master.


Una vez que estamos seguros que estamos en el branch adecuado, vamos a trabajar los cambios. Para este ejemplo únicamente voy a modificar el archivo README que se creó inicialmente. La modificación consiste en agregar una nota en el README, pero ahora en español.


Commit (guardar)


Una vez que he realizado los cambios en mi branch de trabajo, voy a hacer un commit del mismo (guardar). El commit siempre tiene asociado un mensaje, con esto podemos tener la historia de quién hizo los cambios y porqué. Es una buena práctica colocar un mensaje claro de los cambios asociados a ese commit.


Después de haber realizado los cambios en el README, es necesario hacer un merge hacia el branch master. Recordemos que estamos trabajando en branch-20170517.

Pull request


Un pull request es la parte fundamental del concepto de colaboración en GitHub. Básicamente con un pull request le solicitamos a alguien, que haga la revisión de los cambios que hemos realizado, la descargue y haga el merge hacia su branch. En este caso estaríamos haciendo algo como lo siguiente:

branch-20140517  >> pull request >> master

Dentro del pull request va a suceder lo siguiente:

comparación >> merge (aprobación de los cambios)  >> confirmación

Para crear el pull request sólo tenemos que ir al tab de la parte superior del sistema: pull request. Luego elegir el botón nuevo pull request.


Posteriormente vamos a llenar algunos datos para crear el pull request. Desde qué branch se originan los cambios (branch-20170517) y hacia qué branch se tienen que trasladar (master). También se muestran las diferencias entre ambas ramas. Una vez realizado esto, hay que presionar el botón crear pull request.



Podemos incluir algunos comentarios, indicando la razón del pull request.

Merge


Esto será enviado a un flujo de aprobación, donde alguien tendrá que hacer el merge de los cambios. En este caso como estoy usando el mismo usuario, yo completaré ambas tareas. Hasta este momento nuestro pull request estará abierto.

Algo que me pareció muy cotorro, es que puedes agregar algunas reacciones (mano arriba, mano abajo, cara feliz, gorro de fiesta). Esto le da un toque de red social a esta parte del flujo. Y puede reflejar en un ícono, nuestro pensamiento acerca de los cambios realizados en el repositorio.


El pull request va a permanecer abierto hasta que alguien apruebe (o rechace) los cambios, y posteriormente lo cierre. En nuestro caso son cambios que se pueden combinar directamente entre nuestro branch de trabajo y master, así que esto es automático. Simplemente presionamos el botón merge pull request, incluimos algunos comentarios si lo consideramos necesario y entonces el pull request quedará cerrado y nuestro branch master ya contendrá los cambios realizados al README.


En la siguiente pantalla tenemos una última confirmación del merge. Si nos queremos arrepentir, éste es el momento. Una vez presionado el botón, ya no se podrá dar marcha atrás.



Lo que nos mostrará el sistema son dos cosas: la confirmación del merge y una opción para borrar el branch. Una vez que tenemos los cambios en master, ya no necesitamos más ese branch.


Finalmente podríamos agregar algunos comentarios y/o reacciones, vemos la confirmación tanto del merge, como del borrado del branch.



Confirmación en el repositorio


Si volvemos a nuestro repositorio, vamos a poder que los cambios ya están incluídos en master.





SourceTree


Hacer esto directamente en GitHub, pudiera ser muy simple. Sin embargo, para una gran cantidad de artefactos, esas tareas de comparación y merge pueden volverse un poco complejas. O bien, si a nosotros no nos acomodan los sitios web y preferimos la línea de comandos, entonces podemos utilizar Git. O algo intermedio, un cliente de Git.

SourceTree es uno de los que me parecen muy intuitivos y completos, por detrás usa Git. Trae un Git propio, o si ustedes tienen una versión en particular previamente instalada, se puede configurar para que use la que más les convenga.

Una vez que el administrador ha creado el repositorio inicial (todos los pasos anteriores), alguna de nuestras tareas pudiera ser hacer algunos cambios (agregar, modificar o eliminar artefactos). Para eso necesitamos tener el código en nuestras máquinas o en un ambiente local. Posteriormente desarrollar, probar y subir los cambios de nuevo al repositorio. Para esto usamos SourceTree (o Git).

Clonar repositorio


Lo primero que haremos es descargar el repositorio que ya está en la nube de GitHub. Elegimos clone, colocamos la URL de nuestro repositorio de GitHub, la carpeta de destino en nuestra máquina y el nombre del branch que deseamos descargar. Presionamos el botón de clonar y esperamos la confirmación de la descarga.



Copia local


Lo anterior nos va a crear una copia local del repositorio en la ruta que indicamos. Ahí comenzaremos con los cambios.


Los cambios que hice son muy básicos: agregué un README, pero en vez de tener extensión MD (como el original del repositorio), le puse extensión TXT.


Commit


Mis cambios están listos y es hora de hacer commit. Si vamos a la sección de commit (arriba a la izquierda) de SourceTree, podemos ver varias cosas: los archivos que están pendientes por subirse al repositorio (README.txt) y el contenido (o diferencia) de lo que está en nuestra copia local y lo que está en el repositorio. Una vez que seleccionamos lo que queremos subir, presionamos el botón de commit (que está abajo a la derecha). Aquí podemos agregar nuestros comentarios del commit (al igual que lo hicimos en GitHub).








SourceTree nos mostrará un mensaje de confirmación y podremos observar de nuevo en la parte central, que ya no hay cambios en nuestra copia local con respecto al repositorio.




Push


Ya que hicimos el commit, los cambios no se verán reflejados en el repositorio, sino hasta hacer un push. Source Tree nos habilitará la sección de push (arriba a la izquierda). Esto nos dará oportunidad de elegir desde dónde y hacia dónde necesitamos hacer el push de los cambios. En este caso van de mi master local hacia el master del repositorio de GitHub. Esperamos la confirmación de finalización del push.





Confirmación de cambios en el repositorio


Ahora podremos confirmar que los cambios fueron colocados correctamente en el repositorio. El archivo README.txt debería estar ahí:


Cambio directamente en el repositorio


Para mostrar cómo debemos tratar cuando alguien más realiza un cambio en el repositorio, vamos a crear una clase java simple directamente en GitHub. De alguna forma SourceTree nos debe avisar que ha habido un cambio en el repositorio y que lo debemos descargar. Esto es para que siempre podamos tener la última copia del repositorio, Podríamos estar trabajando en un componente que alguien más actualizó y subió al repositorio, si no tenemos la última versión podríamos estar planchando sus cambios.

Para mostrar esto creamos la clase java en el repositorio y hacemos commit, directamente en GutHub.




Pull


Ahora veremos en SourceTree que en el botón de Pull, tenemos una marca (número) que indica que algunos cambios están en el repositorio, pero no en nuestra copia local y debemos descargarlos. Presionamos el botón de pull, confirmamos desde dónde y hacia dónde vamos a traer los cambios y finalmente esperamos la confirmación de que los cambios han sido descargados.






Confirmación en nuestra copia local


Finalmente podemos ir a nuestra copia local y confirmar que los cambios han sido descargados correctamente.





Resumen


Esta es una manera muy simple de mostrar algunas de las características GitHub, y también de cómo podemos interactuar con esos repositorios a través de Git o SourceTree, que es un cliente de Git. A partir de aquí pueden crear su propio repositorio y jugar con las estructuras, branches, merge, flujo de GitHub.

Es una inicial y muy simple aproximación a este tipo de sistemas de control de versiones y colaboración en la nube. Puede convertirse en algo muy poderoso e importante en su entorno de integración continua.

Pueden dar una mirada más a profundidad en las referencias que menciono a continuación.

Referencias


GitHub: https://github.com/
SourceTree: https://www.sourcetreeapp.com/
Git: https://git-scm.com/