Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 47

Merging Code and Migrations

Recommended resources

Olá! Bem-vindo à nossa oitava lição do Módulo 8.

Na aula anterior, desenhamos a "coreografia" do nosso agente, estabelecendo a sequência de chamadas de ferramentas no padrão "contract-first". Definimos como gerar os artefatos individuais — o script de migração do banco de dados, o código do backend e o código do frontend — em uma ordem lógica para respeitar suas dependências. Cada agente especialista produziu sua parte da solução, com a saída de um servindo como "contrato" para o próximo.

Agora, temos esses pedaços de código e scripts gerados, mas eles ainda estão separados. Como os unimos para formar uma única unidade de trabalho coesa?

Nesta lição, vamos abordar exatamente isso, focando no resultado de aprendizagem: combinar o código gerado e o script de migração em um único conjunto de alterações lógicas (logical change set). Este é o passo crucial que transforma os resultados de múltiplos agentes em uma mudança coerente e pronta para ser submetida ao controle de versão.

1. O Que é um "Conjunto de Alterações Lógicas"?

No seu trabalho como desenvolvedor backend, você lida constantemente com o conceito de transações para garantir a consistência dos dados. Um "conjunto de alterações lógicas" em nosso contexto é análogo a isso: é um grupo de modificações relacionadas em diferentes sistemas (banco de dados, backend C#, frontend React) que, juntas, implementam uma única funcionalidade ou correção de bug. Todas as partes devem ser aplicadas em conjunto para que o sistema como um todo permaneça em um estado consistente e funcional.

Para o agente que estamos construindo, um conjunto de alterações lógicas típico incluirá:

  • O script de migração para o MariaDB.
  • Os arquivos C# modificados ou criados para o backend .NET.
  • Os arquivos JS/TSX modificados ou criados para o frontend React.
  • (Potencialmente) arquivos Dart modificados para a aplicação mobile Flutter.

O desafio é que esses arquivos residem em repositórios Git diferentes. Para que o nosso agente os manipule como uma única unidade, ele precisa de um workspace unificado.


2. Criando um Workspace Unificado para o Agente

A melhor maneira de gerenciar alterações em múltiplos repositórios para uma única tarefa é criar um ambiente de trabalho temporário e isolado que espelhe a estrutura necessária. Vamos explorar uma estratégia poderosa para isso.

Agentic Tooling Across Multiple Repositories

Este artigo de Ricky Smith descreve uma abordagem muito elegante para gerenciar tarefas multi-repositório usando uma funcionalidade nativa do Git que talvez você não use com frequência: git worktrees.

Por favor, leia as seções: 'A High-Level Solution – Directory Structure with Git Worktrees': Foque em como os worktrees permitem ter múltiplos diretórios de trabalho para o mesmo repositório. 'Git Worktree Directory Structure': Preste atenção na estrutura proposta: ~/projects/worktrees/<branch-name>/<repo-name>/. Essa é a chave para criar um workspace por tarefa. 'Giving Context': Entenda como o diretório pai (nomeado com o nome da branch) serve como um local para armazenar o contexto da tarefa (PLAN.md, AGENTS.md), unificando o trabalho do agente.

A ideia central do artigo é brilhante para o nosso propósito:

  1. Criar um Diretório por Tarefa: Para uma tarefa do Jira como PROJ-123, o agente criaria um diretório principal, por exemplo, ~/agent_workspaces/feature/PROJ-123/. O nome da branch se torna o nome do workspace.
  2. Popular com Worktrees: Dentro desse diretório, o agente criaria worktrees para cada repositório afetado pela tarefa (backend, frontend, etc.), todos apontando para a mesma nova branch feature/PROJ-123.
  3. Resultado: Teríamos uma estrutura de pastas assim:
    ~/agent_workspaces/feature/PROJ-123/
    ├── backend-repo/      <-- Worktree do repositório de backend na branch 'feature/PROJ-123'
    ├── frontend-repo/     <-- Worktree do repositório de frontend na branch 'feature/PROJ-123'
    └── PLAN.md            <-- Arquivo de contexto/plano para esta tarefa específica
    

Este workspace se torna a manifestação física do nosso conjunto de alterações lógicas. É um sandbox limpo e isolado onde o agente pode trabalhar sem interferir em outras tarefas ou no seu ambiente de desenvolvimento local.

Uma Abordagem Alternativa: O Repositório Raiz

Outra estratégia, descrita no artigo "Setting Up AI Coding Assistants for Large Multi-Repo Solutions" (recurso LINK), é criar um "repositório raiz da solução". Este é um meta-repositório que contém scripts para clonar todos os outros repositórios do projeto em uma estrutura de pastas predefinida.

  • Vantagem: Oferece uma visão persistente e completa de todo o sistema, o que é ótimo para ferramentas de IA que rodam continuamente no seu editor, como o GitHub Copilot.
  • Desvantagem: É menos dinâmico e pode ser excessivo para um agente focado em tarefas, como o nosso, que se beneficia do isolamento por tarefa oferecido pelos worktrees.

Para o seu objetivo, a abordagem com git worktrees é mais adequada, pois cria um ambiente limpo e específico para cada ticket do Jira que o agente processa.


3. Agregando os Artefatos no Workspace

Agora que temos o workspace, o fluxo de trabalho do nosso agente orquestrador se torna claro. Após a conclusão de cada etapa do padrão "contract-first" da lição anterior, o orquestrador fará o seguinte:

  1. Gerar Migração (DatabaseAgent): O agente de banco de dados gera o script 001_add_birth_date.sql.
  2. Agregar: O orquestrador salva este script no local apropriado dentro do worktree do backend, por exemplo: ~/agent_workspaces/feature/PROJ-123/backend-repo/src/Migrations/001_add_birth_date.sql.
  3. Gerar Código Backend (BackendAgent): O agente de backend, usando o "contrato" da existência do script de migração, gera as alterações nos arquivos C#.
  4. Agregar: O orquestrador salva esses arquivos C# modificados diretamente em suas localizações no worktree, por exemplo: .../backend-repo/src/Models/User.cs.
  5. Gerar Código Frontend (FrontendAgent): O agente de frontend gera as alterações nos arquivos React/JS.
  6. Agregar: O orquestrador salva esses arquivos em suas respectivas localizações no worktree do frontend.

Ao final desse processo, o diretório ~/agent_workspaces/feature/PROJ-123/ contém a totalidade do nosso "conjunto de alterações lógicas", perfeitamente organizado e pronto para ser versionado.

Multi-Agent Pattern Example
Neste diagrama, nosso agente orquestrador atua como o **COORDINATOR**. Ele delega tarefas aos agentes especialistas (como o `Writing Agent` para gerar código) e depois **sintetiza** os resultados, que em nosso caso significa agregar os arquivos gerados no workspace unificado.

4. Transformando o Conjunto de Alterações em Commits

Com todos os arquivos no lugar certo, o passo final é transformar esse conjunto de alterações lógicas em um ou mais commits Git. Para isso, o agente precisará de ferramentas para interagir com o Git a partir do código.

Make Your Agent Work With Git

Este vídeo demonstra como um agente pode interagir com o Git usando bibliotecas Python. Embora seu agente final use o ecossistema Atlassian/Forge (provavelmente com APIs REST ou bibliotecas Node.js), os princípios são exatamente os mesmos.

Assista a estes trechos para entender os blocos de construção: 03:37 - 05:01: Preste atenção na distinção entre gitpython (para operações Git locais como commit, branch) e PyGithub (para interações com a API do GitHub como create pull request). Nosso foco hoje é na parte local. 07:03 - 08:50: Observe a função create_pull_request. Antes de criar o PR, ela precisa fazer o trabalho local: criar uma nova branch e fazer o commit das alterações. A lógica para adicionar os arquivos gerados e comitá-los é o que precisamos implementar.

O processo que o agente seguirá, para cada repositório dentro do workspace, será:

  1. Navegar para o diretório do worktree (ex: cd ~/agent_workspaces/feature/PROJ-123/backend-repo/).
  2. Executar uma ferramenta que encapsula o comando git add . para preparar todas as alterações.
  3. Executar outra ferramenta que encapsula git commit -m "feat(backend): Implementar PROJ-123 - Adicionar data de nascimento".

O artigo "Agentic Tooling Across Multiple Repositories" (recurso LINK) também reforça isso em sua seção 'The Real Magic', listando como uma convenção chave: "Instructing the agent to create git commits as it works".

Dessa forma, o "conjunto de alterações lógicas" abstrato é solidificado em conjuntos de alterações concretos e rastreáveis no Git, um para cada repositório.


Conclusão

Nesta lição, construímos a ponte entre a geração de código e o controle de versão. Transformamos a ideia de um "conjunto de alterações lógicas" em um plano de ação concreto para o nosso agente.

Principais Pontos:

  • Um conjunto de alterações lógicas agrupa todas as modificações de código e banco de dados necessárias para uma única tarefa.
  • A estratégia de git worktrees é uma maneira eficaz de criar um workspace unificado e isolado para que o agente possa manipular múltiplos repositórios de forma segura e organizada.
  • O processo de combinação consiste em agregar os artefatos gerados por cada agente especialista no local correto dentro do workspace.
  • Finalmente, o agente usa ferramentas de automação Git (como gitpython ou equivalentes em Node.js) para criar commits dentro de cada worktree, transformando o conjunto lógico em alterações versionadas.

Na próxima lição, vamos dar o passo final e mais visível: orquestrar a criação dos Pull Requests. Com nossos commits locais prontos em branches dedicadas, vamos implementar as ações para enviá-los ao GitHub, criar os Pull Requests e, por fim, atualizar o ticket do Jira para notificar a equipe que o trabalho do agente está pronto para revisão.