Este post foca-se na estrutura do nosso repositório de controlo de versões e como este responde às necessidades de uma aplicação web.
Os exemplos dados são para o Subversion – que é o que nós usamos- mas a lógica do repositório pode ser usada noutros sistemas de controlo de versões.
O Problema
A aplicação está “live” e a ser usada por milhares de utilizadores.
Estás a desenvolver a próxima “killer feature”, mas precisas de continuamente aplicar correções à aplicação.
Como aplicar pequenas correções quando o código está em pleno desevolvimento, logo não estável?
Pior a aplicação deixou de responder, tens utilizadores pendurados, o repositório está num estado inconsistente, o que fazer?
PÂNICO!MEDO! Ir para agricultor?
Os mais aventureiros dirão, “editar o código live no servidor com o Vim”. Certo, mas não é solução para tudo. Precisamos de uma solução melhor.
Mas primeiro uma breve descrição dos ambientes que o nosso repositório tem de suportar.
Três Ambientes
No nosso caso temos três ambientes, onde desenvolvemos, testamos e corremos a nossa aplicação.
Desenvolvimento
Onde o desenvolvimento da aplicação é feito.
Staging
Onde testamos novas funcionalidades. O ambiente de Staging é o mais semelhante possível ao ambiente de produção, de modo a minimizar surpresas indesejadas aquando da passagem a produção.
Produção
Aquele que os nossos utilizadores vêm e usam. A versão mais estavél do nosso código.
Novos Ramos
Depois da aplicação estar em produção, ter apenas um ramo no controlo de versões rapidamentamente se torna um problema(acreditem em nós, já passamos por isso).
A nossa solução foi estruturar o repositório de modo a que este espelhasse os ambientes descritos anteriormente. Assim temos:
- trunk – ramo de desenvolvimento.
- branches/releases/live – ambiente de produção, a versão “live” da aplicação.
- branches/releases/edge – ambiente de staging, onde novas features são testadas
- branches/fixes – onde correções mais complexas são efectuadas.
- tags/fixes – marcar o inicio e o fim das correções mais complexas.
- tags/releases – marcar as transições das releases da nossa aplicação, normalmente equivalem a um sprint.
Esta estrutura permite-nos alterar o código de produção ou staging sem seream afectados por novas features em desenvolvimento, pois estão em ramos separados.
Exemplos
Seguem-se alguns exemplos mais concretos.
Pequenas correções
Para aplicar pequenas correções podemos faze-lo directamente no branch de produção e depois junta-las ao ramo de desenvolvimento e staging.
Para tal basta anotar qual a revisão gerada com a correção e efectuar o merge.
svn merge -r37:38 svn://repository/branches/live
svn commit -m "Merge r38 fix bug 3134"
Sempre que possível devemos utilizaesta alternativa, ao invés de …
Ainda mais dificil
Em correções mais demoradas, onde são necessárias varias revisões e/ou vários developers criamos uma sandbox.
Primeiro criamos o branch para a correção.
svn copy -m "create bugfix branch" \\
svn://repository/branches/current \\
svn://repository/branches/fixes/3345-BUG
Depois criamos uma tag para marcar o principio da correção no branch
svn copy -m "bugfix start" \\
svn://repository/branches/3345-BUG \\
svn://repository/tags/3345-PRE
Fazemos checkout do novo branch.
svn co svn://repository/branches/BUG-3345
Neste momento podemos fazer as correções e aplicar os commits que forem necessários sem qualquer precupação de poluir o branch principal.
Quando terminada a correção, precisamos de aplica-la nos outros branches.
Criamos uma tag a marcar o fim da correção
svn copy -m "bugfix end" \\
svn://repository/branches/3345-BUG \\
svn://repository/tags/3345-POST
Agora utilizamos as duas tags para aplicar a correção aos branches desejados
3345-BUG$ cd..
project$ cd current
current$ svn merge svn://repository/tags/3345-PRE \\
svn://repository/tags/3345-POST
Depois de testada a correção é só fazer commit, e todos na equipa terão acesso a esta.
# be sure to test everything
current$ svn commit -m "Merge bug fix 3345"
Esta opção é mais complicado, no entanto oferece maior flexibilidade.
Resumindo e concluindo
Ter uma aplicação web “live” cria um “conflito” entre o desenvolvimento de novas features e correções que precisam de ser aplicadas imediatamente.
O repositório de código já não pode ter apenas um ramo.
É necessário definir uma estrutura para o repositório e um conjunto de regras a serem aplicadas por toda a equipa.
Arrumar o repositório utilizando os mecanismos disponibilizados pelo controlo de versões como:
- criação de ramos,
- criação de tags/marcas
- facilidade em fazer merges
Aplicando estes principios conseguimos ter desenvolvimento activo e aplicar correções quase instântaneas ao ambiente “live”, mantendo a aplicação o melhor e mais estável possível.
E vocês como “arrumam” o vosso código?
