Do Caos ao Fluxo Perfeito: Minha Experiência Automatizando uma Migração Real Gigantesca no GitLab (4.000 Repos)

Published: (December 17, 2025 at 02:48 PM EST)
5 min read
Source: Dev.to

Source: Dev.to

Por que essa migração precisava acontecer

O GitLab Community Edition funciona bem no começo. Mas, quando os times crescem, os repositórios se multiplicam e o volume de pipelines explode, surgem limites claros:

  • falta de governança
  • configurações inconsistentes
  • runners heterogêneos
  • pipelines instáveis
  • ausência de recursos corporativos essenciais

A migração para o GitLab Enterprise Edition era mais que uma melhoria técnica. Era um passo em direção à maturidade organizacional.

O desafio

Não existe uma migração oficial que preserve tudo corretamente.

Sem outra saída, foi criada uma solução própria.

O que torna essa migração tão complexa?

Mover 4 mil projetos não é mover pastas. É preservar um ecossistema inteiro, com elementos como:

  • histórico completo de commits
  • branches protegidas
  • tags de releases
  • variáveis e segredos
  • pipelines com includes espalhados
  • issues e comentários
  • estados de arquivamento
  • runners e permissões

A ferramenta nativa de import/export do GitLab quebra grande parte disso no caminho. Eu precisava construir uma automação capaz de migrar tudo, confiavelmente.

O toolkit que construiu a ponte

Foi desenvolvido um conjunto modular de scripts em Bash para garantir controle absoluto sobre cada parte da migração. Ele está publicado aqui:

👉

Arquitetura em duas camadas

Camada Git – Responsável por:

  • clonar todos os repositórios
  • reconstruir branches
  • garantir a integridade do DAG
  • preservar tags exatamente como no CE
  • reconfigurar remotes
  • reaplicar estado de arquivamento

Camada API – Responsável por:

  • variáveis e segredos
  • issues e comentários
  • hierarquias de grupos
  • permissões
  • recriação de projetos no destino

Cada script fazia apenas uma coisa, mas fazia com precisão. Entre eles:

  • clone-projects.sh
  • replace_gitlab-ci.sh
  • push_projects.sh
  • migrar-variaveis.sh
  • migrate-issues.sh
  • scripts recursivos para subgrupos
  • inventário completo de runners

Era automação com propósito, não mágica.

O caos escondido que apareceu

A documentação oficial ajudava, mas apenas parcialmente. Muitas partes eram inconsistentes, incompletas ou simplesmente não funcionavam como descrito quando aplicadas em grande escala.

Além disso, detectei problemas como:

  • includes de pipeline com caminhos absolutos que quebrariam após a migração
  • variáveis duplicadas, sem escopo ou mal organizadas
  • runners antigos com configurações imprevisíveis
  • projetos arquivados reaparecendo como ativos na importação oficial
  • tags sendo recriadas de forma incorreta

A adoção do processo padrão teria potencialmente causado um impacto operacional severo em toda a organização.

Os testes piloto… e os erros que salvaram a migração

Para garantir que tudo funcionaria, rodei vários testes piloto em ambientes isolados. Todos eles, sem exceção, apresentaram erros no começo.

Exemplos de falhas encontradas

include: /old-group/subgroup/template.yml
  • pipelines quebrando por includes antigos
  • variáveis ausentes que derrubavam jobs
  • runners recusando execuções
  • YAML inválido por detalhes invisíveis
  • tags que desapareciam ou eram recriadas incorretamente
  • hierarquias surgindo fora de ordem

Esses erros foram exatamente a razão do sucesso final.

[Image: Erro de pipeline]

Como mitiguei os problemas

Para resolver os pipelines quebrados por includes antigos, criei um script que analisava cada include recursivamente dentro das pastas clonadas localmente e adicionava o novo caminho automaticamente conforme ele criava o novo path no novo GitLab.

Cada falha revelou o comportamento real do GitLab. Os erros ensinaram mais do que qualquer documentação poderia ensinar. A cada teste:

  • adicionava novas validações
  • criava filtros
  • reforçava logs
  • corrigia casos especiais
  • adicionava verificações idempotentes

Quando os testes finalmente passaram limpos, a automação demonstrou ser realmente confiável.

O dia da migração real

Quando o pipeline de migração completo foi executado, o resultado correspondeu exatamente ao esperado em um cenário de engenharia bem‑sucedido:

  • nenhum histórico perdido
  • nenhuma tag quebrada
  • pipelines funcionando
  • variáveis recriadas com os escopos certos
  • hierarquia preservada
  • código chegando ao destino corretamente
  • repositórios arquivados permanecendo arquivados
  • runners funcionando de forma uniforme

Foi como transformar um sistema caótico em um ambiente previsível, padronizado e governado.

O impacto disso nos times

Mesmo sem medições formais de DORA no início, o comportamento pós‑migração foi nítido.

[Image: Métricas DORA]

Resultados observados

  • Deploys ficaram mais frequentes
  • Lead time caiu drasticamente
  • Pipelines se tornaram mais estáveis
  • Change Failure Rate diminuiu
  • Runners padronizados reduziram erros estranhos
  • Recuperações ficaram mais rápidas graças ao histórico íntegro

Este relato demonstra como uma abordagem modular, test‑driven e orientada a logs pode transformar uma migração de grande escala em um processo confiável e repetível.

[Image: Migrating GitLab Projects]

Toda a organização passou a se mover com mais velocidade

O que essa experiência me ensinou

  • a documentação oficial nunca cobre 100 % dos casos
  • padronização é a base da confiabilidade
  • pipelines dependem profundamente de variáveis
  • runners definem a saúde invisível do CI/CD
  • erros têm um papel essencial na engenharia
  • automação bem feita cria confiança

E a maior lição de todas:
quando você reorganiza a fundação, todo o fluxo de desenvolvimento melhora.

Conclusão

Migrar milhares de projetos não é apenas um desafio técnico.
É uma prova de disciplina, engenharia e resiliência.

Com automação determinística, testes piloto reais e aprendizagem através dos erros, foi possível migrar cerca de 4 000 repositórios com segurança, mantendo a integridade de código, pipelines, histórico e governança.

É importante destacar a possibilidade de evolução futura do projeto. Uma reescrita em Python é considerada uma etapa natural, permitindo maior flexibilidade e fluidez no código, sem desconsiderar a eficiência e robustez das soluções atualmente implementadas em Bash.

A solução está disponível publicamente e pode servir de base para outras pessoas que enfrentam desafios semelhantes:

Se você gostou do projeto, deixe uma ⭐ estrela ⭐ no GitHub – isso ajuda muito a fortalecer e valorizar o trabalho.

👉

Se você está planejando uma grande migração, lembre‑se:

Erros não são inimigos.
Eles são guias.

E automação bem feita transforma medo em confiança.

📚 Referências

  • GitLab Documentation
  • GitLab Import/Export Guide
  • GitLab API Reference
  • Google Cloud – DORA Research & Four Key Metrics
  • Accelerate: State of DevOps Report (DORA)
  • Martin Fowler – Continuous Delivery & Infrastructure as Code
  • Google SRE Book – Eliminating Toil & Reliability Engineering
  • Pro Git Book – Git Internals
  • Advanced Bash Scripting Guide
  • GitHub Engineering – Migration and Automation Insights
Back to Blog

Related posts

Read more »