Situaciones típicas en la integración continua

¿Has aprendido comandos de Git pero deseas entender cómo funciona la integración continua (Continuous Integration, CI) en la realidad? ¿O tal vez quieres optimizar tus actividades diarias? Este curso te proporcionará habilidades prácticas de integración continua utilizando un repositorio en GitHub. Este curso no está diseñado como un asistente que puedes simplemente hacer clic, por el contrario, realizarás las mismas acciones que las personas realmente hacen en el trabajo, de la misma manera que lo hacen. Te explicaré la teoría a medida que avances por los pasos que tienen relación con ella.

¿Qué haremos?

A medida que avancemos, iremos creando gradualmente una lista de pasos típicos de CI, lo cual es una excelente manera de recordar esta lista. En otras palabras, vamos a crear una lista de acciones que los desarrolladores realizan al llevar a cabo la integración continua. También utilizaremos un conjunto básico de pruebas para acercar nuestro proceso de CI a la realidad.

Este GIF muestra esquemáticamente los commits en tu repositorio a medida que avanzas en el curso. Como puedes ver, no hay nada complicado y solo lo más necesario.

Situaciones típicas en la integración continua

Vas a pasar por los siguientes escenarios estándar de CI:

  • Trabajar en una característica;
  • Aplicar pruebas automáticas para asegurar la calidad;
  • Implementar una tarea prioritaria;
  • Resolver conflictos al fusionar ramas (merge conflict);
  • Ocurre un error en el entorno de producción.

¿Qué aprenderás?

Podrás responder a estas preguntas:

  • ¿Qué es la integración continua (CI)?
  • ¿Qué tipos de pruebas automáticas se utilizan en CI y ante qué acciones se activan?
  • ¿Qué es un pull request y cuándo son necesarios?
  • ¿Qué es el desarrollo dirigido por pruebas (Test Driven Development, TDD) y cómo se relaciona con la CI?
  • ¿Realizar un merge o aplicar cambios mediante rebase?
  • ¿Hacer un rollback o corregir en la siguiente versión?

Al principio traducía términos como "pull request", pero al final decidí devolver frases al inglés en algunos lugares para disminuir el grado de locura en el texto. A veces usaré "surgir de programador" como el curioso verbo "commitear" allí donde la gente realmente lo utiliza en el trabajo.

¿Qué es la integración continua?

Integración continua, o CI, es una práctica técnica que consiste en que cada miembro del equipo integra su código en un repositorio común al menos una vez al día, y el código resultante debe compilarse sin errores.

Existen discrepancias sobre este término.

El tema de discusión es la frecuencia de integración. Algunos argumentan que integrar el código solo una vez al día no es suficiente y que en realidad debería ser de manera continua. Se cita el ejemplo de un equipo en el que todos toman el código fresco por la mañana e integran una vez por la noche. Aunque es un argumento razonable, en general se considera que la definición de 'una vez al día' es suficientemente práctica, específica y adecuada para equipos de diferentes tamaños.

Otro argumento es que C++ ya no es el único lenguaje utilizado en el desarrollo, y el simple requerimiento de compilar sin errores como forma de validación es débil. Un conjunto de pruebas (por ejemplo, pruebas unitarias que se ejecutan localmente) también debe finalizar con éxito. En este momento, la comunidad tiende a considerar que tal requisito debe ser obligatorio, y en el futuro, 'compilación + pruebas unitarias', evidentemente, se convertirá en un estándar, si es que no ha sucedido ya.

Integración continua se diferencia de la entrega continua (Continuous Delivery, CD) en que no requiere un candidato a lanzamiento después de cada ciclo de integración.

Lista de pasos que utilizaremos a lo largo del curso

  1. Extrae el último código. Crea una rama desde master. Comienza a trabajar.
  2. Crea commits en tu nueva rama. Compila y prueba localmente. ¿Pasó? Ve al siguiente paso. ¿Falló? Corrige los errores o pruebas y vuelve a intentarlo.
  3. Envía a tu repositorio remoto o rama remota.
  4. Crea una solicitud de extracción. Discute los cambios, agrega más commits a medida que continúa la discusión. Haz que las pruebas pasen en la rama de características.
  5. Fusiona/rebase commits de master. Haz que las pruebas pasen en el resultado de la fusión.
  6. Despliega desde la rama de características a producción.
  7. Si todo está bien en producción durante un tiempo, fusiona los cambios a master.

Situaciones típicas en la integración continua

️ Preparación

Asegúrate de tener el software necesario.

Para seguir este curso necesitarás Node.js y un cliente de Git..

Puedes usar cualquier cliente de Git, pero solo proporcionaré comandos para la línea de comandos.

Asegúrate de tener instalado un cliente de Git que soporte la línea de comandos.

Si aún no tienes un cliente de Git que soporte la línea de comandos, puedes encontrar instrucciones para la instalación. aquí.

Prepara el repositorio.

Necesitarás crear una copia personal (fork) del repositorio plantilla con el código para el curso en GitHub. Vamos a convenir en llamar a esta copia personal el repositorio del curso..

¿Lo has hecho? Si no has cambiado la configuración predeterminada, tu repositorio del curso probablemente se llama continuous-integration-team-scenarios-students, se encuentra en tu cuenta de GitHub y la URL se ve así

https://github.com//continuous-integration-team-scenarios-students

Yo llamaré a esta dirección simplemente <URL репозитория>.

Los signos de menor y mayor como <тут> significarán que debes reemplazar esa expresión por el valor correspondiente.

Asegúrate de que GitHub actions estén habilitadas para este repositorio del curso. Si no están habilitadas, por favor habilítalas haciendo clic en el gran botón en el centro de la página, al que puedes acceder haciendo clic en Actions en la interfaz de GitHub.

No podrás completar el curso siguiendo mis instrucciones si GitHub Actions no están habilitadas.

Situaciones típicas en la integración continua

Siempre puedes usar la capacidad de GitHub de mostrar Markdown para ver el estado actual de la lista que estamos elaborando aquí

https://github.com//continuous-integration-team-scenarios-students/blob/master/ci.md

Sobre las respuestas

Aunque la mejor manera de completar este curso es hacerlo todo por tu cuenta, puedes encontrar algunas dificultades.

Si sientes que no entiendes qué hacer y no puedes continuar, puedes echar un vistazo a la rama solution, que está en tu repositorio inicial.
Por favor, no realices una fusión solution en master durante el curso. Puedes usar esta rama para entender qué hacer, o para comparar tu código con el original, usando todas las capacidades que Git nos ofrece. Si te has perdido completamente, puedes reemplazar tu rama master con la rama solution y luego restablecer tu directorio de trabajo al paso del curso que necesites.

Usa esto solo si realmente lo necesitas.

Confirma (commit) tu código

git add .
git commit -m "Respaldo de mi trabajo"

Estos comandos

  • renombrarán master en master-backup;
  • renombrarán solution en master;
  • cambiarán (checkout) a la nueva rama master y sobrescribirán el contenido del directorio de trabajo;
  • crearán la rama "solution" desde "master" (que antes era "solution") por si en el futuro necesitas la rama "solution".

git branch -m master master-backup
git branch -m solution master
git checkout master -f
git branch solution

Después de estas acciones, puedes usar git log master para averiguar qué commit necesitas.
Puedes restablecer tu directorio de trabajo a este commit así:

git reset --hard

Si estás satisfecho con el resultado, en algún momento necesitarás publicar tu versión del repositorio en un repositorio remoto. No olvides especificar claramente la rama remota al hacerlo.

git push --force origin master

Por favor, ten en cuenta que estamos usando git push --force. Es poco probable que quieras hacer esto a menudo, pero tenemos un caso muy específico con un usuario del repositorio que además entiende lo que está haciendo.

Comenzando a trabajar

Situaciones típicas en la integración continua

Empezaremos a elaborar nuestra lista de pasos de CI. Normalmente comienzas este paso extrayendo la última versión del código del repositorio remoto, pero aún no tenemos un repositorio local, así que en su lugar lo clonamos desde el remoto.

️ Tarea: actualiza el repositorio local, crea una rama de master, comienza a trabajar

  1. Clona el repositorio del curso desde <URL репозитория>.
  2. Ejecute npm install en el directorio del repositorio del curso; lo necesitamos para instalar Jest, que utilizamos para ejecutar pruebas.
  3. Crea una rama y llámala feature. Cambia a esta rama.
  4. Agrega código de prueba a ci.test.js entre los comentarios pidiendo hacerlo.

    it('1. extraer el último código', () => {
      expect(/.*pull.*/ig.test(fileContents)).toBe(true);
    });
    
    it('2. agregar commits', () => {
      expect(/.*commit.*/ig.test(fileContents)).toBe(true);
    });
    
    it('3. hacer push a la rama remota con el mismo nombre', () => {
      expect(/.*push.*/ig.test(fileContents)).toBe(true);
    });
    
    it('4. crear una solicitud de extracción y continuar trabajando', () => {
      expect(/.*pulls+request.*/ig.test(fileContents)).toBe(true);
    });

  5. Agrega el texto con los primeros 4 pasos al archivo ci.md.
    1. Extraer el código más reciente. Crear una rama desde `master`. Comienza a trabajar.   
    2. Crear commits en tu nueva rama. Compila y prueba localmente.  
    ¿Pasó? Ve al siguiente paso. ¿Falló? Corrige errores o pruebas y vuelve a intentarlo.  
    3. Haz push a tu repositorio remoto o rama remota.  
    4. Crea una solicitud de extracción. Discute los cambios, agrega más commits  
    a medida que continua la discusión. Haz que las pruebas pasen en la rama de características.  

    Comandos

# Клонируйте репозиторий курса
git clone <repository URL>
cd <repository name>

# Выполните npm install в каталоге репозитория курса; он установит Jest, который мы используем для запуска тестов.
npm install

# Создайте ветку и назовите ее feature. Переключитесь на эту в ветку.
git checkout -b feature

# Отредактируйте ci.test.js как описано выше.
# Отредактируйте ci.md как описано выше

Crea commits en la nueva rama, realiza la compilación y prueba localmente

Vamos a configurar las pruebas para que se ejecuten antes del commit, y luego hacer commit del código.

Escenarios típicos cuando las pruebas se ejecutan automáticamente

  • Localmente:
    • Constantemente o en respuesta a cambios relevantes en el código;
    • Al guardar (para lenguajes interpretados o compilados JIT);
    • Al compilar (cuando se requiere compilación);
    • Al hacer commit;
    • Al publicar en un repositorio compartido.

  • En el servidor de compilación o en el entorno de compilación:
    • Cuando el código se publica en una rama / repositorio personal.
    • El código se prueba en esta rama.
    • Se prueba el resultado de la fusión potencial (usualmente con master).
    • Como etapa de integración continua / canal de entrega continua

Por lo general, cuanto más rápido se ejecute un conjunto de pruebas, más a menudo podrá permitirle ejecutarlo. Una distribución típica por etapas podría verse así.

  • Pruebas de unidad rápidas - al compilar, en el canal CI
  • Pruebas de unidad lentas, pruebas de componente rápidas e integraciones - al hacer commit, en el canal CI
  • Pruebas de componente e integraciones lentas - en el canal CI
  • Pruebas de seguridad, de carga y otras pruebas prolongadas o costosas - en los canales CI/CD, pero solo en ciertos modos / etapas / canales de construcción, por ejemplo, al preparar un candidato a lanzamiento o al ejecutar manualmente.

️ Tarea

Propongo primero ejecutar las pruebas manualmente utilizando el comando npm test. Después de esto, vamos a añadir un git hook para ejecutar nuestras pruebas al hacer commit. Hay un pequeño inconveniente: los git hooks no se consideran parte del repositorio y, por lo tanto, no se pueden clonar desde GitHub junto con los otros materiales del curso. Para instalar el hook, debe ejecutar install_hook.sh o copiar el archivo repo/hooks/pre-commit en el directorio local .git/hooks/.
Al hacer commit verá que las pruebas se ejecutan y verifican si ciertas palabras clave están presentes en la lista.

  1. Ejecute las pruebas manualmente ejecutando el comando npm test en la carpeta del repositorio de su curso. Asegúrese de que las pruebas se hayan ejecutado.
  2. Configure el hook para hacer commit (pre-commit hook), ejecutando install_hook.sh.
  3. Haga commit de los cambios en su repositorio local.
  4. Asegúrese de que las pruebas se ejecuten antes de hacer commit.

Su repositorio debería verse así después de realizar estas acciones.
Situaciones típicas en la integración continua

Comandos

# Установите pre-commit hook выполнив install_hook.sh.  

# Закоммитьте изменения в локальный репозиторий. Используйте "Add first CI steps" в качестве сообщения при коммите.
git add ci.md ci.test.js
git commit -m "Add first CI steps"

# Убедитесь, что тесты запускаются перед коммитом.  

Publique el código en un repositorio remoto o en una rama remota

Después de trabajar localmente, los desarrolladores generalmente hacen que su código sea público para que se pueda integrar en el conjunto común. Con GitHub, esto se logra usualmente publicando el trabajo ya sea en una copia personal del repositorio (fork), o en una rama personal.

  • Al utilizar forks, el desarrollador clona un repositorio remoto compartido, creando una copia remota personal conocida como fork. Después, clona este repositorio personal para trabajar en él localmente. Cuando termina su trabajo y crea commits, los coloca en su fork, donde son accesibles para otros y pueden integrarse en el repositorio compartido. Este enfoque se usa comúnmente en proyectos de código abierto en GitHub. También se utiliza en mi curso avanzado [Team Work and CI with Git]http://devops.redpill.solutions/).
  • Otro enfoque es utilizar solo un repositorio remoto y considerar solo la rama master del repositorio compartido como "protegida". En este escenario, los desarrolladores individuales publican su código en ramas del repositorio remoto para que otros puedan revisarlo, y si todo está en orden, fusionarlo con master el repositorio compartido.

En este curso en particular, usaremos un flujo de trabajo basado en ramas.

Publiquemos nuestro código.

️ Tarea

  • Publica los cambios en una rama remota con el mismo nombre que tu rama de trabajo

Comandos

git push --set-upstream origin feature

Crea un pull request

Crea un pull request titulado Revisión de pasos. Establece feature como "rama cabecera" y master como "rama base".

Asegúrate de haber establecido master en su el fork del repositorio como "rama base"; no responderé a las solicitudes de cambios en el repositorio con materiales del curso.

En la jerga de GitHub, "rama base" es la rama sobre la que fundamentas tu trabajo, y "rama cabecera" es la rama que contiene los cambios propuestos.

Discute los cambios, añade nuevos commits a medida que avanzas en la discusión.

El pull request (PR)

El pull request (PR) es una forma de discutir y documentar el código, así como de realizar revisiones de código. Los pull requests reciben su nombre de la forma común de integrar cambios individuales en el código común. Típicamente, una persona clona el repositorio remoto oficial del proyecto y trabaja en el código localmente. Luego, coloca su código en su repositorio remoto personal y solicita a los responsables del repositorio oficial que integrenpull) su código en sus repositorios locales, donde lo revisan y, posiblemente, lo integranmerge) . Este concepto es conocido también por otros nombres, como merge request.

En realidad, no es necesario utilizar la función de pull request de GitHub o de plataformas similares. Los equipos de desarrollo pueden utilizar otras formas de comunicación, incluidas conversaciones cara a cara, llamadas de voz o correos electrónicos, pero aún hay varias razones para utilizar pull requests en un estilo de discusión en el foro. Aquí hay algunas de ellas:

  • discusiones organizadas relacionadas con cambios específicos en el código;
  • como un lugar para revisar comentarios sobre trabajo incompleto tanto de pruebas automáticas como de colegas;
  • formalización de revisiones de código;
  • para que más tarde se pueda averiguar las razones y consideraciones detrás de determinado fragmento de código.

Normalmente, creas un pull request cuando necesitas discutir algo o recibir comentarios. Por ejemplo, si trabajas en una función que se puede implementar de varias maneras, puedes crear un cambio proposed aún antes de escribir la primera línea de código, para compartir tus ideas y discutir tus planes con los coautores. Si el trabajo es más simple, el pull request se abre una vez que algo ya está hecho, registrado y puede ser discutido. En algunos escenarios, puedes abrir un PR solo por razones de control de calidad: para ejecutar pruebas automáticas o iniciar una revisión de código. Sea lo que decidas, no olvides @mencionar a las personas cuya aprobación necesitas en tu pull request.

Normalmente, al crear un PR haces lo siguiente.

  • Indicas qué propones cambiar y dónde.
  • Escribes una descripción que explique el propósito de los cambios. Puedes querer:
    • agregar algo importante que no sea obvio del código, o algo útil para entender el contexto, como #bugs y números de commits relevantes;
    • @mencionar a todos con quienes deseas comenzar a trabajar juntos, o puedes @mencionarlos en los comentarios más tarde;
    • pedir ayuda a colegas con algo o revisar algo específico.

Después de que abras un PR, se ejecutan las pruebas configuradas para esos casos. En nuestro caso, será el mismo conjunto de pruebas que ejecutamos localmente, pero en un proyecto real puede haber pruebas y verificaciones adicionales.

Por favor, espere mientras se completan las pruebas. Puede ver el estado de las pruebas en la parte inferior de la discusión del PR en la interfaz de GitHub. Continúe cuando las pruebas se hayan completado.

️ Agregue una nota sobre la aleatoriedad de la lista de pasos de CI

La lista utilizada en este curso es aleatoria y subjetiva, debemos agregar una nota al respecto.

️ Tarea: crear un pull request para esta anotación

  1. auth0 master.
  2. Cree una rama llamada bugfix.
  3. Agregue el texto de la anotación al final del archivo ci.md.
    > **El flujo de trabajo de GitHub** a veces se usa como un apodo para referirse a un tipo de desarrollo basado en trunk cuando el código se despliega directamente desde ramas de características. Esta lista es solo una interpretación que utilizo en mis [cursos de DevOps](http://redpill.solutions). El tutorial oficial está [aquí](https://guides.github.com/introduction/flow/).
  4. Confirme los cambios.
  5. Publique la rama bugfix en el repositorio remoto.
  6. Cree un pull request llamado Agregando una anotación a la rama principal bugfix y a la rama basemaster.

Asegúrate de haber establecido master en su el fork del repositorio como "rama base"; no responderé a las solicitudes de cambios en el repositorio con materiales del curso.

Así es como debe verse su repositorio.
Situaciones típicas en la integración continua

Comandos

# Переключитесь на ветку master. Создайте ветку bugfix.
git checkout master

# Создайте ветку bugfix-remark.
git checkout -b bugfix

# Добавьте текст примечания внизу ci.md.

# Закоммитьте изменения
git add ci.md
git commit -m "Add a remark about the list being opinionated"

# Опубликуйте ветку bugfix в удалённый репозиторий.
git push --set-upstream origin bugfix

# Создайте pull request при помощи интерфейса GitHub как описано выше

Apruebe el pull request "Agregando una anotación"

️ Tarea

  1. Cree el pull request.
  2. Haga clic en "Fusionar pull request".
  3. Haga clic en "Confirmar fusión".
  4. Haga clic en "Eliminar rama", ya no la necesitamos.

Este es el diagrama de los commits después de la fusión.
Situaciones típicas en la integración continua

️ Continúe trabajando y agregando pruebas.

Colaborar en un pull request a menudo genera la necesidad de trabajo adicional. Normalmente es el resultado de una revisión de código o discusión, pero en nuestro curso pretendemos simular esto, agregando nuevos elementos a nuestra lista de pasos de CI.

En la integración continua, generalmente se aplica cierta cobertura de pruebas. Los requisitos de cobertura de pruebas varían y normalmente se encuentran en un documento titulado algo así como "guía para autores" (contribution guidelines). Lo haremos simple y agregaremos una prueba para cada línea en nuestra lista de verificación.

Al realizar tareas, primero intente confirmar las pruebas. Si configuró correctamente el gancho pre-commit anteriormente, la prueba que se acaba de agregar se ejecutará, no pasará y no se confirmará nada. Tenga en cuenta: así es como sabremos que nuestras pruebas realmente verifican algo. Curiosamente, si hubiéramos comenzado con el código antes de las pruebas, pasar las pruebas podría significar que el código funciona como se esperaba o que las pruebas en realidad no verifican nada. Además, si no hubiéramos escrito pruebas en primer lugar, podríamos olvidarlas por completo, ya que nada nos recordaría acerca de ellas.

Desarrollo guiado por pruebas (TDD)

TDD recomienda escribir pruebas antes del código. El proceso habitual de trabajo utilizando TDD es así.

  1. Agrega una prueba.
  2. Ejecuta todas las pruebas y asegúrate de que la nueva prueba no se pase con éxito.
  3. Escribe el código.
  4. Ejecuta las pruebas y asegúrate de que todas las pruebas se pasen con éxito.
  5. Refactoriza el código.
  6. Repite.

Dado que los resultados de las pruebas que no se han pasado con éxito se muestran generalmente en rojo y los que se han pasado con éxito en verde, el ciclo también se conoce como "rojo-verde-refactorizar".

️ Tarea

Primero intenta confirmar las pruebas y hacer que fallen, luego agrega y confirma el texto de la lista de pasos de CI. Verás que las pruebas se pasan ("verdes").
Luego publica el nuevo código en un repositorio remoto y observa cómo se ejecutan las pruebas en la interfaz de GitHub en la parte inferior de la discusión de la solicitud de extracción y se actualiza el estado del PR.

  1. auth0 feature.
  2. Agrega estas pruebas a ci.test.js después de la última llamada it (...);.

    it('5. Fusionar/rebase commits desde master. Hacer que las pruebas pasen en el resultado de la fusión.', () => {
      expect(/.*merge.*commits.*tests+pass.*/ig.test(fileContents)).toBe(true);
    });
    
    it('6. Desplegar desde la rama de características a producción.', () => {
      expect(/.*Deploy.*to+production.*/ig.test(fileContents)).toBe(true);
    });
    
    it('7. Si todo está bien en producción durante algún tiempo, fusionar cambios a master.', () => {
      expect(/.*merge.*to+master.*/ig.test(fileContents)).toBe(true);
    });

  3. Intenta confirmar las pruebas. Si gancho pre-commit el gancho está configurado, el intento de confirmación fallará.
  4. Luego agrega este texto a ci.md.
    5. Fusionar/rebase commits desde master. Hacer que las pruebas pasen en el resultado de la fusión.  
    6. Desplegar desde la rama de características con un bug encubierto a producción.
    7. Si todo está bien en producción durante algún tiempo, fusionar cambios a master. 
  5. Realiza y confirma los cambios localmente.
  6. Publica los cambios en la rama feature.

Ahora deberías tener algo como esto
Situaciones típicas en la integración continua

Comandos


# Переключительна ветку feature
git checkout feature

# Добавить тесты в ci.test.js как описано выше

# Добавьте в индекс ci.test.js чтобы позже закоммитить
git add ci.test.js

# Попытайтесь закоммитить тесты. Если pre-commit hook установлены, коммит не произойдёт.
git commit

# Теперь добавьте текст в ci.md как описано выше

# Внесите изменения и закоммитьте их
git add ci.md
git commit -m "Add the remaining CI steps"

# Опубликуйте изменения в ветку feature
git push

Conflicto de fusión

Ve a la solicitud de fusión Revisión de pasos.

A pesar de que no hicimos nada malo y las pruebas para nuestro código pasaron con éxito, aún no podemos fusionar la rama. feature y master. Esto se debe a que otra rama bugfix se ha fusionado con master mientras trabajábamos en este PR.
Esto crea una situación en la que la rama remota master tiene una versión más nueva que la base que utilizamos para nuestra rama. feature. Debido a esto, no podemos simplemente retroceder a HEAD master hasta el final de la rama. feature. En esta situación, necesitamos fusionar o aplicar commits feature encima. master. GitHub en realidad puede realizar fusiones automáticas si no hay conflictos. Lamentablemente, en nuestra situación ambas ramas tienen cambios en conflicto en el archivo. ci.md. Esta situación se conoce como conflicto de fusión (merge conflict), y necesitamos resolverla manualmente.

Fusión o rebase

Fusionar

  • Crea un commit de fusión adicional (merge commit) y conserva el historial de trabajo.
    • Conserva los commits originales de las ramas con las marcas de tiempo y autores originales.
    • Conserva los SHA de los commits y los enlaces a ellos en las discusiones de solicitudes de cambios.
  • Requiere resolución de conflictos una sola vez.
  • Hace que el historial sea no lineal.
    • El historial puede ser difícil de leer debido a la gran cantidad de ramas (se parece a un cable IDE).
    • Complica la depuración automática, por ejemplo, hace que git bisect sea menos útil: solo encontrará el commit de fusión.

Rebase

  • Reproduce los commits de la rama actual sobre la base uno por uno.
    • Se forman nuevos commits con nuevos SHA, como resultado los commits en GitHub se relacionan con las solicitudes de extracción originales, pero no con los comentarios correspondientes.
    • Los commits pueden ser recombinados y modificados en el proceso o incluso fusionados en uno solo.
  • Puede ser necesario resolver varios conflictos.
  • Permite mantener un historial lineal.
    • El historial puede ser más fácil de leer, siempre que no sea demasiado largo sin razones razonables para ello.
    • La depuración automática y la resolución de problemas son algo más simples: permite que git bisect, los retrocesos automáticos sean más claros y predecibles.
  • Se requiere la publicación de la rama con los commits trasladados con la bandera --force al usarla con solicitudes de cambios.

Normalmente, los equipos acuerdan usar siempre la misma estrategia cuando necesitan fusionar cambios. Puede ser una fusión "limpia" o una aplicación "limpia" de commits encima o algo intermedio, como realizar la aplicación de commits en modo interactivo (git rebase -i) localmente para ramas no publicadas en el repositorio compartido, pero fusión (merge) para ramas "públicas".

Aquí utilizaremos la fusión.

️ Tarea

  1. Asegúrese de que el código en la rama local master esté actualizado desde el repositorio remoto.
  2. auth0 feature.
  3. Inicie la fusión con la rama master. Se notificará un conflicto de fusión relacionado con los cambios en conflicto en. ci.md.
  4. Resuelva el conflicto de manera que se mantenga tanto nuestra lista de pasos de CI como la observación sobre ella.
  5. Publique el commit de fusión en la rama remota. feature.
  6. Verifique el estado del pull request en la interfaz de usuario de GitHub, espere a que se resuelva la fusión.

Comandos

# Убедитесь, что код в локальное ветке `master` обновлён из удалённого репозитория.
git checkout master
git pull

# Переключитесь на ветку feature
git checkout feature

# Инициируйте слияние с веткой master 
git merge master

# A merge conflict related to concurrent changes to ci.md will be reported
# => Auto-merging ci.md
#    CONFLICT (content): Merge conflict in ci.md
#    Automatic merge failed; fix conflicts and then commit the result.

# Разрешите конфликт так, чтобы и наш список шагов CI, и замечание о нем остались в тексте.
# отредактируйте ci.md чтоб он не содержал маркеров конфликта слияния
git add ci.md
git merge --continue
# при коммите можете оставить сообщение по умолчанию

# Опубликуйте коммит слияния в удаленную ветку feature.
git push

# Проверьте статус запроса на изменения в пользовательском интерфейсе GitHub, дождитесь пока слияние не будет разрешено.

¡Buen trabajo!

Has terminado de trabajar con la lista, y ahora necesitas aprobar el pull request en master.

️ Tarea: Aprobación del pull request "Revisión de pasos"

  1. Abre el pull request.
  2. Haga clic en "Fusionar pull request".
  3. Haga clic en "Confirmar fusión".
  4. Haz clic en "Eliminar rama", ya que no la necesitamos más.

Este es tu repositorio en este momento.
Situaciones típicas en la integración continua

Error en producción.

Se dice que "las pruebas se pueden utilizar para demostrar la existencia de errores, pero nunca para mostrar su ausencia". Aunque teníamos pruebas y no nos mostraron errores, un error astuto se ha colado en producción.

En un escenario como este, necesitamos tener en cuenta:

  • lo que está desplegado en producción;
  • el código en la rama master con el error, desde el cual los desarrolladores pueden comenzar un nuevo trabajo.

¿Retroceder o corregir en la siguiente versión?

"Retroceder" (rolling back) es desplegar una versión anterior que se sabe que es correcta en el entorno de producción y revertir commits que contienen errores. "Corregir en la siguiente versión" (fixing forward) es agregar una corrección en master y desplegar una nueva versión lo más pronto posible. Dado que las API y los esquemas de bases de datos cambian a medida que se despliega el código en un entorno de producción, en un entorno de entrega continua y con buena cobertura de pruebas, el retroceso tiende a ser mucho más complejo y arriesgado que corregir en la siguiente versión.

Dado que retroceder no conlleva ningún riesgo en nuestro caso, seguiremos este camino, ya que nos permite

  • corregir el error en producción lo antes posible;
  • hacer que el código en master sea inmediatamente apto para comenzar un nuevo trabajo.

️ Tarea

  1. auth0 master localmente.
  2. Actualice su repositorio local desde el repositorio remoto.
  3. Revocar el commit de fusión del PR. Revisión de pasos en master.
  4. Publicar cambios en el repositorio remoto.

Esta es la historia del repositorio con el commit de fusión revocado.
Situaciones típicas en la integración continua

Comandos

# Переключитесь на ветку master.
git checkout master

# Обновите локальный репозиторий из удалённого репозитория.
git pull

# Отмените коммит слияния PR Steps review в master.
# Мы отменяем коммит слияния, поэтому нам нужно выбрать ветку истории, которую мы захотим оставить
git show HEAD

# предположим, что коммит, который был последним в ветке master до слияния, был отображён предыдущей командой первым
git revert HEAD -m 1
# можете не менять сообщения коммитов

# Опубликуйте изменения в удалённый репозиторий
git push

️ Autoevaluación

Asegúrate de que ci.md ya no contiene el texto "sneaky bug" después de revocar el commit de fusión.

Corrija la lista de pasos de CI y devuélvala a master.

Hemos revocado completamente el commit de fusión de la rama feature. La buena noticia es que ahora no tenemos errores en masterLa mala noticia es que también ha desaparecido nuestra valiosa lista de pasos para la integración continua. Así que, idealmente, necesitamos aplicar una corrección a los commits de feature y devolverlos a master junto con la corrección.

Podemos abordar la tarea de diferentes maneras:

  • revertir el commit que revierte la fusión feature con master;
  • mover los commits de la antigua feature.

Diferentes equipos de desarrolladores utilizan distintos enfoques en este caso; nosotros moveremos los commits útiles a una rama separada y crearemos una solicitud de extracción para esta nueva rama.

️ Tarea

  1. Crea una rama llamada feature-fix y cámbiate a ella.
  2. Mueve todos los commits de la antigua rama feature a la nueva rama. Resuelve los conflictos de fusión que surgieron al moverlos.

    Situaciones típicas en la integración continua

  3. Agrega una prueba de regresión en ci.test.js:

    it('does not contain the sneaky bug', () => {
    expect( /.*sneakys+bug.* /gi.test(fileContents)).toBe(false);
    });

  4. Ejecuta las pruebas localmente para asegurarte de que no terminen exitosamente.
  5. Elimina el texto " with a sneaky bug" de ci.md.
  6. Agrega al índice los cambios de las pruebas y los cambios en la lista de pasos y confírmalos.
  7. Publica la rama en el repositorio remoto.

El resultado debería ser algo como
Situaciones típicas en la integración continua

Comandos

# Создайте ветку под названием feature-fix и переключитесь на нее.
git checkout -b feature-fix

# Перенесите все коммиты из бывшей ветки feature в новую ветку. Разрешите конфликты слияния, которые возникли при переносе.
# используйте историю чтобы узнать хэши коммитов:
# - предшествующего коммиту с первой частью списка: C0
# - добавляющего последние элементы списка: C2
git log --oneline --graph
git cherry-pick C0..C2
# разрешите конфликты слияния
# - отредактируйте ci.md и/или ci.test.js
# - добавьте файлы в индекс
# - выполните "git cherry-pick --continue", можете не менять сообщение коммита

# Добавьте регрессионный тест в ci.test.js
# Запустите тесты локально, чтобы убедиться, что они не завершаются успешно.

# Удалите текст " with a sneaky bug" в ci.md.

# Добавьте в индекс изменения тестов и в списке шагов и закоммитьте их.
git add ci.md ci.test.js
git commit -m "Fix the bug in steps list"

# Опубликуйте ветку в удалённый репозиторий.
git push --set-upstream origin feature-fix

Cree el pull request.

Crea un pull request titulado Fixing the feature. Establece feature-fix como "head branch", y master como "rama base".
Por favor, espera a que finalicen las pruebas. Puedes ver el estado de las pruebas en la parte inferior de la discusión del PR.

Asegúrate de haber establecido master en su el fork del repositorio como "rama base"; no responderé a las solicitudes de cambios en el repositorio con materiales del curso.

Aprueba la solicitud de extracción "Fixing the feature"

¡Gracias por la corrección! Por favor, aprueba los cambios en master de la solicitud de extracción.

️ Tarea

  1. Haga clic en "Fusionar pull request".
  2. Haga clic en "Confirmar fusión".
  3. Haz clic en "Eliminar rama", ya que no la necesitamos más.

Esto es lo que deberías tener en este momento
Situaciones típicas en la integración continua

¡Felicidades!

Has realizado todas las acciones que las personas suelen llevar a cabo en el proceso de integración continua.

Si notas algún problema con el curso o sabes cómo mejorarlo, crea un issue en el repositorio con los materiales del curso. Este curso también tiene una versión interactiva que utiliza GitHub Learning Lab como plataforma.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster