{"id":93885,"date":"2020-09-10T19:42:23","date_gmt":"2020-09-10T17:42:23","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov"},"modified":"2020-09-10T19:42:23","modified_gmt":"2020-09-10T17:42:23","slug":"continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","title":{"rendered":"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/ed8a32ae63b8dccfc8b4893ab27f1527.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Discutamos por qu\u00e9 las herramientas CI y CI son cosas completamente diferentes.<\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 problema pretende resolver CI, de d\u00f3nde surgi\u00f3 la idea, cu\u00e1les son las \u00faltimas evidencias de que funciona, y c\u00f3mo saber si usted tiene realmente pr\u00e1ctica y no solo un Jenkins instalado?<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>La idea de hacer una presentaci\u00f3n sobre Continuous Integration surgi\u00f3 hace un a\u00f1o, cuando estuve en entrevistas buscando trabajo. Habl\u00e9 con 10-15 empresas, de las cuales solo una pudo responder claramente qu\u00e9 es CI y explicar c\u00f3mo se dieron cuenta de que no la ten\u00edan. Las dem\u00e1s dec\u00edan tonter\u00edas confusas sobre Jenkins \ud83d\ude42. Bueno, tenemos Jenkins, hace compilaciones, \u00a1CI! En la presentaci\u00f3n intentar\u00e9 explicar qu\u00e9 es realmente Continuous Integration y por qu\u00e9 Jenkins y herramientas similares tienen una relaci\u00f3n muy d\u00e9bil con eso.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/a57813a652c0d788e5a927dc8a7130ba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y as\u00ed, \u00bfqu\u00e9 suele venir a la mente al escuchar CI? A la mayor\u00eda de la gente le viene a la mente Jenkins, GitLab CI, Travis, etc.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c9799c11ba7bb7bbdb2048c2f314b22a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Incluso si lo buscamos en Google, nos mostrar\u00e1n estas herramientas.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/028ef088b28b73e7905b1666d9d53d1b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si preguntamos a los conocidos, justo despu\u00e9s de enumerar las herramientas, les contar\u00e1n que CI es cuando en un Pull Request se realizan compilaciones y pruebas en el commit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/f37ba8f985c10900f669540e063c5e43.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Continuous Integration no se trata de herramientas, ni de compilaciones con pruebas en la rama. Continuous Integration es la pr\u00e1ctica de integrar muy frecuentemente nuevo c\u00f3digo y para su aplicaci\u00f3n no es necesario construir Jenkins, GitLab, etc.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c3a12b4a875050550b42714607e787c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Antes de que analicemos c\u00f3mo se ve un CI completo, primero sumerg\u00e1monos en el contexto de las personas que lo idearon y sintamos el dolor que intentaron resolver.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/2ab9c0f4dba2887fed5744c8b021b424.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y enfrentaron el problema de la colaboraci\u00f3n en equipo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/11a5f3b1075f8b8d0f169fe07adf6c91.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Miremos ejemplos de las dificultades que enfrentan los desarrolladores en el trabajo en equipo. Supongamos que tenemos un proyecto, la rama master en git y dos desarrolladores.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/8138a52376e87239ff5f7b0af5cd8fee.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y comenzaron a trabajar como todos est\u00e1n acostumbrados a hacerlo. Tomaron una tarea en Jira, crearon una rama feature, est\u00e1n escribiendo c\u00f3digo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/54720c40d9bbd9631b411a2a26c4083f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uno termin\u00f3 la funci\u00f3n m\u00e1s r\u00e1pido y la fusion\u00f3 en master.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/4593dc3cf33a44bf3a4d8166be9bc5da.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El otro necesit\u00f3 m\u00e1s tiempo, se fusion\u00f3 m\u00e1s tarde y recibi\u00f3 un conflicto. Ahora, en lugar de escribir las funciones necesarias para el negocio, el desarrollador gasta su tiempo y esfuerzo resolviendo conflictos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c947601fb1dd3b3dd64bac455dc6691a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cuanto m\u00e1s complicado es combinar tu caracter\u00edstica con el maestro com\u00fan, m\u00e1s tiempo pasamos en ello. Y este es un ejemplo bastante simple. Este es un caso donde solo hay 2 desarrolladores. Imagina si hay 10, 15 o 100 personas en la empresa escribiendo en un solo repositorio. Te volver\u00e1s loco tratando de resolver todos esos conflictos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/16c6b8b51ae462f1e0acb966a93c0ae5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hay un caso un poco diferente. Tenemos un maestro y varios desarrolladores que est\u00e1n trabajando en algo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/21b78ad8d0cb7cb5bded6ef9d49707c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Crearon una rama cada uno.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/b85d8aa0080f08c1ad8ad83f3a9ab084.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uno se fusion\u00f3, todo bien, entreg\u00f3 la tarea.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/e96d4fd52c39089e3377ed85adeeb591.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El segundo desarrollador, mientras tanto, entreg\u00f3 su tarea. Supongamos que la envi\u00f3 para revisi\u00f3n. En muchas empresas existe la pr\u00e1ctica de la revisi\u00f3n. Por un lado, es una pr\u00e1ctica buena y \u00fatil, pero por otro, nos frena en muchos aspectos. No profundizaremos en ello, pero aqu\u00ed hay un gran ejemplo de a d\u00f3nde puede llevar una historia torcida con la revisi\u00f3n. Entregaste un pull request para revisi\u00f3n. El desarrollador ya no tiene nada m\u00e1s que hacer. \u00bfQu\u00e9 empieza a hacer? Comienza a tomar otras tareas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/7b8e121be99432606056acf11e20f518.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Durante ese tiempo, el segundo desarrollador hizo algo m\u00e1s. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/ceaa5ba5b3b5014fad527362f5794e94.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>El primero complet\u00f3 la tercera tarea. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/9c27663e63bb9489ecffc5a1f73abb87.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Y despu\u00e9s de un tiempo prolongado, su revisi\u00f3n fue probada, y \u00e9l intenta fusionarse. \u00bfY qu\u00e9 sucede? Encuentra una gran cantidad de conflictos. \u00bfPor qu\u00e9? Porque mientras su pull request estaba en revisi\u00f3n, el c\u00f3digo ya ha cambiado mucho. <\/p>\n<p><\/p>\n<p>Adem\u00e1s de la historia de los conflictos, hay una historia sobre las comunicaciones. Mientras tu rama est\u00e1 en revisi\u00f3n, esperando, mientras est\u00e1s trabajando durante mucho tiempo en la funcionalidad, dejas de seguir qu\u00e9 m\u00e1s est\u00e1 cambiando en la base de c\u00f3digo de tu servicio. Es posible que lo que ahora est\u00e1s tratando de resolver ya se haya solucionado ayer y podr\u00edas reutilizar alg\u00fan m\u00e9todo. Pero no lo ver\u00e1s, porque siempre trabajas con una rama desactualizada. Y esta rama desactualizada siempre lleva a tener que resolver conflictos de fusi\u00f3n. <\/p>\n<p><\/p>\n<p>Por lo tanto, si trabajamos en equipo, es decir, no una sola persona est\u00e1 metiendo mano en el repositorio, sino unas 5-10 personas, cuanto m\u00e1s tiempo no a\u00f1adimos nuestro c\u00f3digo al maestro, m\u00e1s sufrimos porque al final hay que fusionar algo. Y cuanto m\u00e1s conflictos tengamos, y cuanto m\u00e1s antigua sea la versi\u00f3n con la que trabajamos, m\u00e1s problemas tendremos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/55c070f65a4d3838fb8c02bb9684c76b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hacer algo juntos es doloroso. Siempre nos interrumpimos entre nosotros. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/b914c50aad6f3c9f97edcad7e71ba627.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este problema fue se\u00f1alado hace m\u00e1s de 20 a\u00f1os. La primera menci\u00f3n de la pr\u00e1ctica de la Integraci\u00f3n Continua la encontr\u00e9 en la programaci\u00f3n extrema.<\/p>\n<p><\/p>\n<p>La programaci\u00f3n extrema es el primer marco \u00e1gil. La p\u00e1gina apareci\u00f3 en 1996. La idea era utilizar ciertas pr\u00e1cticas de programaci\u00f3n, planificaci\u00f3n y dem\u00e1s, para que el desarrollo fuera lo m\u00e1s flexible posible, para que pudi\u00e9ramos reaccionar m\u00e1s r\u00e1pidamente a cambios y requisitos de nuestros clientes. Y hace 24 a\u00f1os comenzaron a enfrentarse al hecho de que si haces algo durante mucho tiempo y por tu cuenta, gastas m\u00e1s tiempo en ello debido a los conflictos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/93a80838bdb3b297557dbf2ac7587965.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ahora desglosaremos la expresi\u00f3n \"Integraci\u00f3n Continua\" palabra por palabra. Si traducimos literalmente, queda integraci\u00f3n continua. Pero no est\u00e1 muy claro cu\u00e1n continua es, porque en realidad es bastante intermitente. Y tambi\u00e9n no es tan obvio cu\u00e1n grande es la integraci\u00f3n. <\/p>\n<p><\/p>\n<p>Por eso les traigo ahora citas de la programaci\u00f3n extrema. Y ambos t\u00e9rminos los desglosaremos por separado. <\/p>\n<p><\/p>\n<p>Integraci\u00f3n \u2014 Como ya mencion\u00e9, buscamos que cada ingeniero trabaje con la versi\u00f3n m\u00e1s actual del c\u00f3digo, para que su c\u00f3digo se a\u00f1ada tan a menudo como sea posible a la rama principal, utilizando ramas peque\u00f1as. Porque si son grandes, podemos quedarnos atrapados durante una semana en conflictos de merge. Especialmente si tenemos un ciclo de desarrollo largo tipo waterfall, donde un desarrollador se dedic\u00f3 un mes a crear alguna caracter\u00edstica enorme. En el momento de la integraci\u00f3n, puede quedar atascado durante mucho tiempo. <\/p>\n<p><\/p>\n<p>Integraci\u00f3n es cuando tomamos nuestra rama y la integramos con la principal, la fusionamos. Hay una variante definitiva, donde transbasamos al desarrollador, donde buscamos escribir directamente a la rama principal sin crear ramas innecesarias.<\/p>\n<p><\/p>\n<p>En general, la integraci\u00f3n es tomar tu c\u00f3digo y llevarlo a la rama principal. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/8950103e6a59ed7132ec321ac6abe600.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 se entiende aqu\u00ed por la palabra \u00abcontinuous\u00bb y qu\u00e9 se llama continuidad? La pr\u00e1ctica implica que el desarrollador se esfuerza por integrar su c\u00f3digo lo m\u00e1s r\u00e1pido posible. Ese es su objetivo al realizar cualquier tarea: hacer que su c\u00f3digo aparezca en el maestro lo m\u00e1s r\u00e1pido posible. En un mundo ideal, los desarrolladores lo har\u00edan cada pocas horas. Es decir, tomas una peque\u00f1a tarea, la fusionas en el maestro. Todo est\u00e1 genial. Te esfuerzas por eso. Y hay que hacerlo continuamente. En cuanto haces algo, lo integras inmediatamente en el maestro. <\/p>\n<p><\/p>\n<p>Y el desarrollador que hace algo es responsable de lo que hizo, para que funcione y no rompa nada. Aqu\u00ed es donde suele surgir la historia de las pruebas. Queremos ejecutar algunas pruebas en nuestro commit, en nuestra fusi\u00f3n, para asegurarnos de que funciona. Y aqu\u00ed es donde Jenkins puede ser de ayuda.<\/p>\n<p><\/p>\n<p>Pero con historias como: hagamos que los cambios sean peque\u00f1os, hagamos que las tareas sean peque\u00f1as, hagamos una tarea y tratemos de fusionarla en el maestro de inmediato, aqu\u00ed ning\u00fan Jenkins puede ayudar. Porque Jenkins solo te ayuda a ejecutar pruebas. <\/p>\n<p><\/p>\n<p>Puedes prescindir de ellos. Eso no te perjudicar\u00e1 en absoluto. Porque el objetivo de la pr\u00e1ctica es fusionar lo m\u00e1s a menudo posible, para no perder mucho tiempo en conflictos en el futuro. <\/p>\n<p><\/p>\n<p>Imaginemos que en 2020 por alguna raz\u00f3n no hay internet. Y trabajamos localmente. No tenemos Jenkins. Est\u00e1 bien. A\u00fan puedes crear una rama local. Escribiste alg\u00fan c\u00f3digo en ella. Hiciste la tarea en 3-4 horas. Cambias a maestro, haces un git pull, fusionas tu rama all\u00ed. Listo. Si haces esto a menudo, \u00a1felicitaciones, tienes Integraci\u00f3n Continua!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/1f2117b65994b940edb04e0e119f6e8a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00bfQu\u00e9 evidencias hay en el mundo moderno de que vale la pena invertir esfuerzo en esto? Porque en general es complicado. Si intentas trabajar as\u00ed, te dar\u00e1s cuenta de que tendr\u00e1s que hacer algo de planificaci\u00f3n, tendr\u00e1s que dedicar m\u00e1s tiempo a la descomposici\u00f3n de tareas. Porque si haces un man\u2026 no podr\u00e1s fusionar r\u00e1pido y, por lo tanto, te meter\u00e1s en problemas. La pr\u00e1ctica ya no existir\u00e1. <\/p>\n<p><\/p>\n<p>Y esto ser\u00e1 caro. No se podr\u00e1 trabajar desde ma\u00f1ana con Continuous Integration. Todos ustedes se acostumbrar\u00e1n a descomponer las tareas muy lentamente, se acostumbrar\u00e1n a rehacer la pr\u00e1ctica de revisi\u00f3n, si la tienen. Porque nuestro objetivo es que se integre hoy. Y si hacen la revisi\u00f3n en tres d\u00edas, entonces tienen problemas y no obtienen Continuous Integration. <\/p>\n<p><\/p>\n<p>Pero, \u00bftenemos actualmente algunas pruebas que nos digan que invertir en esta pr\u00e1ctica tiene sentido?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/2026a8f1d72fb05613511e7bab57e8ec.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lo primero que se me ocurre es el State of DevOps. Es un estudio que el equipo ha estado realizando durante 7 a\u00f1os. Ahora lo hacen como una organizaci\u00f3n independiente, pero bajo Google.<\/p>\n<p><\/p>\n<p>Y su investigaci\u00f3n en 2018 mostr\u00f3 una correlaci\u00f3n entre las empresas que intentan usar ramas de corta vida, que se integran r\u00e1pidamente y con frecuencia, y tienen mejores indicadores de rendimiento en TI.<\/p>\n<p><\/p>\n<p>\u00bfCu\u00e1les son esos indicadores? Son 4 m\u00e9tricas que recogen de todas las empresas en sus encuestas: frecuencia de despliegue, tiempo de cambio, tiempo para restaurar el servicio, tasa de fallo en cambios.<\/p>\n<p><\/p>\n<p>Y, en primer lugar, existe esta correlaci\u00f3n; sabemos que las empresas que se fusionan con frecuencia tienen m\u00e9tricas significativamente mejores. Y hay una clasificaci\u00f3n de las empresas en varias categor\u00edas: empresas lentas que producen algo lentamente, de rendimiento medio, de alto rendimiento y la \u00e9lite. La \u00e9lite son Netflix, Amazon, que son superr\u00e1pidos, hacen todo r\u00e1pido, bonito y de calidad.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/4fd98ef48a5cffdd6ae2ceea93dbb0bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La segunda historia, que ocurri\u00f3 hace apenas un mes. En el Technology Radar apareci\u00f3 una nota interesante sobre Gitflow. Gitflow se diferencia de los dem\u00e1s en que sus ramas viven mucho tiempo. Hay ramas de lanzamiento que viven mucho tiempo y ramas de caracter\u00edsticas que tambi\u00e9n viven mucho. Esta pr\u00e1ctica se movi\u00f3 a HOLD en el Technology Radar. \u00bfPor qu\u00e9? Porque las personas se enfrentan a la dificultad de la integraci\u00f3n. <\/p>\n<p><\/p>\n<p>Si tu rama vive mucho tiempo, se estanca, se pudre, comenzamos a gastar m\u00e1s tiempo en hacer cambios en ella. <\/p>\n<p><\/p>\n<p>Y recientemente, el autor de Gitflow dijo que si te esfuerzas por la Integraci\u00f3n Continua, si deseas integrar tan a menudo como sea posible, entonces Gitflow es una mala idea. En un art\u00edculo aparte, mencion\u00f3 que si tienes un backend donde puedes esforzarte en eso, Gitflow es innecesario para ti, porque Gitflow te ralentizar\u00e1 y te generar\u00e1 problemas de integraci\u00f3n. <\/p>\n<p><\/p>\n<p>Esto no significa que Gitflow sea malo y que no debas usarlo. Es adecuado para otros casos. Por ejemplo, cuando necesitas mantener varias versiones de un servicio o aplicaci\u00f3n, es decir, cuando necesitas ofrecer soporte durante un per\u00edodo prolongado. <\/p>\n<p><\/p>\n<p>Pero si hablas con personas que mantienen esos servicios, escuchar\u00e1s mucho dolor sobre c\u00f3mo esta versi\u00f3n fue la 3.2, que fue hace 4 meses, y que no se incluy\u00f3 este arreglo, y ahora, para integrarlo, hay que realizar un mont\u00f3n de cambios. Y as\u00ed est\u00e1n atascados de nuevo, y pasan una semana tratando de fusionar alguna nueva caracter\u00edstica. <\/p>\n<p><\/p>\n<p>Como Alexander Kovalev se\u00f1al\u00f3 correctamente en el chat, la correlaci\u00f3n no es igual a la causalidad. Es as\u00ed. Es decir, no hay una relaci\u00f3n directa que indique que si tienes Integraci\u00f3n Continua, todas las m\u00e9tricas ser\u00e1n excelentes; no es as\u00ed. Pero hay una correlaci\u00f3n positiva, donde si una cosa ocurre, es muy probable que la otra tambi\u00e9n. No es un hecho, pero es probable. Es solo una correlaci\u00f3n. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Integraci\u00f3n Continua como pr\u00e1ctica, no solo Jenkins. Andrei Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/d5fc050550b0e9f86a1fdf85fff32fa5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Parece que ya estamos haciendo algo, parece que ya estamos fusionando, pero \u00bfc\u00f3mo entender que realmente tenemos Integraci\u00f3n Continua, que nos fusionamos con suficiente frecuencia?<\/p>\n<p><\/p>\n<p>Jez Humble es el autor del Handbook, Accelerate, del sitio Continuous Delivery y del libro \"Continuous Delivery\". Propone esta prueba:<\/p>\n<p><\/p>\n<ul>\n<li>El c\u00f3digo del ingeniero llega a master a diario. <\/li>\n<li>Por cada commit, ejecutas pruebas unitarias.<\/li>\n<li>La compilaci\u00f3n en master fall\u00f3, y se repar\u00f3 en aproximadamente 10 minutos.<\/li>\n<\/ul>\n<p><\/p>\n<p>\u00c9l sugiere utilizar esta prueba para asegurarte de que efectivamente est\u00e1s practicando. <\/p>\n<p><\/p>\n<p>Lo \u00faltimo que encuentro un poco discutible. Es decir, si puedes arreglarlo en 10 minutos, entonces tienes Integraci\u00f3n Continua; suena un poco extra\u00f1o, en mi opini\u00f3n, pero tiene sentido. \u00bfPor qu\u00e9? Porque si haces merges con frecuencia, significa que tus cambios son peque\u00f1os. Si un peque\u00f1o cambio hace que tu compilaci\u00f3n master falle, podr\u00e1s encontrar el problema r\u00e1pidamente porque el cambio es peque\u00f1o. Has tenido un peque\u00f1o merge en el que cambiaron 20-30 l\u00edneas. Y, por lo tanto, podr\u00e1s entender r\u00e1pidamente cu\u00e1l fue la causa, porque los cambios son min\u00fasculos, tienes un \u00e1rea de b\u00fasqueda del problema muy reducida. <\/p>\n<p><\/p>\n<p>E incluso si despu\u00e9s del lanzamiento se cae el prod, si tenemos la pr\u00e1ctica de Integraci\u00f3n Continua, es mucho m\u00e1s f\u00e1cil actuar, porque los cambios son peque\u00f1os. S\u00ed, esto afectar\u00e1 la planificaci\u00f3n. Va a ser doloroso. Y, probablemente, lo m\u00e1s dif\u00edcil en esta pr\u00e1ctica es acostumbrarse a descomponer las tareas, es decir, c\u00f3mo hacer algo y completarlo en unas pocas horas y pasar la revisi\u00f3n, si la tienes. La revisi\u00f3n es un dolor aparte. <\/p>\n<p><\/p>\n<p>Las pruebas unitarias son simplemente una herramienta que te ayuda a entender si tu integraci\u00f3n ha salido bien, si realmente no se ha roto nada. En mi opini\u00f3n, esto tampoco es un punto del todo obligatorio, porque el sentido de la pr\u00e1ctica no se basa en esto. <\/p>\n<p><\/p>\n<p>Esto es un breve resumen sobre Integraci\u00f3n Continua. Eso es todo lo que hay en esta pr\u00e1ctica. Estoy listo para las preguntas. <\/p>\n<p><\/p>\n<p>En resumen, solo volver\u00e9 a hacer un repaso:<\/p>\n<p><\/p>\n<ul>\n<li>Integraci\u00f3n Continua no es Jenkins, no es Gitlab.<\/li>\n<li>No es una herramienta, es una pr\u00e1ctica que consiste en hacer merges de nuestro c\u00f3digo en master lo m\u00e1s frecuentemente posible. <\/li>\n<li>Lo hacemos para evitar el gran dolor que surge con los merges en el futuro; es decir, experimentamos un peque\u00f1o dolor ahora para no experimentar uno grande despu\u00e9s. Ese es todo el sentido. <\/li>\n<li>La comunicaci\u00f3n pasa a trav\u00e9s del c\u00f3digo, pero rara vez lo veo; sin embargo, para eso tambi\u00e9n fue dise\u00f1ado.<\/li>\n<\/ul>\n<p><\/p>\n<p><strong>Preguntas<\/strong><\/p>\n<p><\/p>\n<p><em>\u00bfQu\u00e9 hacer con las tareas que no se pueden descomponer?<\/em><\/p>\n<p><\/p>\n<p>Descomponer. \u00bfCu\u00e1l es el problema? \u00bfPuedes dar un ejemplo de que hay una tarea y no se puede descomponer?<\/p>\n<p><\/p>\n<p><em>Hay tareas que no se pueden descomponer en absoluto, por ejemplo, aquellas que requieren una experiencia muy profunda y que realmente pueden tardar un mes en llegar a un resultado razonable.<\/em> <\/p>\n<p><\/p>\n<p>Si te entend\u00ed correctamente, hay una tarea grande y compleja cuyo resultado solo ser\u00e1 visible dentro de un mes?<\/p>\n<p><\/p>\n<p><em>S\u00ed, es correcto. S\u00ed, se podr\u00e1 evaluar el resultado no antes de un mes.<\/em> <\/p>\n<p><\/p>\n<p>Est\u00e1 bien. En general, esto no es un problema. \u00bfPor qu\u00e9? Porque en este caso, cuando hablamos de ramas, no hablamos de una rama con una funci\u00f3n. Las funciones pueden ser grandes y complejas. Pueden involucrar muchos componentes. Y, posiblemente, no podamos completar todo en una sola rama. Eso est\u00e1 bien. Solo necesitamos dividir esta historia. Si la funci\u00f3n no est\u00e1 completamente lista, eso no significa que no se puedan fusionar algunos fragmentos de su c\u00f3digo. Supongamos que has agregado una migraci\u00f3n y dentro de la funci\u00f3n hay algunos pasos. Supongamos que tienes un paso: hacer la migraci\u00f3n, agregar un nuevo m\u00e9todo. Y ya puedes fusionar estas cosas a diario. <\/p>\n<p><\/p>\n<p><em>Est\u00e1 bien. Entonces, \u00bfcu\u00e1l es el sentido de esto?<\/em><\/p>\n<p><\/p>\n<p>\u00bfCu\u00e1l es el sentido de fusionar peque\u00f1as cosas a diario?<\/p>\n<p><\/p>\n<p><em>S\u00ed.<\/em><\/p>\n<p><\/p>\n<p>Si te rompieron algo, lo ves inmediatamente. Tienes un peque\u00f1o fragmento que rompi\u00f3 algo, te resulta m\u00e1s f\u00e1cil solucionarlo. El sentido est\u00e1 en que fusionar un peque\u00f1o fragmento ahora es mucho m\u00e1s f\u00e1cil que fusionar algo grande en unas semanas. Y el tercer sentido es que otros ingenieros trabajar\u00e1n con la versi\u00f3n de c\u00f3digo actual. Ver\u00e1n que se han agregado algunas migraciones aqu\u00ed y que ha aparecido alg\u00fan m\u00e9todo que tambi\u00e9n podr\u00edan querer usar. Todos ver\u00e1n lo que est\u00e1 sucediendo en tu c\u00f3digo. Esta pr\u00e1ctica se realiza precisamente por estas tres razones. <\/p>\n<p><\/p>\n<p><em>Gracias, \u00a1pregunta cerrada!<\/em><\/p>\n<p><\/p>\n<p><em>(Oleg Soroka) \u00bfPuedo agregar algo? Tienes raz\u00f3n, solo quiero a\u00f1adir una frase.<\/em><\/p>\n<p><\/p>\n<p>Bien.<\/p>\n<p><\/p>\n<p><em>Con la Integraci\u00f3n Continua, el c\u00f3digo se fusiona en la rama principal no cuando la funci\u00f3n est\u00e1 completamente lista, sino cuando la construcci\u00f3n ha dejado de romperse. Y puedes comprometerte al maestro tantas veces como quieras al d\u00eda. El segundo aspecto es que si no puedes, por alguna raz\u00f3n, dividir una tarea mensual en tareas de al menos tres d\u00edas, no hablemos de tres horas, significa que tienes un gran problema. Y el hecho de que no tengas Integraci\u00f3n Continua es el menor de esos problemas. Significa que tienes problemas con la arquitectura y las pr\u00e1cticas de ingenier\u00eda est\u00e1n en cero. Porque incluso si se trata de investigaci\u00f3n, en cualquier caso, debe formularse en forma de hip\u00f3tesis o ciclos.<\/em> <\/p>\n<p><\/p>\n<p><em>Hablamos de 4 m\u00e9tricas que distinguen a las empresas exitosas de las rezagadas. A\u00fan hay que alcanzar estas 4 m\u00e9tricas. Si una tarea promedio toma un mes, me concentrar\u00eda primero en esa m\u00e9trica. La reducir\u00eda a 3 d\u00edas. Despu\u00e9s de eso, empezar\u00eda a pensar en Continuous.<\/em><\/p>\n<p><\/p>\n<p>\u00bfEntend\u00ed bien que piensas que, en general, invertir en pr\u00e1cticas de ingenier\u00eda no tiene sentido si cualquier tarea toma un mes?<\/p>\n<p><\/p>\n<p><em>Tienes Continuous Integration. Y hay un tema en el que, en 10 minutos, o corriges el error o lo retrocedes. Imagina que lo implementaste. Y tienes incluso continuous deployment, lo lanzaste en producci\u00f3n y luego te das cuenta de que algo sali\u00f3 mal. Necesitas retroceder, pero ya has migrado la base de datos. La estructura de la base de datos ya est\u00e1 en una versi\u00f3n m\u00e1s reciente, adem\u00e1s, ya ha pasado alguna copia de seguridad, y se han registrado datos all\u00ed.<\/em><\/p>\n<p><\/p>\n<p><em>\u00bfY qu\u00e9 alternativa tienes? Si retrocedes el c\u00f3digo, ya no puede funcionar con esta base de datos actualizada.<\/em><\/p>\n<p><\/p>\n<p>La base avanza solo hacia adelante, s\u00ed. <\/p>\n<p><\/p>\n<p><em>Las personas con malas pr\u00e1cticas de ingenier\u00eda probablemente tampoco leyeron un libro grueso sobre\u2026 \u00bfqu\u00e9 hacer con las copias de seguridad? Si te recuperas de una copia de seguridad, significa que pierdes los datos que se han generado en ese momento. Por ejemplo, trabajaste tres horas con la nueva versi\u00f3n de la base de datos, y los usuarios se registraron all\u00ed. Retrocedes a la copia de seguridad antigua porque con la nueva versi\u00f3n la estructura no funciona, as\u00ed que esos usuarios se pierden. Y est\u00e1n descontentos, se quejan.<\/em><\/p>\n<p><\/p>\n<p><em>Para dominar todo el espectro de pr\u00e1cticas que respaldan la Integraci\u00f3n Continua y la Entrega Continua, no es suficiente con aprender a escribir simplemente\u2026 En primer lugar, pueden llegar a ser muchas y eso ser\u00eda poco pr\u00e1ctico. Adem\u00e1s, hay un mont\u00f3n de otras pr\u00e1cticas como la Cient\u00edfica. Hay una pr\u00e1ctica que GitHub populariz\u00f3 en su momento. Es cuando ejecutas al mismo tiempo el c\u00f3digo antiguo y el nuevo. Es cuando est\u00e1s trabajando en una funci\u00f3n no terminada, pero que puede devolver alg\u00fan valor: ya sea como funci\u00f3n o como API Rest. Ejecutas tanto el c\u00f3digo nuevo como el antiguo y comparas la diferencia entre ellos. Y si hay una diferencia, registras ese evento. De esta manera, sabes que tu nueva caracter\u00edstica est\u00e1 lista para ser implementada sobre la antigua, si no ha habido discrepancias entre los dos durante un tiempo determinado.<\/em> <\/p>\n<p><\/p>\n<p><em>Hay cientos de tales pr\u00e1cticas. Yo sugerir\u00eda comenzar con el desarrollo transbase. No est\u00e1 100 % enfocado en la Integraci\u00f3n Continua, pero las pr\u00e1cticas son las mismas, y una sin la otra no funciona bien.<\/em> <\/p>\n<p><\/p>\n<p>\u00bfHas mencionado el desarrollo transbase como ejemplo de d\u00f3nde se pueden ver las pr\u00e1cticas o est\u00e1s sugiriendo a las personas que empiecen a usar el desarrollo transbase?<\/p>\n<p><\/p>\n<p><em>Mirar, ya que no podr\u00e1n usarlo. Para poder utilizarlo, hay que leer mucho. Y cuando la pregunta de una persona es: \"\u00bfQu\u00e9 hacer con una caracter\u00edstica que toma un mes?\", eso significa que no ha le\u00eddo sobre el desarrollo transbase. Yo no recomendar\u00eda eso por ahora. Sugerir\u00eda concentrarse exclusivamente en el tema de c\u00f3mo descomponer arquitect\u00f3nicamente tareas grandes en tareas m\u00e1s peque\u00f1as. Esa es la esencia de la descomposici\u00f3n.<\/em><\/p>\n<p><\/p>\n<p><em>La descomposici\u00f3n es una de las herramientas del arquitecto. Primero hacemos un an\u00e1lisis, luego la descomposici\u00f3n, despu\u00e9s la s\u00edntesis, y finalmente la integraci\u00f3n. As\u00ed es como todo encaja. Y hay que crecer hacia la Integraci\u00f3n Continua a trav\u00e9s de la descomposici\u00f3n. En la primera etapa surgen preguntas, y ya estamos hablando de la cuarta etapa, es decir, cuanto m\u00e1s frecuente sea la integraci\u00f3n, mejor. A\u00fan es pronto para hacerlo; ser\u00eda bueno primero descomponer tu monolito.<\/em> <\/p>\n<p><\/p>\n<p><em>Es necesario dibujar algunas flechas y rect\u00e1ngulos en alg\u00fan esquema. No puedes decir que ahora voy a mostrar el diagrama arquitect\u00f3nico de una nueva aplicaci\u00f3n y mostrar un solo cuadrado, dentro del cual hay un bot\u00f3n verde para la aplicaci\u00f3n. En cualquier caso, habr\u00e1 m\u00e1s cuadrados y flechas. En cualquier diagrama que he visto, hab\u00eda m\u00e1s de uno. Y la descomposici\u00f3n, incluso a nivel de presentaci\u00f3n gr\u00e1fica, ya se est\u00e1 realizando. Por lo tanto, se pueden hacer rect\u00e1ngulos independientes. Si no, tengo muchas preguntas para el arquitecto.<\/em> <\/p>\n<p><\/p>\n<p>Hay una pregunta del chat: \u00abSi la revisi\u00f3n es obligatoria y dura m\u00e1s de un d\u00eda, \u00bfqu\u00e9 se hace?\u00bb.<\/p>\n<p><\/p>\n<p>Tienes problemas con la pr\u00e1ctica. La revisi\u00f3n no deber\u00eda durar m\u00e1s de un d\u00eda. Esta es la misma historia que la pregunta anterior, solo que un poco m\u00e1s suave. Si la revisi\u00f3n dura un d\u00eda, significa que, probablemente, se trata de una revisi\u00f3n de un cambio muy grande. Por lo tanto, debe hacerse m\u00e1s peque\u00f1a. En el desarrollo de transbase, que Oleg recomend\u00f3, hay una historia llamada revisi\u00f3n continua. La idea es que hacemos solicitudes de extracci\u00f3n lo suficientemente peque\u00f1as intencionadamente, porque buscamos fusionarnos constantemente y en peque\u00f1as cantidades. Y por eso la solicitud de extracci\u00f3n cambia una abstracci\u00f3n o 10 l\u00edneas. Gracias a esto, la revisi\u00f3n nos lleva un par de minutos. <\/p>\n<p><\/p>\n<p>Si la revisi\u00f3n tarda un d\u00eda o m\u00e1s, significa que algo no est\u00e1 bien. En primer lugar, puede que tengas problemas con la arquitectura. O es un gran bloque de c\u00f3digo, de 1000 l\u00edneas, por ejemplo. O tienes una arquitectura tan compleja que la persona no puede entenderla. Este es un problema secundario, pero tambi\u00e9n habr\u00e1 que resolverlo. Tal vez ni siquiera necesites revisi\u00f3n. Tambi\u00e9n hay que pensar en eso. La revisi\u00f3n es esa cosa que te frena. Tiene sus ventajas en general, pero hay que entender por qu\u00e9 lo haces. \u00bfEs para ti una forma r\u00e1pida de transmitir informaci\u00f3n? \u00bfEs para establecer algunos est\u00e1ndares internos? \u00bfPara qu\u00e9? Porque la revisi\u00f3n debe hacerse muy r\u00e1pido o cancelarse por completo. Es como el desarrollo de transbase: una historia muy bonita, pero solo para personas muy maduras. <\/p>\n<p><\/p>\n<p>Con respecto a las 4 m\u00e9tricas, recomendar\u00eda que las quites, para entender a qu\u00e9 conduce. Mirar los n\u00fameros, ver la imagen, cu\u00e1n mal est\u00e1 todo. <\/p>\n<p><\/p>\n<p><em>(Dmitry) Estoy listo para discutir esto contigo. Los n\u00fameros y m\u00e9tricas son geniales, la pr\u00e1ctica es genial. Pero hay que entender si esto es necesario para el negocio. Hay negocios que no necesitan tal velocidad de cambio. Conozco empresas en las que no se pueden hacer cambios cada 15 minutos. Y no porque sean malas. Es un ciclo de vida. Y para implementar la funcionalidad de branches, la funcionalidad de toggle, se requieren conocimientos profundos.<\/em> <\/p>\n<p><\/p>\n<p>Es complicado. Si deseas leer m\u00e1s sobre la historia de la funcionalidad de toggle, te lo recomiendo encarecidamente. <noindex><a rel=\"nofollow\" href=\"https:\/\/trunkbaseddevelopment.com\/\">https:\/\/trunkbaseddevelopment.com\/<\/a><\/noindex>. Y hay un art\u00edculo maravilloso de Martin Fowler sobre las funcionalidades de toggle: sobre los tipos que existen, ciclos de vida, etc. La funcionalidad de toggle es compleja. <\/p>\n<p><\/p>\n<p><em>Y aun as\u00ed no respondiste a la pregunta: \u00ab\u00bfJenkins es necesario o no?\u00bb<\/em><\/p>\n<p><\/p>\n<p>Jenkins no es necesario en ning\u00fan caso, en realidad. Hablando en serio, herramientas como Jenkins o Gitlab te brindar\u00e1n comodidad. Podr\u00e1s ver si la compilaci\u00f3n se realiz\u00f3 o no. Pero no te proporcionar\u00e1n la pr\u00e1ctica. Solo te dar\u00e1n un c\u00edrculo: Ok, no Ok. Y eso, si a\u00fan escribes pruebas, porque si no hay pruebas, es casi in\u00fatil. As\u00ed que es necesario, porque es m\u00e1s conveniente, pero en general se puede vivir sin \u00e9l, no perder\u00e1s mucho. <\/p>\n<p><\/p>\n<p><em>Es decir, si tienes pr\u00e1cticas, \u00bfsignifica que no lo necesitas?<\/em><\/p>\n<p><\/p>\n<p>Correcto. Recomiendo la prueba de Jez Humble. Tengo una relaci\u00f3n ambigua con el \u00faltimo punto. Pero en general, si tienes tres cosas: te fusionas constantemente, ejecutas pruebas en los commits en master y reparas r\u00e1pidamente la compilaci\u00f3n en master, entonces posiblemente no necesites nada m\u00e1s. <\/p>\n<p><\/p>\n<p><em>Mientras esperamos preguntas de los participantes, tengo una pregunta. Hablamos sobre c\u00f3digo de producto. \u00bfHas utilizado esto para c\u00f3digo de infraestructura? \u00bfEs el mismo c\u00f3digo, tiene los mismos principios y el mismo ciclo de vida, o hay otros ciclos de vida y principios? Normalmente, cuando todos hablan sobre Integraci\u00f3n y Desarrollo Continuos, olvidan que tambi\u00e9n existe el c\u00f3digo de infraestructura. Y \u00faltimamente se est\u00e1 utilizando cada vez m\u00e1s. \u00bfDeber\u00edamos llevar todas estas reglas all\u00ed?<\/em><\/p>\n<p><\/p>\n<p>No es solo que debamos, ser\u00eda genial, porque definitivamente simplificar\u00e1 la vida. En cuanto trabajamos con c\u00f3digo, no con scripts en bash, y tenemos c\u00f3digo normal.<\/p>\n<p><\/p>\n<p><em>Espera, espera, el script en bash tambi\u00e9n es c\u00f3digo. No toques a mi viejo amor.<\/em> <\/p>\n<p><\/p>\n<p>Est\u00e1 bien, no voy a pisotear tus recuerdos. Tengo una aversi\u00f3n personal hacia bash. Se rompen de forma poco agradable y siempre asustan. Y a menudo se rompen de manera impredecible, por lo que no me agrada. Pero bien, supongamos que tienes c\u00f3digo en bash. Tal vez realmente no entiendo y hay frameworks decentes para pruebas. Simplemente no estoy al tanto. Y obtenemos los mismos beneficios.<\/p>\n<p><\/p>\n<p>Una vez que trabajamos con infraestructura como c\u00f3digo, obtenemos los mismos problemas que los desarrolladores. Hace unos meses me encontr\u00e9 en una situaci\u00f3n en la que un colega me envi\u00f3 un pull request de 1,000 l\u00edneas en bash. Y te quedas atascado en la revisi\u00f3n durante 4 horas. Los problemas son los mismos. Todav\u00eda es c\u00f3digo. Y a\u00fan es trabajo colaborativo. Nos quedamos atascados con el pull request y lidiamos con los mismos conflictos de fusi\u00f3n del mismo bash, por ejemplo. <\/p>\n<p><\/p>\n<p>Actualmente estoy observando intensamente esta cuesti\u00f3n de la programaci\u00f3n de infraestructura de la manera m\u00e1s hermosa. He incorporado Pulumi a la infraestructura. Esto es programaci\u00f3n en su m\u00e1xima expresi\u00f3n. Es a\u00fan m\u00e1s atractivo, porque tengo todas las posibilidades del lenguaje de programaci\u00f3n, es decir, con las mismas condiciones hice toggles bonitos en un abrir y cerrar de ojos y todo va bien. Es decir, mi cambio ya est\u00e1 en el master. Todos ya lo ven. Otros ingenieros est\u00e1n al tanto. Ya ha influido en algo. Pero no se ha activado para todas las infraestructuras. Se activ\u00f3 para mis entornos de prueba, por ejemplo. Por lo tanto, respondiendo a tu pregunta una vez m\u00e1s, es necesario. Esto, para nosotros como ingenieros que trabajamos con c\u00f3digo, definitivamente facilita la vida. <\/p>\n<p><\/p>\n<p><em>\u00bfAlguien m\u00e1s tiene preguntas?<\/em> <\/p>\n<p><\/p>\n<p>Tengo una pregunta. Quiero continuar la discusi\u00f3n con Oleg. En general, creo que tienes raz\u00f3n, que si una tarea te lleva un mes, entonces tienes un problema con la arquitectura, tienes un problema con el an\u00e1lisis, la descomposici\u00f3n, la planificaci\u00f3n, etc. Pero tengo la sensaci\u00f3n de que si comienzas a tratar de vivir con la Integraci\u00f3n Continua, empezar\u00e1s a corregir los problemas con la planificaci\u00f3n, porque no puedes escapar de eso. <\/p>\n<p><\/p>\n<p><em>(Oleg) S\u00ed, es as\u00ed. En t\u00e9rminos de esfuerzo, esta pr\u00e1ctica es comparable a cualquier otra pr\u00e1ctica seria que cambie la cultura. Lo m\u00e1s dif\u00edcil de superar son los h\u00e1bitos, especialmente los malos h\u00e1bitos. Y si para implementar esta pr\u00e1ctica se requiere un cambio significativo en los h\u00e1bitos de quienes te rodean: desarrolladores, direcci\u00f3n, gerente de producci\u00f3n, entonces te esperan sorpresas.<\/em> <\/p>\n<p><\/p>\n<p><em>\u00bfQu\u00e9 sorpresas pueden haber? Supongamos que decidiste que har\u00e1s m\u00e1s integraciones. Y en la integraci\u00f3n tienes atados algunas cosas, como artefactos. Y en tu empresa, por ejemplo, hay una pol\u00edtica de que cada artefacto debe ser contabilizado de alguna manera en un sistema de almacenamiento de artefactos. Y esto toma un cierto tiempo. La persona necesita marcar que, como gerente de lanzamientos, ha probado este artefacto para su disposici\u00f3n en producci\u00f3n. Si esto toma 5-10-15 minutos, pero al mismo tiempo haces lanzamientos una vez a la semana, entonces gastar media hora una vez a la semana no es un gran impuesto.<\/em> <\/p>\n<p><\/p>\n<p><em>Si realizas Integraci\u00f3n Continua 10 veces al d\u00eda, entonces debes multiplicar 10 veces por 30 minutos. Y esto supera la cantidad de tiempo laboral de ese gerente de lanzamientos. Simplemente se cansa de hacerlo. Hay costos constantes asociados a ciertas pr\u00e1cticas. Y eso es todo.<\/em> <\/p>\n<p><\/p>\n<p><em>Y necesitas o cancelar esta regla, para que ya no te ocupes de tonter\u00edas, es decir, no asignas manualmente un grado de conformidad de algo a algo. Conf\u00edas total y completamente en un conjunto automatizado de pruebas de preparaci\u00f3n.<\/em> <\/p>\n<p><\/p>\n<p><em>Y si necesitas que alguien te d\u00e9 pruebas para que el jefe firme, y no entras en producci\u00f3n sin que Vasya haya dicho que lo permite, etc., toda esta tonter\u00eda se interpone en el camino de las pr\u00e1cticas. Porque si hay actividades relacionadas que son como un impuesto, todo se multiplica por 100. Por lo tanto, el cambio generalmente no es bien recibido por todos. Porque es dif\u00edcil corregir los h\u00e1bitos de la gente.<\/em> <\/p>\n<p><\/p>\n<p><em>Cuando una persona realiza un trabajo habitual, lo hace pr\u00e1cticamente sin pensarlo. Su carga cognitiva es igual a cero. Simplemente se dedica a lo que ya est\u00e1, tiene una lista de verificaci\u00f3n en su cabeza, lo ha hecho mil veces. Y tan pronto como llegas y le dices: 'Vamos a cancelar esta pr\u00e1ctica y a partir del lunes implementaremos una nueva', para \u00e9l se convierte en una carga cognitiva enorme. Y esto afecta a todos de inmediato.<\/em> <\/p>\n<p><\/p>\n<p><em>Por lo tanto, lo m\u00e1s f\u00e1cil, aunque esta es una lujo que no todos pueden permitirse, es siempre hacer exactamente eso, lo siguiente. Si se lanza un nuevo proyecto, por lo general se introducen de inmediato todas las pr\u00e1cticas no probadas en este proyecto. Mientras el proyecto es joven, no estamos asumiendo un gran riesgo. No hay producci\u00f3n, no hay nada que destruir. Por lo tanto, se puede utilizar como pr\u00e1ctica. Este enfoque funciona. Sin embargo, no todas las empresas tienen la oportunidad de iniciar tales proyectos con frecuencia. Aunque esto tambi\u00e9n resulta un poco extra\u00f1o, porque actualmente estamos en plena transformaci\u00f3n digital, todos deber\u00edan lanzar experimentos para seguir el ritmo de la competencia.<\/em> <\/p>\n<p><\/p>\n<p>Aqu\u00ed te enfrentas a que primero debes tener claridad sobre lo que necesitas hacer. El mundo no es perfecto, la producci\u00f3n tampoco es perfecta. <\/p>\n<p><\/p>\n<p><em>S\u00ed, estas cosas est\u00e1n interrelacionadas.<\/em><\/p>\n<p><\/p>\n<p>Las empresas tampoco siempre tienen claridad sobre que necesitan dirigirse hacia eso. <\/p>\n<p><\/p>\n<p><em>Hay situaciones en las que ning\u00fan cambio es posible. Esta es una situaci\u00f3n en la que hay m\u00e1s presi\u00f3n sobre el equipo. El equipo ya est\u00e1 bastante quemado. No tiene tiempo extra para ning\u00fan tipo de experimentos. Desde la ma\u00f1ana hasta la noche est\u00e1n desarrollando caracter\u00edsticas. Y la direcci\u00f3n siempre pide m\u00e1s y m\u00e1s caracter\u00edsticas. Se necesita cada vez m\u00e1s. En tal situaci\u00f3n, no es posible realizar ning\u00fan cambio. Solo se les puede decir al equipo que ma\u00f1ana haremos lo mismo que ayer, solo que necesitamos hacer un poco m\u00e1s de caracter\u00edsticas. No hay transici\u00f3n a ninguna pr\u00e1ctica significativa en este sentido. Esta es una situaci\u00f3n cl\u00e1sica donde no hay tiempo para afilar el hacha, hay que talar \u00e1rboles, as\u00ed que se talan con un hacha desafilada. Aqu\u00ed no hay consejos sencillos.<\/em> <\/p>\n<p><\/p>\n<p><em>(Dmitry) Voy a leer una aclaraci\u00f3n del chat: \u00abPero es necesario tener una amplia cobertura de pruebas a diferentes niveles. \u00bfCu\u00e1nto tiempo se dedica a las pruebas? Es algo costoso, lleva mucho tiempo\u00bb.<\/em><\/p>\n<p><\/p>\n<p><em>(Oleg) Este es un mito cl\u00e1sico. Debe haber suficientes pruebas para que ustedes mismos tengan confianza. La Integraci\u00f3n Continua no es algo donde primero se realizan el 100% de las pruebas y solo luego se comienza a aplicar esta pr\u00e1ctica. La Integraci\u00f3n Continua reduce su carga cognitiva porque cada uno de los cambios que ven con sus propios ojos es tan obvio que pueden entender si va a romper algo o no, incluso sin pruebas. Pueden probarlo r\u00e1pidamente en su mente, porque son cambios peque\u00f1os. Incluso si solo tienen testers manuales, para ellos tambi\u00e9n es m\u00e1s sencillo. Ustedes hacen un despliegue y dicen: 'Mira, \u00bfno se rompi\u00f3 nada?'. Ellos verifican y dicen: 'No, no se rompi\u00f3 nada'. Porque el tester sabe a d\u00f3nde mirar. Tienen un commit relacionado con un fragmento de c\u00f3digo. Y esto se explota hacia un comportamiento espec\u00edfico.<\/em><\/p>\n<p><\/p>\n<p>Aqu\u00ed, por supuesto, has embellecido las cosas. <\/p>\n<p><\/p>\n<p><em>(Dmitry) Aqu\u00ed no estoy de acuerdo. Existe una pr\u00e1ctica: desarrollo a trav\u00e9s de pruebas, que es precisamente lo que salvar\u00e1 de esto.<\/em> <\/p>\n<p><\/p>\n<p><em>(Oleg) A\u00fan no he llegado a eso. La primera ilusi\u00f3n es que hay que escribir el 100% de las pruebas o no se debe hacer nada relacionado con la Integraci\u00f3n Continua. Eso es falso. Son dos pr\u00e1cticas paralelas. Y no dependen entre s\u00ed directamente. Su cobertura de pruebas debe ser \u00f3ptima. \u00d3ptima significa que ustedes mismos est\u00e1n seguros de que la calidad del maestro, que qued\u00f3 despu\u00e9s del commit, les permite presionar el bot\u00f3n 'Deploy' con confianza el viernes por la noche, incluso si han bebido. \u00bfC\u00f3mo logran esto? A trav\u00e9s de revisiones, cobertura y buen monitoreo.<\/em> <\/p>\n<p><\/p>\n<p><em>Un buen monitoreo es indistinguible de las pruebas. Si ejecutan las pruebas una vez en pre producci\u00f3n, solo verifican todos sus escenarios de usuario una vez. Pero si las ejecutan en un ciclo infinito, esto se convierte en su sistema de monitoreo desplegado, que prueba todo de forma continua \u2013 si fall\u00f3 o no. En este caso, la \u00fanica diferencia es si es una vez o muchas veces. Un conjunto muy bueno de pruebas..., ejecutado de forma infinita, es monitoreo. Y el monitoreo correcto debe ser as\u00ed.<\/em> <\/p>\n<p><\/p>\n<p><em>Y por lo tanto, c\u00f3mo exactamente lograr\u00e1n este estado, donde el viernes por la noche despliegan y se van a casa, es otra cuesti\u00f3n. Tal vez simplemente sean un atrevido.<\/em> <\/p>\n<p><\/p>\n<p>Volvamos un poco atr\u00e1s a la Integraci\u00f3n Continua. Nos hemos desviado hacia otra pr\u00e1ctica compleja. <\/p>\n<p><\/p>\n<p><em>Y la segunda ilusi\u00f3n es que, se dice, hay que hacer el MVP r\u00e1pidamente, por lo que no se necesitan pruebas en absoluto. No es del todo as\u00ed. La cuesti\u00f3n es que cuando escribes una historia de usuario para el MVP, puedes desarrollarla de dos maneras: o a la ligera, es decir, escuchas que hay alguna historia de usuario y te pones a codificarla de inmediato, o puedes trabajar con TDD. Y con TDD, como demuestra la pr\u00e1ctica, no se tarda m\u00e1s, es decir, las pruebas son un efecto secundario. La pr\u00e1ctica de TDD no se trata de probar. A pesar de que se llama Desarrollo Impulsado por Pruebas, realmente no se trata de pruebas. Tambi\u00e9n es m\u00e1s bien un enfoque arquitect\u00f3nico. Es un enfoque sobre c\u00f3mo escribir exactamente lo que se necesita y no escribir lo que no se necesita. Esta pr\u00e1ctica se centra en la siguiente iteraci\u00f3n de tu desarrollo de ideas en t\u00e9rminos de creaci\u00f3n de la arquitectura de la aplicaci\u00f3n.<\/em> <\/p>\n<p><\/p>\n<p><em>Por lo tanto, no es tan f\u00e1cil deshacerse de estas ilusiones. El MVP y las pruebas no se contradicen mutuamente. De hecho, m\u00e1s bien, si haces tu MVP siguiendo la pr\u00e1ctica de TDD, lo har\u00e1s mejor y m\u00e1s r\u00e1pido que si lo haces sin ninguna pr\u00e1ctica y a la ligera.<\/em><\/p>\n<p><\/p>\n<p>Es un pensamiento muy poco obvio y complicado. Cuando escuchas que ahora vas a escribir m\u00e1s pruebas y aun as\u00ed vas a hacer algo m\u00e1s r\u00e1pido, suena absolutamente inadecuado. <\/p>\n<p><\/p>\n<p><em>(Dmitry) Aqu\u00ed muchos, cuando mencionan el MVP, es que la gente simplemente no quiere escribir algo decente. Y, de hecho, son cosas diferentes. No conviertas el MVP en algo que no funcione.<\/em> <\/p>\n<p><\/p>\n<p>S\u00ed, tienes raz\u00f3n.<\/p>\n<p><\/p>\n<p><em>Y luego, de repente, el MVP en producci\u00f3n.<\/em><\/p>\n<p><\/p>\n<p>Para siempre. <\/p>\n<p><\/p>\n<p>Y TDD suena muy extra\u00f1o cuando escuchas que est\u00e1s escribiendo pruebas y parece que tienes m\u00e1s trabajo. Suena muy raro, pero en realidad resulta m\u00e1s r\u00e1pido y m\u00e1s est\u00e9tico. Cuando escribes una prueba, ya piensas mucho en c\u00f3mo ser\u00e1 el c\u00f3digo, c\u00f3mo ser\u00e1 invocado, y tambi\u00e9n qu\u00e9 comportamiento esperamos de \u00e9l. No solo dices que has escrito alguna funci\u00f3n y que hace algo. Primero piensas en qu\u00e9 condiciones tendr\u00e1, c\u00f3mo ser\u00e1 invocada. Cubres esto con pruebas y a partir de ah\u00ed entiendes c\u00f3mo se ver\u00e1n las interfaces dentro de tu c\u00f3digo. Esto influye mucho en la arquitectura. Tu c\u00f3digo autom\u00e1ticamente se vuelve m\u00e1s modular, porque primero intentas entender c\u00f3mo lo vas a probar, y solo luego lo escribes. <\/p>\n<p><\/p>\n<p>En mi experiencia con TDD, en alg\u00fan momento contrat\u00e9 un mentor de Ruby cuando a\u00fan era programador de Ruby. \u00c9l me dijo: \"Hagamos esto usando TDD\". Y pens\u00e9: \"Vaya, ahora tengo que escribir algo adicional\". Entonces acordamos que durante dos semanas, escribir\u00eda todo el c\u00f3digo funcional en Python usando TDD. Al cabo de esas dos semanas, comprend\u00ed que ya no quer\u00eda volver atr\u00e1s. Al intentar aplicarlo en todos lados durante dos semanas, te das cuenta de lo mucho m\u00e1s f\u00e1cil que se vuelve incluso solo pensar. Pero no es obvio, as\u00ed que recomiendo a todos que, si sienten que TDD es complicado, largo y innecesario, lo intenten por dos semanas. A m\u00ed me bastaron esos dos para darme cuenta.<\/p>\n<p><\/p>\n<p><em>(Dmitry) Podemos desarrollar esta idea desde la perspectiva de la explotaci\u00f3n de infraestructura. Antes de lanzar algo nuevo, hacemos un monitoreo y luego lo lanzamos. En este caso, el monitoreo se convierte en una prueba normal. Y hay desarrollo a trav\u00e9s del monitoreo. Pero casi todos dicen que es largo, que les da pereza, y que hacen un borrador temporal. Si hacemos un monitoreo adecuado, entendemos el estado del sistema CI. Y en el sistema CI hay mucho monitoreo. Entendemos el estado del sistema, entendemos lo que hay dentro de \u00e9l. Y durante el desarrollo, precisamente creamos el sistema para que alcance el estado deseado.<\/em> <\/p>\n<p><\/p>\n<p><em>Estas pr\u00e1cticas son conocidas desde hace tiempo. Hace unos 4 a\u00f1os lo discutimos. Pero en 4 a\u00f1os pr\u00e1cticamente nada ha cambiado.<\/em> <\/p>\n<p><\/p>\n<p><em>Pero propongo finalizar esta discusi\u00f3n oficial en esta nota.<\/em><\/p>\n<p><\/p>\n<p>Video (insertado como elemento multimedia, pero por alguna raz\u00f3n no funciona):<\/p>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/zZ3qXVN3Oic\">https:\/\/youtu.be\/zZ3qXVN3Oic<\/a><\/noindex><br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/518406\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 CI-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 CI \u2013 \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e \u0440\u0430\u0437\u043d\u043e\u0435. \u041a\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c CI \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0438\u0434\u0435\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Jenkins. \u041c\u044b\u0441\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e Continuous Integration \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0435\u0449\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u044f \u0445\u043e\u0434\u0438\u043b \u043f\u043e \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438\u0441\u043a\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u043e\u0431\u0449\u0430\u043b\u0441\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":93886,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-93885","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Continuous Integration \u043a\u0430\u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 Jenkins. \u0410\u043d\u0434\u0440\u0435\u0439 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-09-10T17:42:23+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-09-10T17:42:23+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Integraci\u00f3n Continua como pr\u00e1ctica, no Jenkins. Andrey Alexandrov | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Continuous Integration \u043a\u0430\u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 Jenkins. \u0410\u043d\u0434\u0440\u0435\u0439 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u043e\u0432 | ProHoster","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-09-10T17:42:23+00:00","article:modified_time":"2020-09-10T17:42:23+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"93885","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 11:37:31","updated":"2022-09-27 15:57:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/93885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=93885"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/93885\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/93886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=93885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=93885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=93885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}