Como podemos rastrear qual versão do nosso código está em cada ambiente?


14

Atualmente, minha equipe usa um processo de ramificação / implantação bastante simples, semelhante a este:

                ┌────────┐ ┌────┐ ┌──────┐
 Environments:  │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Builds:        │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Branches:      │ master │ │ qa │ │ prod │
                └────────┘ └────┘ └──────┘

Cada ambiente tem sua própria ramificação (usamos git ) e sua própria compilação que usa essa ramificação. Quando queremos promover de um ambiente para outro, por exemplo, do DEV ao controle de qualidade, mesclamos a masterramificação qae iniciamos uma nova compilação de controle de qualidade (que é implantada automaticamente no ambiente de controle de qualidade).

Estamos pensando em mudar para um novo processo que acabaria com uma filial dedicada e a construção para cada ambiente. Em vez disso, uma compilação de versão única criaria um "pacote de implantação" que poderia ser implantado em qualquer ambiente. Estamos imaginando que um fluxo de trabalho típico seria algo como isto:

                ┌────────┐     ┌────┐     ┌──────┐
 Environments:  │  DEV   │ ──► │ QA │ ──► │ PROD │
                └────────┘     └────┘     └──────┘

                      ▲ 
                       \ 

                        ┌───────────────┐
 Builds:                │ release build │
                        └───────────────┘

                                ▲
                                │

                ┌────────┐ ┌─────────┐
 Branches:      │ master │ │ release │
                └────────┘ └─────────┘

A promoção de um ambiente para outro não seria mais tratada no controle de origem; em vez disso, pegamos os binários já criados (o "pacote de implantação") e os lançamos no novo ambiente.

Esse novo sistema nos permitiria implantar qualquer build em qualquer ambiente, o que tem várias vantagens. Por exemplo, é trivial testar as correções de PROD no DEV e QA. Nosso sistema atual não fornece uma maneira fácil de fazer isso sem reverter uma ramificação, o que obviamente gostaríamos de evitar.

A maior desvantagem desse novo sistema é que não temos mais uma maneira automática de rastrear qual código está em qual ambiente. Se precisarmos corrigir o PROD, não teremos mais uma ramificação dedicada sincronizada com a base de código de produção atual. O mesmo vale para o controle de qualidade - se queremos fazer uma alteração rápida no controle de qualidade sem dragar o trabalho em andamento master, não temos mais uma filial que reflete o estado atual do ambiente de controle de qualidade.

Como podemos acompanhar o código em cada ambiente?

Algumas opções que estamos considerando:

  • utilizando tags git para acompanhar qual commit está em qual ambiente
  • incorporando o commit git usado pela compilação em cada pacote de implantação

Você tem um sistema de IC como Hudson ou Jenkins? É capaz de enviar tags do que foi construído de volta ao git? (Eu sei que existem plugins para Hudson e Jenkins que podem ... - não tenho tanta certeza sobre os outros).

@MichaelT Usamos o MSBuild para nossas compilações e o Octopus Deploy para nossas implantações. Estou bastante confiante de que poderíamos fazer o Octopus manipular nosso repositório git com um script de implantação personalizado do Powershell.
18137 Nathan Friend

Respostas:


14

Tags Git são o que você realmente deseja usar para designar lançamentos. O motivo é que eles têm significado para você e podem ser usados ​​para reconhecer rapidamente a ligação entre o código implementado pelo estado e qualquer informação que o servidor de construção possa ter (como o número da construção).

Embora essa seja a resposta que você está procurando, ela resolve apenas metade do problema. O outro é "ei, aqui está o implantado .[wje]arno servidor, de que build veio?" Sabemos que você nunca terá versões diferentes do aplicativo implantadas no dev e qa ou prod. Certo?

A solução para essa parte da pergunta é fazer com que o servidor de compilação coloque as informações no manifesto. Vindo de um exemplo de maven e svn que tenho na minha frente:

<manifestEntries>
    <Specification-Title>${project.name}</Specification-Title>
    <Specification-Version>${project.version}</Specification-Version>
    <Build-Number>${build.number}</Build-Number>
    <Build-Id>${build.id}</Build-Id>
    <Svn-Revison>${svn.revision}</Svn-Revison>
</manifestEntries>

Isso está na configuração do arquivo maven-war-plugin. Mas você pode encontrá-lo em outros plugins também. Então, em Hudson, parte da invocação do maven build é:

-Dbuild.number=${BUILD_NUMBER}
-Dsvn.revision=${SVN_REVISION}
-Dbuild.id=${BUILD_ID}

que define aqueles que então o maven pega. E é apenas uma questão de procurar no arquivo MANIFEST.MF que foi implantado no servidor para ver qual versão é.

Existe um plugin git , que oferece um conjunto semelhante de variáveis ​​de ambiente, incluindo:

  • GIT_COMMIT - SHA do atual
  • GIT_BRANCH - Nome do repositório remoto (padrão de origem), seguido pelo nome da filial atualmente em uso, por exemplo, "origem / mestre" ou "origem / foo"

A combinação dessas duas práticas permite identificar facilmente a compilação (porque os números da compilação avançam e têm significado, diferentemente das somas de verificação sha) e o commit específico do git do qual é construído.


3

Uma abordagem completamente diferente seria descartar versionscompletamente a idéia . Você só tem "uma versão" que possui um comportamento configurável diferente. A única diferença seria que você tem uma base de código comum - mesmo em produção, implantaria o trabalho em andamento : mas não ativado.

A diferença se resume apenas a diferentes conjuntos de recursos ativados no seu produto.

A desativação / ativação é feita via alternância de recursos .

De cabeça para baixo: todo o processo de lançamento é simplificado: você está sempre entregando uma versão integrada do seu software. Todos os recursos estão sempre disponíveis no master. Nenhuma ramificação adicional é necessária.

Não há problema em mesclar recursos juntos, porque: não há ramificações, não é necessário mesclar. Não há confusão sobre qual recurso está em qual ramificação e talvez dependa ou entre em conflito com os recursos de outras ramificações. Cada parte pode ser ativada à vontade. Mesmo uma reversão não é mais necessária: é apenas uma toque de um interruptor .

Não sei se isso funciona para a sua base de código: os pré-requisitos em termos de qualidade do código e disciplina do desenvolvedor são bastante altos - você precisa lidar com a "limpeza" depois que um recurso se torna uma funcionalidade principal e é necessário gerenciar várias alternâncias impedindo uma maior bagunça .

Talvez funcione para você.


Mas e quanto a ter diferentes estados de repositório implantados em diferentes servidores? O código que está sendo executado na caixa de controle de qualidade é o mesmo que está sendo executado na produção para poder reproduzir um erro? O código que os desenvolvedores enviaram para seus desenvolvedores é igual ao código em que o controle de qualidade está sendo executado?

1
A pergunta deve ser feita de forma diferente: o bug com uma configuração especial reproduzível "agora" se sim, você pode corrigi-lo. Se não - o bug importa? Você sempre pressiona o trabalho (e o código integrado).
Thomas Junk

-1

Usamos o maven para colocar a versão no arquivo de manifesto. Em seguida, faça com que o aplicativo exiba a versão se for um aplicativo da Web ou tenha um terminal / version para serviços da Web.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.