Controle do código-fonte (criando aplicativos de nuvem Real-World com o Azure)

por Rick Anderson, Tom Dykstra

Baixar Corrigir Projeto ou Baixar Livro Eletrônico

O livro eletrônico Building Real World Cloud Apps with Azure é baseado em uma apresentação desenvolvida por Scott Guthrie. Ele explica 13 padrões e práticas que podem ajudá-lo a desenvolver aplicativos Web para a nuvem com êxito. Para obter informações sobre o livro eletrônico, consulte o primeiro capítulo.

O controle do código-fonte é essencial para todos os projetos de desenvolvimento de nuvem, não apenas para ambientes de equipe. Você não pensaria em editar o código-fonte ou mesmo em um documento Word sem uma função desfazer e backups automáticos, e o controle do código-fonte fornece essas funções em um nível de projeto em que elas podem economizar ainda mais tempo quando algo der errado. Com os serviços de controle do código-fonte de nuvem, você não precisa mais se preocupar com a configuração complicada e pode usar Azure Repos controle do código-fonte gratuitamente para até 5 usuários.

A primeira parte deste capítulo explica três práticas recomendadas principais para ter em mente:

O restante do capítulo fornece algumas implementações de exemplo desses padrões no Visual Studio, no Azure e no Azure Repos:

Tratar scripts de automação como código-fonte

Quando você está trabalhando em um projeto de nuvem, está mudando as coisas com frequência e deseja ser capaz de reagir rapidamente aos problemas relatados por seus clientes. Responder rapidamente envolve o uso de scripts de automação, conforme explicado no capítulo Automatizar Tudo . Todos os scripts que você usa para criar seu ambiente, implantá-lo, dimensioná-lo etc., precisam estar sincronizados com o código-fonte do aplicativo.

Para manter os scripts sincronizados com o código, armazene-os em seu sistema de controle do código-fonte. Em seguida, se você precisar reverter as alterações ou fazer uma correção rápida no código de produção que é diferente do código de desenvolvimento, não será necessário perder tempo tentando rastrear quais configurações foram alteradas ou quais membros da equipe têm cópias da versão necessária. Você tem certeza de que os scripts necessários estão sincronizados com a base de código para a qual você precisa e tem certeza de que todos os membros da equipe estão trabalhando com os mesmos scripts. Em seguida, se você precisar automatizar o teste e a implantação de uma correção dinâmica para produção ou desenvolvimento de novos recursos, você terá o script certo para o código que precisa ser atualizado.

Não marcar em segredos

Um repositório de código-fonte normalmente é acessível a muitas pessoas para que ele seja um local apropriadamente seguro para dados confidenciais, como senhas. Se os scripts dependerem de segredos como senhas, parametrize essas configurações para que elas não sejam salvas no código-fonte e armazene seus segredos em outro lugar.

Por exemplo, o Azure permite baixar arquivos que contêm configurações de publicação para automatizar a criação de perfis de publicação. Esses arquivos incluem nomes de usuário e senhas que estão autorizados a gerenciar seus serviços do Azure. Se você usar esse método para criar perfis de publicação e se você marcar nesses arquivos para o controle do código-fonte, qualquer pessoa com acesso ao seu repositório poderá ver esses nomes de usuário e senhas. Você pode armazenar com segurança a senha no próprio perfil de publicação porque ela está criptografada e está em um arquivo .pubxml.user que, por padrão, não está incluído no controle do código-fonte.

Estruturar branches de origem para facilitar o fluxo de trabalho de DevOps

A forma como você implementa branches em seu repositório afeta sua capacidade de desenvolver novos recursos e corrigir problemas na produção. Aqui está um padrão que muitas equipes de médio porte usam:

Estrutura do branch de origem

O branch main sempre corresponde ao código que está em produção. Os branches sob main correspondem a diferentes estágios no ciclo de vida de desenvolvimento. O branch de desenvolvimento é onde você implementa novos recursos. Para uma equipe pequena, você pode ter apenas main e desenvolvimento, mas geralmente recomendamos que as pessoas tenham um branch de preparo entre o desenvolvimento e main. Você pode usar o preparo para teste de integração final antes que uma atualização seja movida para produção.

Para grandes equipes, pode haver branches separados para cada novo recurso; para uma equipe menor, você pode ter todos fazendo check-in no branch de desenvolvimento.

Se você tiver um branch para cada recurso, quando o Recurso A estiver pronto, você mesclará seu código-fonte será alterado para o branch de desenvolvimento e para baixo nos outros branches de recursos. Esse processo de mesclagem de código-fonte pode ser demorado e, para evitar esse trabalho enquanto mantém os recursos separados, algumas equipes implementam uma alternativa chamada alternâncias de recursos (também conhecidas como sinalizadores de recursos). Isso significa que todo o código para todos os recursos está no mesmo branch, mas você habilita ou desabilitar cada recurso usando opções no código. Por exemplo, suponha que o Recurso A seja um novo campo para tarefas do aplicativo Corrigir e o Recurso B adiciona funcionalidade de cache. O código para ambos os recursos pode estar no branch de desenvolvimento, mas o aplicativo só exibirá o novo campo quando uma variável for definida como true e só usará o cache quando uma variável diferente for definida como true. Se o Recurso A não estiver pronto para ser promovido, mas o Recurso B estiver pronto, você poderá promover todo o código para Produção com a opção Recurso A desativada e a opção Recurso B ativada. Em seguida, você pode concluir o Recurso A e promovê-lo mais tarde, tudo sem mesclagem de código-fonte.

Se você usa ou não branches ou alternâncias para recursos, uma estrutura de ramificação como essa permite que você flua seu código do desenvolvimento para a produção de maneira ágil e repetível.

Essa estrutura também permite que você reaja rapidamente aos comentários dos clientes. Se você precisar fazer uma correção rápida para a produção, também poderá fazer isso com eficiência de maneira ágil. Você pode criar um branch com main ou preparo e, quando estiver pronto, mesclá-lo em main e para baixo em branches de desenvolvimento e recursos.

Ramificação de hotfix

Sem uma estrutura de ramificação como essa com sua separação de branches de produção e desenvolvimento, um problema de produção pode colocá-lo na posição de ter que promover o novo código de recurso junto com sua correção de produção. O novo código de recurso pode não estar totalmente testado e pronto para produção e talvez seja necessário fazer muito trabalho fazendo backup de alterações que não estão prontas. Ou talvez seja necessário atrasar a correção para testar as alterações e prepará-las para implantação.

Em seguida, você verá exemplos de como implementar esses três padrões no Visual Studio, no Azure e no Azure Repos. Estes são exemplos em vez de instruções passo a passo detalhadas de como fazer; para obter instruções detalhadas que fornecem todo o contexto necessário, consulte a seção Recursos no final do capítulo.

Adicionar scripts ao controle do código-fonte no Visual Studio

Você pode adicionar scripts ao controle do código-fonte no Visual Studio incluindo-os em uma pasta de solução do Visual Studio (supondo que seu projeto esteja no controle do código-fonte). Aqui está uma maneira de fazê-lo.

Crie uma pasta para os scripts na pasta da solução (a mesma pasta que tem o arquivo .sln ).

Pasta de automação

Copie os arquivos de script para a pasta .

Conteúdo da pasta de automação

No Visual Studio, adicione uma pasta de solução ao projeto.

Seleção do menu Nova Pasta da Solução

E adicione os arquivos de script à pasta da solução.

Adicionar seleção de menu Item Existente

Caixa de diálogo Adicionar Item Existente

Os arquivos de script agora estão incluídos em seu projeto e o controle do código-fonte está acompanhando as alterações de versão, juntamente com as alterações de código-fonte correspondentes.

Armazenar dados confidenciais no Azure

Se você executar seu aplicativo em um site do Azure, uma maneira de evitar armazenar credenciais no controle do código-fonte é armazená-las no Azure.

Por exemplo, o aplicativo Fix It armazena em seu arquivo Web.config duas cadeias de conexão que terão senhas em produção e uma chave que fornece acesso à sua conta de armazenamento do Azure.

<connectionStrings>
  <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\MyFixItMembership.mdf;Initial Catalog=MyFixItMembership;Integrated Security=True" providerName="System.Data.SqlClient" />
  <add name="appdb" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\MyFixItTasks.mdf;Initial Catalog=aspnet-MyFixItTasks;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
  <add key="webpages:Version" value="3.0.0.0" />
  <add key="webpages:Enabled" value="false" />
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  <add key="StorageAccountName" value="fixitdemostorage" />
  <add key="StorageAccountAccessKey" value="[accesskeyvalue]" />
</appSettings>

Se você colocar valores de produção reais para essas configurações em seu arquivo Web.config ou se colocá-los no arquivo deWeb.Release.config para configurar uma transformação Web.config para inseri-las durante a implantação, elas serão armazenadas no repositório de origem. Se você inserir as cadeias de conexão de banco de dados no perfil de publicação de produção, a senha estará no arquivo .pubxml . (Você pode excluir o arquivo .pubxml do controle do código-fonte, mas perde o benefício de compartilhar todas as outras configurações de implantação.)

O Azure oferece uma alternativa para as seções appSettings e cadeias de conexão do arquivo Web.config . Aqui está a parte relevante da guia Configuração de um site no portal de gerenciamento do Azure:

appSettings e connectionStrings no portal

Quando você implanta um projeto neste site e o aplicativo é executado, quaisquer valores armazenados no Azure substituem quaisquer valores que estejam no arquivo Web.config.

Você pode definir esses valores no Azure usando o portal de gerenciamento ou scripts. O script de automação de criação de ambiente que você viu no capítulo Automatizar Tudo cria um banco de dados SQL do Azure, obtém o armazenamento e Banco de Dados SQL cadeias de conexão e armazena esses segredos nas configurações do site.

# Configure app settings for storage account and New Relic
$appSettings = @{ `
    "StorageAccountName" = $storageAccountName; `
    "StorageAccountAccessKey" = $storage.AccessKey; `
    "COR_ENABLE_PROFILING" = "1"; `
    "COR_PROFILER" = "{71DA0A04-7777-4EC6-9643-7D28B46A8A41}"; `
    "COR_PROFILER_PATH" = "C:\Home\site\wwwroot\newrelic\NewRelic.Profiler.dll"; `
    "NEWRELIC_HOME" = "C:\Home\site\wwwroot\newrelic" `
}
# Configure connection strings for appdb and ASP.NET member db
$connectionStrings = ( `
    @{Name = $sqlAppDatabaseName; Type = "SQLAzure"; ConnectionString = $sql.AppDatabase.ConnectionString}, `
    @{Name = "DefaultConnection"; Type = "SQLAzure"; ConnectionString = $sql.MemberDatabase.ConnectionString}
)

Observe que os scripts são parametrizados para que os valores reais não sejam persistidos no repositório de origem.

Quando você executa localmente em seu ambiente de desenvolvimento, o aplicativo lê o arquivo de Web.config local e a cadeia de conexão aponta para um banco de dados localDB SQL Server na pasta App_Data do projeto Web. Quando você executa o aplicativo no Azure e o aplicativo tenta ler esses valores do arquivo Web.config, o que ele recebe de volta e usa são os valores armazenados para o Site, não o que realmente está em Web.config arquivo.

Usar o Git no Visual Studio e no Azure DevOps

Você pode usar qualquer ambiente de controle do código-fonte para implementar a estrutura de ramificação de DevOps apresentada anteriormente. Para equipes distribuídas, um DVCS ( sistema de controle de versão distribuído ) pode funcionar melhor; para outras equipes, um sistema centralizado pode funcionar melhor.

O Git é um sistema de controle de versão distribuído popular. Ao usar o Git para controle do código-fonte, você tem uma cópia completa do repositório com todo o histórico dele no computador local. Muitas pessoas preferem isso porque é mais fácil continuar trabalhando quando você não está conectado à rede. Você pode continuar fazendo commits e reversões, criar e alternar branches e assim por diante. Mesmo quando você está conectado à rede, é mais fácil e rápido criar branches e alternar branches quando tudo é local. Você também pode fazer commits e reversões locais sem ter um impacto sobre outros desenvolvedores. E você pode fazer commits em lote antes de enviá-los para o servidor.

Azure Repos oferece git e Controle de Versão do Team Foundation (TFVC; controle do código-fonte centralizado). Introdução ao Azure DevOps aqui.

O Visual Studio 2017 inclui suporte interno do Git de primeira classe. Aqui está uma demonstração rápida de como isso funciona.

Com um projeto aberto no Visual Studio, clique com o botão direito do mouse na solução em Gerenciador de Soluções e escolha Adicionar Solução ao Controle do Código-Fonte.

Adicionar solução ao controle do código-fonte

O Visual Studio pergunta se você deseja usar o TFVC (controle de versão centralizado) ou o Git.

Escolher Controle do Código-Fonte

Quando você seleciona o Git e clica em OK, o Visual Studio cria um novo repositório Git local na pasta da solução. O novo repositório ainda não tem arquivos; você precisa adicioná-los ao repositório fazendo um commit do Git. Clique com o botão direito do mouse na solução no Gerenciador de Soluções e clique em Confirmar.

Confirmar

O Visual Studio prepara automaticamente todos os arquivos de projeto para o commit e os lista no Team Explorer no painel Alterações Incluídas. (Se houver alguns que você não deseja incluir no commit, você poderá selecioná-los, clicar com o botão direito do mouse e clicar em Excluir.)

Team Explorer

Insira um comentário de confirmação e clique em Confirmar e o Visual Studio executa o commit e exibe o ID do commit.

Alterações de Explorer de equipe

Agora, se você alterar algum código para que ele seja diferente do que está no repositório, você poderá exibir facilmente as diferenças. Clique com o botão direito do mouse em um arquivo que você alterou, selecione Comparar com Não Modificado e você obtém uma exibição de comparação que mostra sua alteração não confirmada.

Comparar com Não Modificado

Comparação mostrando alterações

Você pode ver facilmente quais alterações você está fazendo e marcar-las.

Suponha que você precise criar um branch – você também pode fazer isso no Visual Studio. No Team Explorer, clique em Novo Branch.

Equipe Explorer Novo Branch – Imagem 1

Insira um nome de branch, clique em Criar Branch e, se você selecionou o branch Checkout, o Visual Studio faz o check-out automaticamente do novo branch.

Equipe Explorer Novo Branch – Imagem 2

Agora você pode fazer alterações nos arquivos e marcar-los nesse branch. E você pode alternar facilmente entre branches e o Visual Studio sincroniza automaticamente os arquivos com qualquer branch que você tenha verificado. Neste exemplo, o título da página da Web em _Layout.cshtml foi alterado para "Hot Fix 1" no branch HotFix1.

Ramificação hotfix1

Se você voltar para o branch main, o conteúdo do arquivo _Layout.cshtml reverter automaticamente para o que eles estão no branch main.

branch main

Este é um exemplo simples de como você pode criar rapidamente um branch e inverter entre branches. Esse recurso permite um fluxo de trabalho altamente ágil usando a estrutura de branch e os scripts de automação apresentados no capítulo Automatizar Tudo . Por exemplo, você pode estar trabalhando no branch desenvolvimento, criar um branch de correção frequente fora do main, alternar para o novo branch, fazer suas alterações lá e confirmá-las e, em seguida, voltar para o branch desenvolvimento e continuar o que você estava fazendo.

O que você viu aqui é como você trabalha com um repositório Git local no Visual Studio. Em um ambiente de equipe, normalmente, você também envia alterações por push para um repositório comum. As ferramentas do Visual Studio também permitem que você aponte para um repositório Git remoto. Você pode usar GitHub.com para essa finalidade ou pode usar o Git e Azure Repos integrados a todos os outros recursos do Azure DevOps, como item de trabalho e rastreamento de bugs.

Essa não é a única maneira de implementar uma estratégia de ramificação ágil, é claro. Você pode habilitar o mesmo fluxo de trabalho ágil usando um repositório de controle do código-fonte centralizado.

Resumo

Meça o sucesso do sistema de controle do código-fonte com base na rapidez com que você pode fazer uma alteração e fazê-la viver de maneira segura e previsível. Se você tiver medo de fazer uma mudança porque você tem que fazer um ou dois dias de teste manual nele, você pode se perguntar o que você tem que fazer em termos de processo ou teste para que você possa fazer essa mudança em minutos ou, na pior das hipóteses, não mais do que uma hora. Uma estratégia para fazer isso é implementar a integração contínua e a entrega contínua, que abordaremos no próximo capítulo.

Recursos

Para obter mais informações sobre estratégias de ramificação, consulte os seguintes recursos:

Para obter mais informações sobre como lidar com informações confidenciais que não devem ser mantidas em repositórios de controle do código-fonte, consulte os seguintes recursos:

Para obter informações sobre outros métodos para manter informações confidenciais fora do controle do código-fonte, consulte ASP.NET MVC: Manter configurações privadas fora do controle do código-fonte.