socialgekon.com
  • Principal
  • Pessoas E Equipes
  • Nutrição
  • Ascensão Do Remoto
  • Ágil
Gerenciamento De Projetos

Fluxo Git aprimorado explicado

Causar danos inadvertidamente com o Git pode ser muito fácil. Ainda assim, a melhor maneira de usar Ir sempre será controverso.

Isso porque o próprio Git apenas detalha as operações básicas de ramificação, o que deixa seus padrões de uso - ou seja, modelos de ramificação - uma questão de opinião do usuário. Os modelos de ramificação Git prometem aliviar a dor, organizando o caos que inevitavelmente surge quando os desenvolvedores de software fazem alterações em suas bases de código.

Como muitos desenvolvedores, você queria algo que “simplesmente funcionasse” para que pudesse continuar com o desenvolvimento de software real. Então você pegou Fluxo Git , um modelo de ramificação frequentemente recomendado para usuários Git. Talvez você tenha concordado com a lógica do fluxo do Git no início, até que encontrou alguns empecilhos na prática. Ou talvez o fluxo do Git não pareça um ajuste bom o suficiente para você adotá-lo. Afinal, existem inúmeras variáveis ​​em jogo e nenhum modelo de ramificação único funcionará bem em todas as situações.



Boas notícias! Uma variação do modelo de fluxo clássico do Git, fluxo Git aprimorado simplifica as manobras mais comuns do fluxo de trabalho do Git e ainda mantém as vantagens principais.

O Esplendor e a Miséria do Modelo de Fluxo Git Clássico

Sou um forte defensor do fluxo Git desde que descobri como ele se destaca no desenvolvimento de um produto que evolui em incrementos de valor significativo (Em outras palavras, lançamentos )

Um incremento de valor significativo requer uma quantidade significativa de tempo para ser concluído, como os sprints de mais de duas semanas normalmente usados ​​em Scrum baseado no desenvolvimento. Se uma equipe de desenvolvimento já implementou a produção, pode haver problemas se o escopo da próxima versão se acumular no mesmo lugar onde reside o código de produção - por exemplo, no branch principal do repositório Git que eles usam.

Enquanto o produto ainda está na fase inicial de desenvolvimento, ou seja, não há produção e não há usuários reais do produto, está tudo bem para a equipe simplesmente manter tudo dentro do ramo principal. Na verdade, é mais do que bom: essa estratégia permite o ritmo de desenvolvimento mais rápido sem muita cerimônia. Mas as coisas mudam em um ambiente de produção; então, pessoas reais começam a confiar que o produto seja estável.

Por exemplo, se houver um bug crítico na produção que precisa ser corrigido imediatamente, seria um grande desastre para a equipe de desenvolvimento ter que reverter todo o trabalho acumulado no branch principal até agora apenas para implantar a correção. E implantar código sem o teste adequado - seja o código considerado incompleto ou bem desenvolvido - claramente não é uma opção.

É aí que os modelos de ramificação brilham, incluindo o fluxo Git. Qualquer modelo sofisticado de ramificação deve responder a perguntas sobre como isolar o próximo lançamento da versão do sistema usado atualmente pelas pessoas, como atualizar essa versão com o próximo lançamento e como introduzir hotfixes de quaisquer bugs críticos para a versão atual.

O processo de fluxo do Git aborda esses cenários fundamentais separando “principal” (o ramo de produção ou “versão atual”) e “desenvolver” (o ramo de desenvolvimento ou “próximo lançamento”) e fornecendo todas as regras sobre o uso de ramos de recurso / lançamento / hotfix . Ele resolve com eficácia muitas dores de cabeça dos fluxos de trabalho de desenvolvimento de produtos baseados em lançamento.

Mas mesmo com projetos bem adequados ao modelo de fluxo clássico do Git, sofri os problemas típicos que ele pode trazer:

  • O fluxo do Git é complexo, com dois branches de longa duração, três tipos de branches temporários e regras rígidas sobre como os branches lidam uns com os outros. Essa complexidade torna os erros mais prováveis ​​e aumenta o esforço necessário para corrigi-los.
  • Ramificações de lançamento e hotfix requerem “dupla fusão” - uma vez no principal, depois no desenvolvimento. Às vezes, você pode esquecer de fazer as duas coisas. Você pode tornar a ramificação do fluxo Git mais fácil com scripts ou plug-ins de cliente VCS GUI, mas você deve configurá-los primeiro para cada máquina de cada desenvolvedor envolvido em um determinado projeto.
  • Em fluxos de trabalho de CI / CD, você geralmente acaba com duas compilações finais para um release - uma do commit mais recente do próprio branch de release e outra do commit de mesclagem para principal. Estritamente falando, você deve usar o do principal, mas os dois geralmente são idênticos, criando o potencial para confusão.

Digite “Fluxo Git aprimorado”

A primeira vez que usei o fluxo Git aprimorado foi em um projeto greenfield de código fechado. Eu estava trabalhando com outro desenvolvedor e estávamos trabalhando no projeto nos comprometendo diretamente com o branch principal.

Observação: até o primeiro lançamento público de um produto, faz sentido comprometer todas as alterações diretamente no branch principal - mesmo se você for um defensor do fluxo do Git - por causa da velocidade e simplicidade do fluxo de trabalho de desenvolvimento. Como ainda não há produção, não há possibilidade de um bug de produção que a equipe precise corrigir o mais rápido possível. Fazer toda a mágica de ramificação que o fluxo clássico do Git implica é, portanto, um exagero neste estágio.

Então chegamos perto do lançamento inicial e concordamos que, além desse ponto, não estaríamos mais confortáveis ​​em nos comprometermos diretamente com o branch principal. Tínhamos mudado muito rapidamente e as prioridades de negócios não deixavam muito espaço para estabelecer um processo de desenvolvimento sólido, ou seja, um com testes automatizados suficientes para nos dar a confiança de que nosso branch principal estava pronto para o lançamento.

Parecia ser um caso válido para o modelo de fluxo clássico do Git. Com ramificações principais e de desenvolvimento separadas e tempo suficiente entre incrementos de valor significativos, havia confiança de que o controle de qualidade manual produziria resultados bons o suficiente. Quando defendi o fluxo do Git, meu colega sugeriu algo semelhante, mas com algumas diferenças importantes.

No começo, eu empurrei de volta. Pareceu-me que alguns dos “patches” propostos para o fluxo clássico do Git eram um pouco revolucionários demais. Achei que eles poderiam quebrar a ideia principal, e toda a abordagem seria insuficiente. Mas, pensando melhor, percebi que esses ajustes não interrompem o fluxo do Git. Enquanto isso, eles o tornam um modelo de ramificação Git melhor resolvendo todos os pontos problemáticos mencionados acima.

Após o sucesso com a abordagem modificada naquele projeto, eu usei em outro projeto de código fechado com uma pequena equipe por trás dele, onde eu era o proprietário permanente da base de código e um desenvolvedor terceirizado ou dois ajudavam de tempos em tempos. Neste projeto, entramos em produção há seis meses e, desde então, temos usado testes de CI e E2E por mais de um ano, com lançamentos a cada mês ou mais.

Um gráfico de confirmação Git típico ao usar o fluxo Git aprimorado. O gráfico mostra alguns commits em development e main, e antes de seu commit comum, várias tags baseadas em data.

Minha experiência geral com essa nova abordagem de ramificação foi tão positiva que eu queria compartilhá-la com meus colegas desenvolvedores para ajudá-los a contornar as desvantagens do fluxo Git clássico.

Semelhanças com o fluxo Git clássico: isolamento de desenvolvimento

Para o isolamento do trabalho no fluxo Git aprimorado, ainda existem dois ramos de longa duração, principal e desenvolver. (Os usuários ainda têm recursos de hotfix e lançamento - com ênfase em 'recursos', uma vez que esses não são mais branches. Entraremos em detalhes na seção de diferenças.)

Não há um esquema de nomenclatura oficial para branches de recursos de fluxo clássicos do Git. Basta ramificar a partir do desenvolvimento e fundir novamente para desenvolver quando o recurso estiver pronto. As equipes podem usar qualquer convenção de nomenclatura que desejarem ou simplesmente esperar que os desenvolvedores usem nomes mais descritivos do que 'meu-branch'. O mesmo é verdadeiro para o fluxo Git aprimorado.

Todos os recursos acumulados na ramificação de desenvolvimento até algum ponto de corte irão moldar a nova versão.

Squash Merges

Eu recomendo fortemente o uso de squash merge para ramificações de recursos para manter o histórico bom e linear na maioria das vezes. Sem isso, os gráficos de commit (das ferramentas GUI ou git log --graph) começam a parecer desleixados quando uma equipe está lidando com até mesmo um punhado de branches de recursos:

Comparando o gráfico de confirmação resultante de uma estratégia de mesclagem de compressão com aquele resultante de uma estratégia de confirmação de mesclagem. O gráfico inicial do Git commit tem seu branch primário rotulado

Mas mesmo que você esteja bem com o visual neste cenário, há outro motivo para reprimir. Sem comprimir, commitar visualizações de histórico — entre elas planas git log (sem --graph) e também GitHub - conte histórias um tanto incoerentes, mesmo com o mais simples dos cenários de mesclagem:

Comparando a visualização do histórico de commits resultante de uma tática de squash merge com aquela resultante de uma tática de merge commit. O estado de repo original é fornecido na forma de linha do tempo, mostrando a cronologia de commits para dois branches de recursos vindos de um commit comum

A advertência ao usar a mesclagem de squash é que o histórico de ramificações do recurso original é perdido. Mas essa advertência nem mesmo se aplica se você estiver usando o GitHub, por exemplo, que expõe toda a história original de um branch de recurso por meio da solicitação pull que foi mesclada, mesmo após o branch de recurso em si ser excluído.

Diferenças do fluxo do Git clássico: versões e hotfixes

Vamos passar pelo ciclo de lançamento, pois (espero) é a coisa principal que você fará. Quando chegarmos ao ponto em que gostaríamos de liberar o que foi acumulado no desenvolvimento, é estritamente um superconjunto do principal. Depois disso, é onde começam as maiores diferenças entre o fluxo Git clássico e aprimorado.

Gráficos de commit do Git conforme eles mudam ao executar uma versão normal sob o fluxo Git aprimorado. O gráfico inicial tem divergência principal de desenvolver vários commits por trás da ponta e por um commit. Após a marcação, principal e vYYYY-MM-DD ficam parecidos. Depois de excluir o principal local, criá-lo na ponta do desenvolvimento, empurrar, implantar, testar, etc., main é mostrado mesmo com o desenvolver, deixando vYYYY-MM-DD onde o principal estava originalmente. Após o ciclo de implantação / teste, correções de teste no principal (eventualmente squash mesclado em desenvolvimento) e, entretanto, mudanças não relacionadas no desenvolvimento, o gráfico final desenvolveu e divergiu principal, cada um com vários commits, de onde eles estavam mesmo com o outro em o gráfico anterior.

Versões no fluxo Git aprimorado

Cada etapa para fazer uma versão com fluxo Git aprimorado difere do processo de fluxo Git clássico:

  1. Os lançamentos são baseados no principal, em vez de no desenvolvimento. Identifique a ponta atual do ramo principal com algo significativo. Adotei tags com base na data atual no formato ISO 8601 prefixado com um “v” - por exemplo, v2020-09-09 .
    • Se acontecer de haver vários lançamentos em um dia - por exemplo, hotfixes - o formato pode ter um número sequencial ou uma letra anexada a ele conforme necessário.
    • Esteja ciente de que as tags, em geral, não correspondem às datas de lançamento. Eles servem apenas para forçar o Git a manter uma referência de como o branch principal parecia no momento em que o próximo processo de lançamento começou.
  2. Empurre a tag usando git push origin .
  3. Depois disso, um pouco de surpresa: exclua sua filial principal local . Não se preocupe, porque vamos restaurá-lo em breve.
    • Todos os commits para main ainda são seguros - nós os protegemos da coleta de lixo marcando main na etapa anterior. Cada um desses commits - até mesmo os hotfixes, como veremos em breve - também faz parte do desenvolvimento.
    • Apenas certifique-se de que apenas uma pessoa da equipe esteja fazendo isso para qualquer versão; essa é a chamada função de 'gerente de lançamento'. Um gerente de liberação é geralmente o membro da equipe mais experiente e / ou sênior, mas uma equipe seria sábia para evitar que qualquer membro da equipe em particular assuma essa função permanentemente. Faz mais sentido espalhar conhecimento entre a equipe para aumentar o infame fator de ônibus .
  4. Crie um novo branch principal local no commit de ponta de seu branch de desenvolvimento .
  5. Empurre essa nova estrutura usando git push --force , já que o repo remoto não aceitará uma 'mudança drástica' tão facilmente. Novamente, isso não é tão inseguro quanto pode parecer neste contexto porque:
    • Estamos apenas movendo o ponteiro do branch principal de um commit para outro.
    • Apenas um membro da equipe em particular está fazendo essa alteração por vez.
    • O trabalho de desenvolvimento diário acontece no branch de desenvolvimento, então você não interromperá o trabalho de ninguém movendo-se desta forma.
  6. Você tem seu novo lançamento! Implante-o no ambiente de teste e teste. (Discutiremos os padrões de CI / CD convenientes abaixo.) Quaisquer correções vão diretamente para o branch principal e ele começará a divergir do branch de desenvolvimento por causa disso.
    • Ao mesmo tempo, você pode começar a trabalhar em uma nova versão no branch de desenvolvimento, a mesma vantagem vista no fluxo Git clássico.
    • No caso infeliz de um hotfix ser necessário para o que está atualmente em produção (não o próximo lançamento em teste) neste ponto, há mais detalhes sobre este cenário em “Lidando com hotfixes durante um lançamento ativo…” abaixo.
  7. Quando sua nova versão for considerada estável o suficiente, implantar a versão final no ambiente de produção e fazer uma única fusão de squash do principal para desenvolver para pegar todas as correções.

Hotfixes no fluxo Git aprimorado

Os casos de Hotfix são duplos. Se você estiver fazendo um hotfix quando não há liberação ativa —Ou seja, a equipe está preparando uma nova versão no branch de desenvolvimento — é uma brisa: comprometa-se com a principal, faça com que suas mudanças sejam implantadas e testadas na preparação até que estejam prontas e, em seguida, implante para produção.

Como última etapa, selecione seu commit do main para o desenvolvimento para garantir que a próxima versão conterá todas as correções. Caso você termine com vários commits de hotfix, você economiza esforços - especialmente se seu IDE ou outra ferramenta Git puder facilitar isso - criando e aplicando um patch em vez de selecionar várias vezes. Tentar esmagar o merge main para desenvolver após o lançamento inicial provavelmente resultará em conflitos com o progresso independente feito no branch de desenvolvimento, então eu não recomendo isso.

Lidando com hotfixes durante um lançamento ativo - ou seja, quando você apenas força o pressionamento principal e ainda está preparando a nova versão - é a parte mais fraca do fluxo Git aprimorado. Dependendo da duração do seu ciclo de lançamento e da gravidade do problema que você precisa resolver, sempre tente incluir correções na própria versão - essa é a maneira mais fácil de fazer e não interromperá o fluxo de trabalho geral.

Caso isso seja impossível - você tem que introduzir uma correção rapidamente e não pode esperar que a nova versão fique pronta - então prepare-se para um procedimento Git um tanto intrincado:

  1. Crie um branch - vamos chamá-lo de 'new-release', mas sua equipe pode adotar qualquer convenção de nomenclatura aqui - com o mesmo commit da dica atual do main. Empurre o novo lançamento.
  2. Exclua e recrie o branch principal local no commit da tag que você criou anteriormente para a versão ativa atual. Force o push principal.
  3. Apresente as correções necessárias para principal, implante no ambiente de preparação e teste. Sempre que estiver pronto, implante para produção.
  4. Propague as mudanças do principal atual para o novo lançamento, tanto por seleção seletiva quanto por patch.
  5. Depois disso, refaça o procedimento de liberação: marque a ponta do main atual e empurre a tag, exclua e recrie o main local na ponta do branch de nova liberação e force o push do principal.
    1. Você provavelmente não precisará da tag anterior, portanto, pode removê-la.
    2. O branch de nova versão agora é redundante, então você também pode removê-lo.
  6. Agora você deve estar pronto para continuar como de costume com um novo lançamento. Termine propagando os hotfixes de emergência do principal para o desenvolvimento por meio de seleção seletiva ou patch.

Gráficos de commit do Git conforme eles mudam ao executar um hotfix durante uma versão ativa no fluxo Git aprimorado. O gráfico inicial foi desenvolvido como a linha mais longa de commits, com a principal divergência de dois commits anteriores por um commit, e três commits antes disso, o branch a diverge por um commit, marcado como v2020-09-18. Após as duas primeiras etapas acima, o gráfico tem uma nova versão onde o principal costumava ser, e o principal não é nem mesmo com a v2020-09-18. O resto das etapas são então executadas, resultando no gráfico final, onde main é um commit antes de onde o new-release estava e v2020-09-20 é um commit antes de onde v2020-09-18 estava.

Com planejamento adequado, qualidade de código alta o suficiente e um desenvolvimento saudável e cultura de controle de qualidade, é improvável que sua equipe precise usar este método. Foi prudente desenvolver e testar esse plano de desastre para o fluxo Git aprimorado, apenas para garantir, mas nunca precisei usá-lo na prática.

Configuração CI / CD no topo do fluxo Git aprimorado

Nem todo projeto requer um ambiente de desenvolvimento dedicado. Pode ser fácil configurar um ambiente de desenvolvimento local sofisticado em cada máquina de desenvolvedor.

Mas um ambiente de desenvolvimento dedicado pode contribuir para uma cultura de desenvolvimento mais saudável. Executar testes, medir a cobertura de teste e calcular métricas de complexidade no ramo de desenvolvimento geralmente diminui o custo dos erros, detectando-os bem antes que terminem no teste.

Descobri que alguns padrões de CI / CD são especialmente úteis quando combinados com o fluxo Git aprimorado:

  • Se você precisar de um ambiente de desenvolvimento, configure o CI para construir, testar e implantar nele a cada confirmação para o branch de desenvolvimento. Encaixe o teste E2E aqui também, se você tiver e se fizer sentido no seu caso.
  • Configure o CI para construir, testar e implantar no ambiente de preparação em cada confirmação para o branch principal. O teste E2E também é bastante benéfico neste ponto.
    • Pode parecer redundante usar o teste E2E em ambos os lugares, mas lembre-se de que os hotfixes não acontecem no desenvolvimento. Acionar E2E em commits para main testará os hotfixes e as mudanças diárias antes de serem lançadas, mas também o acionamento de commits para desenvolvimento detectará bugs mais cedo.
  • Configure o CI de uma forma que permita que sua equipe implante compilações do ambiente principal para o de produção mediante uma solicitação manual.

A configuração recomendada de CI / CD com fluxo Git aprimorado quando houver

Esses padrões são relativamente simples, mas fornecem um maquinário poderoso para dar suporte às operações de desenvolvimento do dia a dia.

O modelo de fluxo Git aprimorado: melhorias e possíveis limitações

O fluxo Git aprimorado não é para todos. Ele aproveita a controvertida tática da força empurrando o ramo principal, então os puristas podem se ressentir disso. De um ponto de vista prático, não há nada de errado com isso.

Conforme mencionado, os hotfixes são mais desafiadores durante o lançamento, mas ainda são possíveis. Com a devida atenção ao controle de qualidade, cobertura de teste, etc., que não deve acontecer com muita frequência, então, da minha perspectiva, é uma troca válida para os benefícios gerais do fluxo Git aprimorado em comparação ao fluxo Git clássico. Eu estaria muito interessado em ouvir como o fluxo aprimorado do Git se sai em equipes maiores e com projetos mais complexos, onde os hotfixes podem ser uma ocorrência mais frequente.

Minha experiência positiva com o modelo de fluxo Git aprimorado também gira principalmente em torno de projetos comerciais de código fechado. Pode ser problemático para um projeto de código-fonte aberto em que as solicitações pull são frequentemente baseadas em uma derivação de versão antiga da árvore de código-fonte. Não há obstáculos técnicos para resolver isso - pode exigir mais esforço do que o esperado. Agradeço o feedback de leitores com muita experiência no espaço de código aberto com relação à aplicabilidade do fluxo Git aprimorado em tais casos.

Agradecimentos especiais ao colega ApeeScape Antoine Pham por seu papel principal no desenvolvimento da ideia por trás do fluxo Git aprimorado.


Leituras adicionais no blog de engenharia ApeeScape:

  • Desenvolvimento baseado em tronco vs. Fluxo Git
  • Fluxos de trabalho do Git para profissionais: um bom guia do Git

Emblema Microsoft Gold Partner.

Como um Microsoft Gold Partner , ApeeScape é sua rede de elite de especialistas da Microsoft. Monte equipes de alto desempenho com os especialistas de que você precisa - em qualquer lugar e exatamente quando você precisar deles!

Compreender o básico

O que é fluxo Git?

O fluxo Git é um modelo de ramificação para o sistema de controle de versão Git (VCS). Um modelo de ramificação baseia-se em operações básicas do Git, prescrevendo padrões de uso destinados a permitir o gerenciamento robusto de versões. O fluxo do Git foi anunciado publicamente em um artigo de blog de Vincent Driessen em 2010 e permaneceu popular desde então.

Qual é a estratégia de ramificação de fluxo do Git?

A estratégia de ramificação de fluxo Git é excelente ao desenvolver um produto que evolui em incrementos de valor significativos. Ele faz isso separando 'principal' (o ramo de produção ou 'versão atual') e 'desenvolver' (o ramo de desenvolvimento ou 'próximo lançamento') e fornecendo todas as regras necessárias sobre o uso de ramos auxiliares.

Como faço para usar o fluxo do Git?

Você usa o fluxo Git seguindo seu padrão prescrito. Isso permite que sua equipe obtenha respostas a perguntas sobre como isolar a próxima versão da versão do sistema atualmente em produção, como atualizar essa versão com a próxima versão e como introduzir hotfixes de quaisquer bugs críticos para a versão atual.

Devo usar o fluxo do Git?

Se você deve usar o fluxo Git ou não, depende do seu projeto específico. A principal pergunta a ser respondida é: 'O fluxo de trabalho de desenvolvimento geral tem garantia de qualidade automática suficiente para manter o branch principal no estado de liberação?' Se a resposta for não, esse projeto provavelmente se beneficiará do fluxo do Git.

Qual é o melhor fluxo de trabalho do Git?

Não existe um único fluxo de trabalho Git melhor, porque a resposta depende do contexto específico do projeto. Alguns projetos se beneficiarão do fluxo do Git ou de uma variação dele, enquanto outros serão melhores com uma abordagem de desenvolvimento baseada em tronco.

Erupção do vulcão na Indonésia: Merapi ejeta nova nuvem de cinzas

Mundo

Erupção do vulcão na Indonésia: Merapi ejeta nova nuvem de cinzas
Mohenjo Daro: Ashutosh Gowariker, por que seus personagens estão chamando sua cidade de 'monte dos mortos'?

Mohenjo Daro: Ashutosh Gowariker, por que seus personagens estão chamando sua cidade de 'monte dos mortos'?

Pesquisar

Publicações Populares
Trudeau do Canadá, perdendo nas pesquisas, defende a convocação das eleições antecipadas
Trudeau do Canadá, perdendo nas pesquisas, defende a convocação das eleições antecipadas
‘Madrasas têm que encontrar um equilíbrio entre o sagrado e o secular ... este último não pode ser uma reflexão tardia na educação’
‘Madrasas têm que encontrar um equilíbrio entre o sagrado e o secular ... este último não pode ser uma reflexão tardia na educação’
Um tutorial passo a passo para seu primeiro aplicativo AngularJS
Um tutorial passo a passo para seu primeiro aplicativo AngularJS
Um processo de 5 etapas para transformar seu blog em um túnel de alta conversão
Um processo de 5 etapas para transformar seu blog em um túnel de alta conversão
Prêmio Nobel de Química de 2021 concedido a Benjamin List e David MacMillan
Prêmio Nobel de Química de 2021 concedido a Benjamin List e David MacMillan
 
IA descomplicada para seu aplicativo: Conheça o Salesforce Einstein
IA descomplicada para seu aplicativo: Conheça o Salesforce Einstein
Introdução ao PHP 7: O que há de novo e o que aconteceu
Introdução ao PHP 7: O que há de novo e o que aconteceu
Guia de um trabalhador remoto para se manter saudável
Guia de um trabalhador remoto para se manter saudável
O código aberto está aberto para mulheres?
O código aberto está aberto para mulheres?
Dicas de design e práticas recomendadas de experiência do usuário da Shopify
Dicas de design e práticas recomendadas de experiência do usuário da Shopify
Categorias
FilmagemDesign MóvelVida DesignerPlanejamento E PrevisãoProcessos FinanceirosAméricasDesign De IuReceita E CrescimentoPessoas E EquipesÁsia

© 2023 | Todos Os Direitos Reservados

socialgekon.com