|
|
|
# Tabla de contenidos:
|
|
|
|
* [Introducción](#introducción)
|
|
|
|
* [Orden tienen las cosas](#orden-tienen-las-cosas)
|
|
|
|
* [Manos a la obra](#manos-a-la-obra)
|
|
|
|
* [Crear el *fork* con su rama *upstream-master*](#crear-el-fork-con-su-rama-upstream-master)
|
|
|
|
* [Actualizar la rama *upstream-master* en el *fork*](#actualizar-la-rama-upstream-master-en-el-fork)
|
|
|
|
* [Comenzar a trabajar un nuevo feature/mejora](#comenzar-a-trabajar-un-nuevo-featuremejora)
|
|
|
|
* [¿Solicitud de fusión rechazada?](#solicitud-de-fusión-rechazada)
|
|
|
|
|
|
|
|
## Introducción
|
|
|
|
|
|
|
|
Al trabajar en la implementación de un nuevo servicio en Ansible, una tarea cotidiana y más que recomendable es buscar en [la galaxia](https://galaxy.ansible.com) *roles* públicos que ya implementen lo que se necesita.
|
|
|
|
|
|
|
|
Muchas veces encontramos uno o mas *roles* que cumplen a la perfección el 90% de lo que precisamos, pero les falta algún detalle menor o no son completamente compatibles con el sistema operativo que vamos a utilizar.
|
|
|
|
|
|
|
|
Lo natural es aprovechar el avance de la comunidad, partiendo de esa gran base de código, y agregar las características que se consideran necesarias. Una vez concretada la mejora, incorporamos el *role* a nuestro proyecto particular y **¡listo!**
|
|
|
|
|
|
|
|
¿Listo? ¿Qué sucede si luego el *role* original sigue evolucionando e incorpora algún feature o mejora de seguridad que nos interesa? ¿Y si la licencia del proyecto original obliga a recompartir el código (por ejemplo GNU-GPL)? **¿Por qué necesitas que te obliguen para compartir?** ¿Cómo gestionamos dos bases de código que bifurcaron y evolucionaron independientemente?
|
|
|
|
|
|
|
|
**Todo esto lo solucionamos creando y trabajando en *forks*.** Pero, ¿qué entendemos por *fork*?
|
|
|
|
|
|
|
|
> Crear un *fork* es producir una copia propia del repositorio de alguien más. Los *forks* actúan como una especie de vínculo entre el repositorio original y el propio. Se puede enviar solicitudes de fusión para ayudar a mejorar los proyectos de otros, proponiendo cambios al proyecto original sin necesidad de ser miembro.
|
|
|
|
|
|
|
|
Al realizar nuestras mejoras sobre un *fork*, mantenemos el histórico del repositorio original (en adelante *upstream*). Esto hace extremadamente fácil y práctico a los responsables del proyecto, integrar los cambios que podamos proponer en una solicitud de fusión (*merge/pull request*). Igual de práctico será para nosotros, integrar en el propio repositorio, los avances del *upstream*.
|
|
|
|
|
|
|
|
|
|
|
|
## Orden tienen las cosas
|
|
|
|
|
|
|
|
[Ansible Galaxy](https://galaxy.ansible.com) se integra solo con GitHub, por lo tanto todos los *roles* públicos se encuentran en repositorios de esta plataforma. Como consecuencia, los *roles* públicos en los que colaboramos, son *forkeados* en el namespace de [nuestra organización GitHub](https://github.com/UdelaRInterior).
|
|
|
|
|
|
|
|
Tratándose de una organización, muchas veces hay varios miembros del equipo *DevOps* trabajando en simultáneo sobre un mismo *fork*, eventualmente uno retoma el trabajo de otro. Acordamos entonces un flujo estándar de trabajo que nos permita mantener el código ordenado y optimizado para proponer solicitudes de fusión y para actualizarnos desde el *upstream*.
|
|
|
|
|
|
|
|
Este flujo es casi idéntico al [empleado para desarrollos propios](flujo-de-trabajo-con-Git-en-Gitlab-y-GitHub), trabajamos cada feature/mejora en una rama específica, con el agregado de una rama espejo (*mirror*) de *master* del *upstream*.
|
|
|
|
|
|
|
|
Esta rama espejo, denominada `upstream-master`, nos permite mantener en nuestro repositorio (el *fork*) una réplica exacta del *upstream*, desde la cual partir al crear cada nueva rama para trabajar un feature. Al mismo tiempo, nos permite mantener nuestra rama *master* libre, puediendo transformarse en una versión alternativa al *upstream*, en caso que nuestras solicitudes de fusión no sean aceptadas.
|
|
|
|
|
|
|
|
|
|
|
|
## Manos a la obra
|
|
|
|
|
|
|
|
Gestionar correctamente la rama `upstream-master` es una tarea sencilla, pero en la que hay que ser cuidadoso.
|
|
|
|
|
|
|
|
A continuación se documenta paso a paso los procedimientos correctos para:
|
|
|
|
|
|
|
|
### Crear el *fork* con su rama `upstream-master`
|
|
|
|
|
|
|
|
* Una vez localizado en GitHub el repositorio del *role* de interés, [crear el fork](https://guides.github.com/activities/forking/) en el namespace `UdelaRInterior`.
|
|
|
|
|
|
|
|
* Clonar el flamante repositorio *fork*. Bien puede ser mediante un simple `git clone`, o a través de un archivo `requirements.yml` y el utilitario [`ansible-galaxy` con la opción `-g`](entorno-de-desarrollo-operaciones#manual)
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior$ git clone git@github.com:UdelaRInterior/ansible-zabbix-server.git
|
|
|
|
Clonando en 'ansible-zabbix-server'...
|
|
|
|
remote: Enumerating objects: 61, done.
|
|
|
|
remote: Counting objects: 100% (61/61), done.
|
|
|
|
remote: Compressing objects: 100% (39/39), done.
|
|
|
|
remote: Total 1476 (delta 25), reused 44 (delta 15), pack-reused 1415
|
|
|
|
Recibiendo objetos: 100% (1476/1476), 273.62 KiB | 767.00 KiB/s, listo.
|
|
|
|
Resolviendo deltas: 100% (787/787), listo.
|
|
|
|
```
|
|
|
|
|
|
|
|
* Dentro del directorio clonado, podemos listar los *remotos* para comprobar que solo se encuentra el de `UdelaRInterior` bajo el nombre *origin*
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git remote -v
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (fetch)
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (push)
|
|
|
|
```
|
|
|
|
|
|
|
|
* Procedemos a agregar el remoto del repositorio *upstream*, y lo nombramos precisamente `upstream`. (La dirección remota del *upstream* lo obtenemos del mismo modo que si lo fuéramos clonar)
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git remote add upstream \
|
|
|
|
https://github.com/dj-wasabi/ansible-zabbix-server.git
|
|
|
|
```
|
|
|
|
|
|
|
|
Comprbamos el resultado:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git remote -v
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (fetch)
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (push)
|
|
|
|
upstream https://github.com/dj-wasabi/ansible-zabbix-server.git (fetch)
|
|
|
|
upstream https://github.com/dj-wasabi/ansible-zabbix-server.git (push)
|
|
|
|
```
|
|
|
|
|
|
|
|
* "Parados" ahora en la rama *master* del *fork*, que todavía es una copia exacta de su homónima en el *upstream*, creamos la rama `upstream-master`:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch -al
|
|
|
|
* master
|
|
|
|
remotes/origin/HEAD -> origin/master
|
|
|
|
remotes/origin/master
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch upstream-master
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch -al
|
|
|
|
* master
|
|
|
|
upstream-master
|
|
|
|
remotes/origin/HEAD -> origin/master
|
|
|
|
remotes/origin/master
|
|
|
|
```
|
|
|
|
|
|
|
|
* Nos "paramos" ahora en la nueva rama y la subimos a nuestro repositorio (*origin*), indicando el romoto y rama correcta explícitamente en el `push`
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git checkout upstream-master
|
|
|
|
Cambiado a rama 'upstream-master'
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git push origin upstream-master
|
|
|
|
Total 0 (delta 0), reused 0 (delta 0)
|
|
|
|
remote:
|
|
|
|
remote: Create a pull request for 'upstream-master ' on GitHub by visiting:
|
|
|
|
remote: https://github.com/UdelaRInterior/ansible-zabbix-server/pull/new/upstream-master
|
|
|
|
remote:
|
|
|
|
To github.com:UdelaRInterior/ansible-zabbix-server.git
|
|
|
|
* [new branch] upstream-master -> upstream-master
|
|
|
|
```
|
|
|
|
|
|
|
|
Listo, ya tenemos nuestra rama espejo en local y subida a GitHub. Podemos comprobarlo listando las ramas locales y remotas:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch -al
|
|
|
|
master
|
|
|
|
* upstream-master
|
|
|
|
remotes/origin/HEAD -> origin/master
|
|
|
|
remotes/origin/master
|
|
|
|
remotes/origin/upstream-master
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Actualizar la rama `upstream-master` en el *fork*
|
|
|
|
|
|
|
|
Eventualmente el proyecto *upstream* avanzará en su desarrollo y tendremos disponibles esos avances para actualizar nuestra rama *mirror*.
|
|
|
|
|
|
|
|
Con los remotos configurados tal como en el procedimiento anterior:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git remote -v
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (fetch)
|
|
|
|
origin git@github.com:UdelaRInterior/ansible-zabbix-server.git (push)
|
|
|
|
upstream https://github.com/dj-wasabi/ansible-zabbix-server.git (fetch)
|
|
|
|
upstream https://github.com/dj-wasabi/ansible-zabbix-server.git (push)
|
|
|
|
```
|
|
|
|
|
|
|
|
El procedimiento de actualización consistirá en:
|
|
|
|
|
|
|
|
* "Pararse" en la rama `upstream-master`:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git checkout upstream-master
|
|
|
|
Cambiado a rama 'upstream-master'
|
|
|
|
```
|
|
|
|
|
|
|
|
* Hacer `pull` desde *master* del remoto *upstream*:
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git pull upstream master
|
|
|
|
remote: Enumerating objects: 20, done.
|
|
|
|
remote: Counting objects: 100% (20/20), done.
|
|
|
|
remote: Compressing objects: 100% (14/14), done.
|
|
|
|
remote: Total 20 (delta 7), reused 12 (delta 5), pack-reused 0
|
|
|
|
Desempaquetando objetos: 100% (20/20), listo.
|
|
|
|
Desde https://github.com/dj-wasabi/ansible-zabbix-server
|
|
|
|
* branch master -> FETCH_HEAD
|
|
|
|
* [nueva rama] master -> upstream/master
|
|
|
|
Actualizando 3d318f8..812a747
|
|
|
|
Fast-forward
|
|
|
|
.gitignore | 12 ++++++++++++
|
|
|
|
README.md | 11 +++++++----
|
|
|
|
defaults/main.yml | 6 +++++-
|
|
|
|
tasks/main.yml | 7 ++++---
|
|
|
|
tasks/mysql.yml | 24 ++++++++++++------------
|
|
|
|
5 files changed, 40 insertions(+), 20 deletions(-)
|
|
|
|
```
|
|
|
|
|
|
|
|
**Si venimos haciendo todo bien, las historias de `origin/upstream-master` y `upstream/master` serán identicas, por lo que el `pull` se completará automáticamente sin conflictos**
|
|
|
|
|
|
|
|
* Con la rama `upstream-master` ya actualizada en local, solo resta reflejar la actualización en `origin` (nuestro *fork*)
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git push origin upstream-master
|
|
|
|
Total 0 (delta 0), reused 0 (delta 0)
|
|
|
|
To github.com:UdelaRInterior/ansible-zabbix-server.git
|
|
|
|
3d318f8..812a747 upstream-master -> upstream-master
|
|
|
|
```
|
|
|
|
|
|
|
|
### Comenzar a trabajar un nuevo feature/mejora
|
|
|
|
|
|
|
|
Como ya se comentó, cualquier nuevo feature/mejora se trabajará en una rama específica. Como podrá sospecharse, dicha rama deberá crearse desde `upstream-master` previamente actualizado. De este modo partiremos lo más "limpios" posible para luego proponer el feature/mejora al proyecto *upstream*.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch
|
|
|
|
master
|
|
|
|
* upstream-master
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git branch nuevo-feature-mejora
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git checkout nuevo-feature-mejora
|
|
|
|
Cambiado a rama 'nuevo-feature-mejora'
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git commit -am "Ahora hace el doble"
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git push origin nuevo-feature-mejora
|
|
|
|
Total 0 (delta 0), reused 0 (delta 0)
|
|
|
|
remote:
|
|
|
|
remote: Create a pull request for 'nuevo-feature-mejora' on GitHub by visiting:
|
|
|
|
remote: https://github.com/UdelaRInterior/ansible-zabbix-server/pull/new/nuevo-feature-mejora
|
|
|
|
remote:
|
|
|
|
To github.com:UdelaRInterior/ansible-zabbix-server.git
|
|
|
|
* [new branch] nuevo-feature-mejora -> nuevo-feature-mejora
|
|
|
|
```
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
**Es importante tener en cuenta que una solicitud de fusión (*pull request* en GitHub), implica llevar una rama del *fork* a otra del *upstream*. Estas ramas quedan vinculadas durante todo el ciclo de vida de las solicitud de fusión, por lo tanto cualquier commit que se agregue a la rama propuesta será anexado a la solicitud de fusión**. Esta es otra razón por la que trabajar asuntos independientes en ramas independientes. De lo contrario los solicitudes de fusión que se envíen serán muy confusas, reduciendo las posibilidades de ser aceptada.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
### ¿Solicitud de fusión rechazada?
|
|
|
|
|
|
|
|
Eventualmente, si los features/mejoras propuestas no son aceptadas, querremos utilizarlos de todas formas. En este escenario, que debemos evitar siempre que sea posible, podremos fusionar esas ramas en nuestro propio *master*, y pasar a utilizar el *role* en la "versión del *fork*". Análogamente, podremos seguir integrando las mejoras que se agreguen en *upstream*.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git checkout master
|
|
|
|
Ya en 'master'
|
|
|
|
Tu rama está actualizada con 'origin/master'.
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git merge nuevo-feature-mejora
|
|
|
|
Actualizando 5dyd4o2..4a75nd7
|
|
|
|
Fast-forward
|
|
|
|
defaults/main.yml | 9 ++++++-
|
|
|
|
tasks/mysql.yml | 37 +++++++++++++++++++++++++++++++++++----------
|
|
|
|
2 files changed, 56 insertions(+), 23 deletions(-)
|
|
|
|
```
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git merge upstream-master
|
|
|
|
Actualizando 4a42c3f..812a747
|
|
|
|
Fast-forward
|
|
|
|
.gitignore | 12 ++++++++++++
|
|
|
|
README.md | 12 ++++++++----
|
|
|
|
defaults/main.yml | 7 ++++++-
|
|
|
|
tasks/main.yml | 25 ++++++-------------------
|
|
|
|
4 files changed, 67 insertions(+), 34 deletions(-)
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
santiagomr@pc:~/interior/ansible-zabbix-server$ git push origin master
|
|
|
|
Total 0 (delta 0), reused 0 (delta 0)
|
|
|
|
To github.com:UdelaRInterior/ansible-zabbix-server.git
|
|
|
|
4a42c3f..812a747 master -> master
|
|
|
|
``` |
|
|
\ No newline at end of file |