Por que trunk-based é o melhor modelo de desenvolvimento para DevOps

No último dia 20 de Março, no Pipeline Conference em Londres, Dave Farley, co-autor do livro Continuous Delivery, fez uma palestra onde apresentou o slide acima, postado no Twitter. Na palestra, intitulada ‘Optimising Continuous Delivery’, Dave fala sobre a necessidade de adotar trunk-based development para efetivamente praticar Continuous Integration e Continuous Delivery.

A palestra gerou muitos posts, contra e a favor, tantos que ele resolveu escrever um artigo à respeito, que publicou no seu próprio blog no dia 30 de Março. No artigo ele já aborda muito bem o assunto, fiquem à vontade para ler, mas de qualquer forma vou me atrever aqui a colocar a minha visão, e tentar explicar por que trunk-based é o melhor modelo de desenvolvimento para DevOps.

De acordo com o trunk-based development, não é preciso criar branches, o código evolui numa única linha, o trunk. A regra neste modelo é que o código esteja sempre num estado tal que possa ser passado para a produção.

Ele difere portanto do GIT Flow, que contempla branches de tipos diferentes, cada um com seu propósito. Feature branches, por exemplo, são usadas para a criação de novas features. Quando o desenvolvimento da feature termina, o código é efetivamente integrado através de merge.

Por mais que o código seja super bem construído, e siga fielmente princípios de programação orientada a objetos como SOLID, por exemplo, sabemos que conflitos de merge ocorrem. Uma hora ou outra é inevitável que nos deparemos com a necessidade de resolver conflitos de merge.

Não tem jeito, o risco de merge precisa ser endereçado. Mas pensem comigo, o que é melhor: resolver o quanto antes conflitos de merge menores ou deixar pra depois a resolução de um conflito de merge enorme?

Quanto mais duradoura é uma feature branch, maior é a probabilidade dela gerar conflitos de merge. Agora imaginem várias feature branches paralelas que em determinado momento precisarão ser mergeadas para se criar uma nova release?

Outra questão é que quando se usa feature branch, seu código só é integrado quando o merge é realizado. Isto que dizer que a integração neste caso não é tão contínua assim, pelo menos não é tão regular quanto a prática da integração contínua requer. Não adianta se enganar.

Como consequência, não há como existir a entrega contínua de fato, se a própria integração contínua é capenga. A conclusão que se chega é que mesmo usando ferramentas que permitam a automatização e a adoção de práticas DevOps como integração contínua e entrega contínua, é possível que não esteja sendo feita nem integração contínua e tampouco entrega contínua de fato.

Muitos confundem DevOps com automatização, mas automatização não é tudo. A automatização, assim como o trunk-based development, vem como meio para otimizar o fluxo, aí sim um dos princípios do DevOps. Segundo este princípio, quanto antes uma linha de código estiver em produção, melhor, pois é quando efetivamente se entrega valor. Dentro desse contexto, o trunk-based development se encaixa perfeitamente.

O time que usa esse modelo, tem o costume de fazer vários commits ao dia. São commits menores, com o código suficiente para agregar algum valor. Essa regularidade permite que se tenha uma validação muito mais constante do que é feito. Ciclos mais curtos de feedback, portanto, que é outro princípio do DevOps. Visando a qualidade acima de tudo, este princípio defende que eventuais problemas sejam identificados e resolvidos o quanto antes no processo. O trunk-based development cai como uma luva, neste caso.

Ok, mas como então distinguir as features, se o código está todo no trunk? Aí entram as feature flags! Feature flag é uma técnica que habilita/desabilita para execução o código de uma feature específica, dependendo de determinadas condições. Isto quer dizer que uma feature pode ser passada para produção até parcialmente, sem problema algum, desde que esteja desligada. E mais, com este dispositivo, é possível ligar e desligar features em produção com facilidade, ou seja, features podem ser experimentadas.

DevOps tem como princípio o aprendizado contínuo, que justamente se consegue através da experimentação. A adoção de feature flags dentro do modelo trunk-based de desenvolvimento, portanto, se encaixa nesse princípio como nenhum outro modelo.

Resumindo, trunk-based é o modelo de desenvolvimento mais aderente ao DevOps, pois contempla seus três princípios: otimização de fluxo (First Way), ciclos curtos de feedback (Second Way) e aprendizado contínuo (Third Way). Espero que tenham gostado do artigo e não esqueçam de dar qualquer feedback. Afinal, melhoria contínua, sempre 🙂

Como sempre entregar seu projeto open source com qualidade

Você tem então seu projeto open source no Github e quer deixá-lo disponível para uso enquanto ele evolui. Isso é muito importante porque o quanto antes ele é utilizado, novas funcionalidades são testadas, bugs são encontrados, mais rápido o software melhora a cada dia. Os usuários podem ter novidades, que agreguem valor, constantemente, e os colaboradores do projeto podem ter o feedback necessário na mesma velocidade. Você pode até não saber o nome, mas o que você quer é implementar um processo de integração e entrega contínuas no ciclo de desenvolvimento do seu software, prática de quem adota DevOps.

O Github se integra a vários serviços distintos de integração contínua. Eles podem ser vistos em http://bit.ly/2yx6k9h. No exemplo dado aqui hoje vamos optar pelo Travis CI, gratuito para projetos open source. O projeto é o Logistics, uma aplicação Java EE (agora EE4J) que roda no Wildfly e usa um banco de dados MongoDB.

O Travis CI requer um arquivo no repositório, chamado .travis.yml. Um exemplo básico dele e mais informações para começar a usar o serviço podem ser visualizados em Getting started. Vamos conferir agora o que o .travis.yml do projeto Logistics instrui o Travis CI a fazer, sempre que um push é feito. Detalhes de como personalizar o processo pode ser conferido em Customizing the Build.

language: java
sudo: required
install: true

services:
  - docker

addons:
  sonarcloud:
    organization: "gustavomcarmo-github"

jdk:
  - oraclejdk8

script:
  - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar
  - docker build --tag=esignbr/logistics .

cache:
  directories:
    - '$HOME/.m2/repository'
    - '$HOME/.sonar/cache'

after_success:
  - "curl -T logistics-ear/target/logistics-ear-1.0-SNAPSHOT.ear -u $FTP_USER:$FTP_PASSWORD ftp://esign.com.br/appservers/wildfly-10.0.0.Final/standalone/deployments/"
  - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
  - docker push esignbr/logistics

Definindo a linguagem de programação

É o primeiro passo, logo na linha inicial. No caso do projeto Logistics, é Java, mas poderia ser Python ou NodeJS. Nas linhas 12 e 13, é possível ainda especificar qual JDK será utilizada. Para compilar a aplicação, é necessária a versão 8.

Gerando os artefatos Java

Para implantar a aplicação Logistics no Wildfly, geramos o arquivo EAR, contendo o JAR do módulo backend do projeto (logistics-ejb) e o WAR do módulo frontend (logistics-web). Para isso, usamos o Maven, responsável essencialmente pela compilação, pela execução dos testes unitários e pelo empacotamento (package) necessário para a entrega. O Maven permite também a utilização de plugins, que estendem sua funcionalidade. Na linha 16 instruímos o Travis CI a executar o Maven (mvn) passando como parâmetro as tarefas a serem desempenhadas por ele.

Avaliando a qualidade do código

O Travis CI tem integração com o SonarCloud, instância do SonarQube na nuvem, disponível para avaliar projetos open source. O SonarQube é uma excelente ferramenta para analisar continuamente a qualidade do código Java e também de outras linguagens de programação. Ela tem uma funcionalidade chamada Quality Gate, que permite que critérios específicos de qualidade sejam definidos para considerar a aplicação apta para entrega. O Quality Gate usado pelo projeto Logistics é o default da ferramenta.

Para integrar ao Travis CI, primeiro é preciso se registrar no SonarCloud e criar um token de autenticação lá. Nas linhas 8 a 10 é configurado o addon do SonarCloud. Observe que é informada a organização que o identifica no serviço, mas não o token. O token é informado no Travis CI como variável de ambiente (SONAR_TOKEN), para não ficar explícito no arquivo .travis.yml.

Uma vez plugado o SonarCloud, basta instruir o Travis CI a rodar a análise do código fonte. Como estamos usando o Maven, e o plugin do SonarQube para o Maven, basta passar como parâmetro para o comando mvn a tarefa sonar:sonar.

Além disso, é preciso analisar a cobertura dos testes unitários, pois é critério de qualidade definido no Quality Gate padrão do SonarQube. Neste caso, usamos o JaCoCo, e seu plugin para o Maven, que executamos anteriormente à análise do SonarQube, ao passar org.jacoco:jacoco-maven-plugin:prepare-agent para o comando mvn.

Mais sobre a integração do SonarCloud ao Travis CI pode ser visto em Using SonarCloud with Travis CI. Os resultados das análises do código fonte da aplicação Logistics realizadas pelo SonarQube podem ser visualizados em https://sonarcloud.io/dashboard?id=br.com.esign%3Alogistics.

Gerando a imagem Docker

Uma alternativa à geração do EAR, que precisa ser implantado numa instância do Wildfly específica, é gerar a imagem Docker da aplicação com o Wildfly e a própria aplicação já embutidos. Neste caso, a aplicação e tudo que ela depende pra ser executada é empacotado junto numa imagem. Para rodar a aplicação, basta então rodar a imagem numa máquina que tiver o Docker instalado.

Para construir a imagem da aplicação Logistics, usamos como base a imagem jboss/wildfly, aplicamos a configuração necessária para acesso ao MongoDB, e implantamos o EAR gerado, conforme definido no Dockerfile. A construção é realizada na linha 17 do arquivo .travis.yml, a partir do comando docker build. A execução de comandos Docker é possível com a utilização do serviço informada nas linhas 5 e 6 e definindo o sudo como required, como aparece na linha 2. Mais informações de como usar o Docker no Travis CI podem ser visualizadas em Using Docker in Builds.

Entregando efetivamente o software

Após analisada a qualidade do software e gerados os artefatos necessários, a entrega pode efetivamente ocorrer. No arquivo .travis.yml, isso é definido em after_success (linha 24).

Primeiramente, o EAR é colocado via FTP no diretório de deployments do Wildfly que fica no nosso domínio (esign.com.br), como pode ser observado na linha 25. As credenciais para acesso ao nosso servidor são por questões de segurança obtidos de variáveis de ambiente. Com este deploy automático, estamos sempre disponibilizando a versão mais nova da aplicação em http://www.esign.com.br/logistics.

Por último, subimos para o Docker Hub a imagem Docker, como pode ser verificado nas linhas 26 e 27. As credenciais para login no Docker Hub são por questões de segurança também obtidos de variáveis de ambiente (linha 26). Com o push automático (linha 27), a última versão da imagem, com a última versão da aplicação, estará sempre disponível para download e execução em máquinas com Docker. O repositório da imagem no Docker Hub é https://hub.docker.com/r/esignbr/logistics.

Otimizando o tempo de build

O Travis CI permite ainda algumas configurações que fazem diminuir o tempo de build. Na linha 3 do .travis.yml, por exemplo, é desabilitada a etapa de resolução das dependências, quando normalmente muitos downloads acontecem. Além disso, com a definição do uso de cache (linhas 19 a 22), o Travis CI sabe onde buscar as dependências outrora baixadas, eliminando assim o download desnecessário.

À medida que o software cresce, é normal que o tempo de build aumente. Não são apenas mais linhas de código, mas novos testes unitários são realizados. De toda forma, é preciso acompanhar e controlar o tempo de build, para manter todo o processo saudável. Não se esqueça que o objetivo é ter feedbacks rápidos. Caso aumente demais, considere dividir o projeto. No caso do Logistics, os builds podem ser vistos em https://travis-ci.org/esign-consulting/logistics.

Conclusão

Esperamos que com este post você consiga implantar um pipeline de entrega do seu projeto open source. Mais do que isso, que você possa evoluí-lo e compartilhá-lo com a comunidade e conosco também. Nunca se esqueça que compartilhando nossas soluções é que mantemos sempre forte o movimento open source.

O que Yin-yang tem a ver com DevOps e você deveria saber à respeito

Na filosofia chinesa, o Yin-yang representa a dinâmica entre forças opostas complementares e interconectadas. O yin representa a força negativa, escura, e o yang representa a positiva, clara. Uma força não pode existir sem a outra, elas são inseparáveis.

O pequeno ponto dentro de cada metade do símbolo do Yin-yang representa a natureza relativa de cada força, o potencial de uma se transformar na outra. Ambas estão em constante oscilação, numa luta sem fim pelo equilíbrio. Elas formam um sistema em que o todo é maior que as partes reunidas.

O yin e o yang regem juntos tudo. O caos e a ordem, a noite e o dia, você pode encontrar ambos em todos os lugares. Eles representam o ritmo de tudo que experimentamos, num fluxo contínuo e harmônico. Tal movimento eterno reflete a essência do universo.

Ok, o que Yin-yang tem a ver com DevOps então?

Bem, assim como o Yin-yang, o DevOps também apresenta conflitos entre forças distintas, times especializados, através de todo o processo de desenvolvimento e entrega de software. À primeira vista, você poderia adivinhar quem seriam os vilões e os mocinhos da estória, e rotulá-los como yin ou yang. De todo modo, por mais incrível que pareça, a verdade é que todos são importantes, e se complementam.

Na teoria, regulação, conformidade, auditoria, segurança, estabilidade, estariam do lado yin, e inovação, evolução, mudança, autonomia, agilidade, estariam do lado yang. É muito comum que quem cuide de um aspecto ou outro tenda a reclamar do que os pares do outro lado fazem, mas a verdade é que todos tem a sua importância no todo.

O DevOps traz essa visão holística, e encoraja as empresas a fazerem mudanças globais nas usas correntes de valor, ao invés de mudanças localizadas, para ter aumento de performance. O segredo é colocar o peso correto em cada força, de uma forma tal que se tenha ganho de velocidade ao mesmo tempo que os riscos sejam devidamente controlados. Como no Yin-yang, as forças no DevOps são inseparáveis.

Imagine de outra maneira estabilidade sem mudança, por exemplo. Nesse cenário, não haveria espaço para crescimento, tudo ficaria paralisado. Por outro lado, mudança sem estabilidade seria arriscado demais. Cabe totalmente à empresa a busca contínua pelo equilíbrio correto entre as forças, para se ter o melhor da soma delas, ou não.

Adotar DevOps é não é uma tarefa simples, pois as empresas são forçadas a olhar para dentro e a lidar com o que elas tem de pior, e melhor. Elas podem escolher ou não dar o próximo passo, e minimizar o que as atrapalha a conseguir maiores níveis de performance. São elas que ditam o seu próprio ritmo, no final das contas. O mesmo ritmo que tanto o Yin-yang quanto o DevOps representam.

Conclusão

Se sua empresa está adotando DevOps, a transformação cultural também é sua responsabilidade. Tenha a cabeça aberta e se coloque no lugar dos outros. Tenha consciência do impacto que você provoca, e tenha atitudes colaborativas. Lembre-se que nada é totalmente ruim (yin), nem totalmente bom (yang), então esteja à disposição para aprender, e mudar. Nós estamos todos no mesmo barco.

Este texto foi traduzido de https://www.linkedin.com/pulse/what-yin-yang-has-do-devops-you-should-know-gustavo-muniz-do-carmo pelo próprio autor.

Como fazer todos definitivamente entenderem o que DevOps realmente é

Mesmo depois de anos da existência do conceito, por que ele ainda é tão incompreendido? Eu acredito já ter ouvido todas as explicações, mas pra mim existe uma explicação simples, a única delas, que captura a essência do significado:

O objetivo do DevOps é minimizar o time-to-market para entregar o quanto antes valor ao cliente.

Um chamado de alerta

Imagine então o quanto de esforço que uma empresa precisa ter para atingir este objetivo? Ok, este esforço está relacionado à utilização das ferramentas e das práticas corretas, mas além disso, e mais importante, está relacionado à construção da cultura correta. E isso não é responsabilidade da TI sozinha, o principal pré-requisito da adoção do DevOps é ter toda a empresa comprometida em alcançar o objetivo!

A menos que os executivos C-Level entendam isso, e promovam a transformação na empresa como um todo, ela só terá DevOps parcialmente. Pior, o objetivo pode não ser conquistado, caso todo o esforço esteja concentrado somente no departamento de TI. DevOps deve começar na TI? Certamente, e na verdade é o que geralmente ocorre. De todo modo, sem escalar a adoção para a empresa, não existe a garantia de se obter todos os benefícios.

Os três princípios do DevOps

Depois de fazer este tipo de chamado de alerta para posicionar DevOps como uma questão corporativa, deixe-me aprofundar um pouco no conceito. Bem, DevOps, influenciado pela filosofia Toyota Way e pelo movimento Lean, é suportado por três princípios, os três caminhos: otimização de fluxo (primeiro caminho), ciclos rápidos de feedback (segundo caminho) e aprendizado contínuo (terceiro caminho). A figura abaixo mostra os três caminhos:

O primeiro caminho, otimização de fluxo

O primeiro caminho, otimização de fluxo, objetiva eliminar desperdícios, gargalos no processo, transferências entre times funcionais especializados, tempos de espera. A automatização é chave, usada extensivamente na implementação de práticas tais como integração contínua, entrega contínua e implantação contínua. As necessidades dos clientes são atendidas o mais cedo possível, após identificadas pelo negócio.

Observe que o primeiro caminho é sobre o processo como um todo, desde a identificação da necessidade do cliente (esquerda) até o ponto em que ela é atendida (direita). Em outras palavras, desde o momento que a demanda nasce até a implantação da nova funcionalidade no ambiente de produção. Na verdade, a demanda percorre times diferentes de departamentos diversos, incluindo, de forma não exclusiva, a TI.

O segundo caminho, ciclos rápidos de feedback

O segundo caminho, ciclos rápidos de feedback, objetiva resolver problemas o quanto antes, medindo o processo inteiro, testando tudo, alertando assim que uma falha é detectada. A monitoração é chave, permitindo rápidos feedbacks à respeito da qualidade do software, assim como da sua entrega e, acima de tudo, do valor que ele traz para os clientes. O segundo caminho segue a ideia do andon cord da Toyota.

Observe que a qualidade é responsabilidade de todos através do processo, não apenas papel de um time de QA. A qualidade é medida desde o início e, depois de tudo, precisa representar valor para os clientes. Feedbacks ficam constantemente gerando informações relevantes para o sistema, incluindo aquelas que avaliam novas funcionalidades. Isto quer dizer que funcionalidades podem ser removidas do software, se não traduzirem valor real aos clientes. Com feedbacks rápidos, o negócio consegue falhar rápido, e logo retomar o rumo, caso necessário.

O terceiro caminho, aprendizado contínuo

O terceiro caminho, aprendizado contínuo, objetiva gerar conhecimento, através da experimentação. Ao invés de considerar que tudo está certo, hipóteses são formuladas, para serem comprovadas. O sistema inteiro é sujeito a melhoria, a adaptações. O terceiro caminho segue a ideia do processo científico.

Observe que o terceiro caminho requer uma boa dose de humildade, flexibilidade e coragem. Humildade porque a empresa precisa reconhecer que nem sempre está certa, flexibilidade porque a empresa precisa poder mudar, e coragem porque a empresa precisa assumir riscos. E isso tem tudo a ver com livrar-se da cultura da culpa e alavancar a colaboração e o compartilhamento de conhecimento.

Conclusão

Se alguém perguntar pra você o significado de DevOps, ou pedir pra você fazer uma apresentação à respeito, por favor conte a história completa. Não cometa o erro de deixar de lado a parte mais difícil, a que DevOps requer uma transformação cultural. Sim, eu sei, todos querem aprender as ferramentas e as práticas para ganhar agilidade, mas você deve mostrá-los que antes é preciso uma mudança de pensamento. Não há saída.

Este texto foi traduzido de https://www.linkedin.com/pulse/how-definitely-make-everyone-understands-what-devops-muniz-do-carmo pelo próprio autor.