Auto: Hotfixes - Suporte a patches para menores antigos e patches

Criado em 11 mar. 2020  ·  25Comentários  ·  Fonte: intuit/auto

Sua solicitação de recurso está relacionada a um problema?

Eu quero ser capaz de lançar um patch para um velho menor

Descreva a solução que você gostaria

  1. Se nos fundirmos em uma tag, devemos ser capazes de detectar isso e fazer um patch / lançamento menor
  2. esses números de lançamento devem usar a parte de compilação do semver para menor / patch
  3. As tags de versão principal podem ter versão normal, pois nunca haveria um conflito de versão
enhancement

Comentários muito úteis

Eu estaria muito interessado!

Todos 25 comentários

@hipstersmoothie
Você tem detalhes de como isso seria implementado / como seria na prática?

Além disso, não tenho certeza se estou entendendo o que merge into a tag significa ... você poderia esclarecer? Meu entendimento era que você só poderia criar um PR com uma filial como alvo.

Não, eu realmente não pensei muito sobre o problema.

Além disso, não tenho certeza se estou entendendo o que significa mesclar em uma tag

A interface do usuário me levou a acreditar que você poderia ser capaz de mesclar em uma tag, mas após uma análise mais aprofundada, isso não parece ser possível. Se pudéssemos, isso tornaria isso possível.

Lembrando um pouco, porém, acho que era o que eu estava pensando:

  1. Tag 1.2.3 existe, a versão atual é 2.0
  2. PR é transformado em tag 1.2.3, produz 1.2.3-0 (o 0 é a parte de construção de sempre)

ok, utilizar a parte de compilação do semver definitivamente faz sentido. 👍

Se não for possível fazer um PR diretamente para uma tag, esse fluxo pode exigir que os proprietários de repo criem uma ramificação a partir de uma tag na ramificação upstream (ramificação de destino para PR). Seria um pouco chato, mas não tenho certeza se haveria uma alternativa melhor. Além disso, esses tipos de lançamentos provavelmente não são comuns, então talvez não haja problema.

Uma abordagem semelhante ao antigo suporte principal ( versionBranches ) pode ser utilizada onde um prefixo de branch pode ser especificado na configuração. Parece que esse recurso pode ser mais voltado para lançamentos do tipo hotfix, então talvez faça sentido manter a configuração separada do suporte principal antigo. O que você acha?


Um exemplo de fluxo pode ser parecido com:

  • o usuário especifica na configuração automática para construir usando identificadores de construção para ramos com prefixo de hotfix-
  • registro de confirmação existente
    <ul> <li>(tag: v2.0.0) (master)<br /> |</li> <li>(tag: v1.2.0)<br /> |</li> <li>(tag: v1.1.0)<br /> |</li> <li>(tag: v1.0.0)<br />

  • o proprietário do repo cria um novo branch para a tag existente que precisa de hotfix
    <ul> <li>(tag: v2.0.0) (master)<br /> |</li> <li>(tag: v1.2.0)<br /> |</li> <li>(tag: v1.1.0) (hotfix-feature)<br /> |</li> <li>(tag: v1.0.0)<br />

  • PR criado e mesclado com o recurso upstream / hotfix (confirmação de mesclagem marcada com tag + identificador de compilação)
    <ul> <li>(tag: v2.0.0) (master)<br /> | </li> <li>(tag: v1.2.0)<br /> |<br /> | * (tag: v1.1.0+1)<br /> | /</li> <li>(tag: v1.1.0) (hotfix-feature)<br /> |</li> <li>(tag: v1.0.0)<br />

  • Uma abordagem semelhante ao antigo suporte principal (versionBranches) pode ser utilizada onde um prefixo de branch pode ser especificado na configuração.

    Gosto da ideia, mas na prática não acho que seria tão divertido de usar. Já que auto libera muito, você terminaria com um número absurdo de branches.

    Se não for possível fazer um PR diretamente para uma tag, esse fluxo pode exigir que os proprietários de repo criem uma ramificação a partir de uma tag na ramificação upstream (ramificação de destino para PR). Seria um pouco chato, mas não tenho certeza se haveria uma alternativa melhor. Além disso, esses tipos de lançamentos provavelmente não são comuns, então talvez não haja problema.

    Eu concordo que este tipo de lançamento está fora do normal. isso torna a criação automatizada de ramos menos útil. Você obteria muito ruído (mais branches) sem usá-los tanto, se é que o faria.


    Quanto ao fluxo proposto acima, parece funcionar bem. É uma pena que não possamos transformar PRs em tags! tornaria esse fluxo de trabalho muito mais fácil.

    Pensando nisso, este recurso provavelmente precisará de algumas coisas em auto para ser totalmente desenvolvido:

    1. Novo comando auto hotfix : quando executado, o projeto será lançado com uma nova versão de hotfix baseada na última tag do branch
    2. Nova funcionalidade para auto shipit : detecte se estamos em um hotfixBranch e execute auto hotfix

    Quanto a como auto hotfix deve funcionar, pode ser:

    1. a maneira de next ou canary => Novo gancho que permite ao plugin controlar como o hotfix é lançado, seja ele compatível
    2. reutilize os ganchos version e publish e torne-os capazes de liberar build sempre

    Das duas opções, acho que estou inclinado para 1 já que chamar os ganchos version e pubish uma nova maneira pode ser considerado uma mudança significativa. A desvantagem disso é que alguns dos ganchos não serão chamados de afterVersion fazendo com que alguns plug-ins não funcionem. No entanto, este é atualmente um problema para canary e next . como eles também não chamam isso de gancho. Portanto, algo com o qual não precisa se preocupar imediatamente.

    Você está interessado em tentar adicionar isso?

    Gosto da ideia, mas na prática não acho que seria tão divertido de usar. Já que o auto libera muito, você acabaria com um número louco de branches.

    oops, significava que era semelhante ao antigo suporte principal em termos de ter uma configuração de prefixo de ramificação. Definitivamente, concordo que a criação automática de branches criaria muito ruído, especialmente com a liberação frequente, 😆

    Pensando nisso, esse recurso provavelmente precisará de algumas coisas no modo automático para ser totalmente desenvolvido:

    1. Novo hotfix automático de comando: quando executado, o projeto será lançado com uma nova versão de hotfix com base na última tag do branch
    2. Nova funcionalidade para envio automático: detectar se estamos em um hotfixBranch e executar o hotfix automático

    sim. Acho que isso resumiria em grande parte as mudanças necessárias.

    Quanto a como o hotfix automático deve funcionar, pode ser:

    1. the way of next ou canary => Novo gancho que permite ao plugin controlar como o hotfix é lançado, seja ele compatível
    2. reutilizar a versão e publicar ganchos e torná-los capazes de liberar o build semver

    Das duas opções, acho que estou inclinado para a 1, já que chamar a versão e ganchos pubish de uma nova maneira pode ser considerada uma mudança revolucionária. A desvantagem disso é que alguns dos ganchos não serão chamados após a versão, fazendo com que alguns plug-ins não funcionem. Este é atualmente um problema tanto para o canário quanto para o próximo. como eles também não chamam isso de gancho. Portanto, algo com o qual não precisa se preocupar imediatamente.

    De alto nível, acho que também faz sentido. Eu precisaria rastrear o código para ter uma melhor compreensão de quais ganchos são chamados para cada comando, mas se next , canary , & hotfix todos seguem padrões semelhantes, então, qualquer ponto problemático provavelmente seria mais fácil de resolver mais tarde.


    Você está interessado em tentar adicionar isso?

    Claro 👍, eu ficaria feliz.
    Provavelmente, não poderei dar uma olhada na implementação disso até a próxima semana, mas acho que está tudo bem, pois esse problema não foi atualizado desde março.

    Incrível! Nenhum trabalho planejado neste, então é só você

    FWIW - Eu estava tentando construir isso como um plugin, fazendo exatamente o que você considerou uma escolha inferior - fazendo um branch version-MAJOR-MINOR . Não parece muito barulho em relação ao nosso processo atual, TBH. Já criamos branches para cada linha de lançamento.

    A maior parte de versionBranches agora é este plugin :

        this.hooks.beforeCommitChangelog.tapPromise(
          "Old Version Branches",
          async ({ bump }) => {
            if (bump === SEMVER.major && this.config?.versionBranches) {
              const branch = `${this.config.versionBranches}${major(
                await this.hooks.getPreviousVersion.promise()
              )}`;
    
              await execPromise("git", [
                "branch",
                await this.git?.getLatestTagInBranch(),
              ]);
              await execPromise("git", ["push", this.remote, branch]);
            }
          }
        );
    

    Parece trivial adicionar suporte para SEMVER.minor , mas admito que não sei quais outras partes do automóvel precisam ser alteradas.

    Isso é parte do que acontece com a versão antiga, mas essa verificação em shipit também tem que ser aprovada

    https://github.com/intuit/auto/blob/f37945b45b7fef6ffdb00ffa0250de449e02b883/packages/core/src/auto.ts#L1442

    O que então vai para aqui e basicamente substitui onde começar a calcular a liberação

    https://github.com/intuit/auto/blob/f37945b45b7fef6ffdb00ffa0250de449e02b883/packages/core/src/auto.ts#L1509

    A única consideração que devemos fazer com o antigo menor / patch e não com o principal é a possível incompatibilidade de versão. Com menores, é provavelmente menos problemático

    *  (tag: v2.0.0) (master)
    | 
    *  (tag: v1.1.1)
    |
    |  *  (tag: v1.1.2) <- Need to add logic to find an available tag 
    | /
    *  (tag: v1.1.0) (hotfix-feature)
    |
    *  (tag: v1.0.0)
    

    Portanto, talvez o comando hotfix não seja necessário. Em vez disso, ele pode apenas tentar um número de versão exclusivo. Pode ser necessário haver alguma validação em torno disso.

    Regras :

    1. não é possível liberar major em qualquer branch de liberação de patch / secundário antigo (obrigatório)
    2. não é possível lançar o menor em qualquer branch de lançamento de patch antigo (talvez desnecessário?)

    @hipstersmoothie
    Você sabe qual é o comportamento padrão agora se você configurou ci para construir a partir de uma tag mais antiga, onde a próxima tag não está disponível?

    Meu palpite, haveria uma falha, embora eu não tenha certeza de onde esse erro ocorreria (talvez no envio de tag?).

    ie:

    *  (tag: v2.0.0) (master)
    | 
    *  (tag: v1.1.1)
    |
    |  *   <- what is current behavior if I try to release this commit
    | /
    *  (tag: v1.1.0) 
    |
    *  (tag: v1.0.0)
    

    Além de aplicar as regras especificadas por @hipstersmoothie , vejo um problema / confusão em potencial com a estratégia / implementação try to unique version number . Para o exemplo que @hipstersmoothie deu o exemplo, v1.1.2 seria visto por outros como um lançamento de patch de v1.1.1 , mas como o desenvolvimento não foi linear, isso não é garantido. Potencialmente, pode até haver uma alteração incompatível com versões anteriores de v1.1.1 para v1.1.2 pois é provável que v1.1.2 não tenha as alterações de v1.1.1 . Isso pode se tornar exacerbado e mais confuso se a próxima versão exclusiva estiver a uma distância maior de v1.1.0 (ou seja: e se a próxima versão exclusiva for v1.1.100 ?)

    Utilizar a parte dos metadados de compilação do semver limitaria essa confusão, pois, de acordo com as especificações do semver, eles são ignorados ao calcular a precedência da versão. Se for incrementar o número de metadados de construção, talvez o commit sha possa ser usado em vez de um número incremental.

    Em geral, o desenvolvimento de software não é necessariamente linear, portanto, não tenho certeza se há uma melhor implementação.


    Se quisermos generalizar, talvez possamos ter algum tipo de configuração ou gancho para especificar a estratégia acima, independentemente do branch (ou o branch pode ser um parâmetro para o gancho).
    Dessa forma, diferentes implementações podem ser utilizadas por meio de plug-ins.

    Você sabe qual é o comportamento padrão agora se você configurou ci para construir a partir de uma tag mais antiga, onde a próxima tag não está disponível?

    Normalmente as tags não são construídas porque o commit tem [skip ci] na mensagem

    Isso pode se tornar exacerbado e mais confuso se a próxima versão exclusiva estiver a uma distância maior da v1.1.0

    Este é um ótimo ponto. Definitivamente, torna a parte de metadados de compilação da versão a estratégia certa.

    Se quisermos generalizar, talvez possamos ter algum tipo de configuração ou gancho para especificar a estratégia acima, independentemente do branch (ou o branch pode ser um parâmetro para o gancho).
    Dessa forma, diferentes implementações podem ser utilizadas por meio de plug-ins.

    sua postagem me convenceu de que encontrar uma tag exclusiva é um esquema confuso para disparar e provavelmente não deveríamos.

    Talvez se fizermos uma mixagem, poderia funcionar. Remendar e remendar antigo deve ser fácil. Ele poderia funcionar exatamente da mesma maneira que oldVersionBranches para grandes empresas:

    *  (tag: v2.0.0) (master)
    | 
    *  (tag: v1.2.0)
    |
    |  *  (tag: v1.1.5) <- Can merge patched into old minor branch, maybe error when PR has `minor`
    | /
    *  (tag: v1.1.4) <- branch: version-1.1
    |
    *  (tag: v1.0.0)
    

    Então, só precisamos fazer a parte dos metadados de compilação para corrigir os patches.

    Com as opções from e useVerion mescladas, existe uma maneira integrada de fazer um hotfix? Eu só tinha que fazer um hoje e optei por fazê-lo dolorosamente manualmente.

    Para contextualizar, meu projeto está em 7.7. Um grande consumidor de nosso projeto está lançando uma versão que está no 7.5, encontrou um problema e exigiu o 7.5.1 para que eles não precisassem refazer o controle de qualidade de tudo no meio do lançamento. Não é ideal, mas acontece ocasionalmente.

    Ainda não há maneira de fazer isso que eu saiba sem intervenção manual. Acho que alguém internamente aqui na intuição planeja adicionar isso eventualmente. Eu concordo que esse é um recurso que falta no automóvel

    É incrível ouvir! Obrigado 🙏

    Nós (eu e @ 10hendersonm) desenvolvemos uma solução para isso, mas é bastante
    envolvidos. No entanto, ele usa apenas auto e plug-ins!

    Acabamos de corrigir 7.2.1, 8.1.1 e 8.2.2 de nosso projeto usando apenas PRs
    (muito cuidado).

    Poderíamos descobrir como compartilhar isso se as pessoas estiverem interessadas?

    Em quinta-feira, 14 de janeiro de 2021, 19h27, Matt Felten [email protected] escreveu:

    É incrível ouvir! Obrigado 🙏

    -
    Você está recebendo isto porque comentou.
    Responda a este e-mail diretamente, visualize-o no GitHub
    https://github.com/intuit/auto/issues/1054#issuecomment-760583830 ou
    Cancelar subscrição
    https://github.com/notifications/unsubscribe-auth/AACI3Q6RKDONYJVH6UWUPFLSZ6KZNANCNFSM4LFJ4ULQ
    .

    Eu estaria muito interessado!

    Olá a todos! Estou interessado em contribuir com isso. Minha proposta é a seguinte:

    1. Em geral, auto tentará respeitar quaisquer version-* branches. Por exemplo, um patch merge de qualquer branch em version-1.1.4 irá gerar um lançamento da versão 1.1.5 . Se essa versão já tiver sido criada, o lançamento do NPM ou o Git Tag falharão, mas esse é um caso de erro normal e esperado
    2. Podemos atualizar versionBranches para aceitar "major" | "minor" | "patch" , o que gerará possíveis branches de hotfix com base no que você especificar. Isso permite que você escolha a compensação entre a necessidade manual de criar um branch version-* e terminar com muitos branches para manter quando você não precisa de correções

    Pensamentos?

    mas esse é um caso de erro normal e esperado \

    Eu ainda espero que isso crie algum tipo de versão. Recentemente, tive um caso em que queria lançar um hotfix de um commit específico para não puxar mais nada. Acho que, neste caso, poderíamos usar a parte de compilação do semver da conversa acima.

    Podemos atualizar versionBranches para aceitar "major" | "menor" | "correção"

    A configuração atual pode ser true ou uma string para prefixar os ramos principais. Eu acho que a nova configuração teria que ser parecida com

    {
      "versionBranches": {
          "branchPrefix": "version-",
          "types": ["major", "minor"] // defaults to just major   
       }
    }
    

    A última pergunta a ser respondida ainda é o gancho do hotfix ou chama a versão + publicação dos ganchos olhando o código para a implementação do branch da versão antiga atual, fazemos a opção 2 e chamamos a versão + publicar (e acho que isso publica erroneamente a última tag).

    @lshadler Muitos precisam

    @bmuenzenmeyer Você pode dar uma visão geral de sua abordagem?

    Quanto mais eu penso sobre a implementação, eu acho que isso vai precisar da v11 e mais contexto adicionado à versão e comandos de publicação.

    Para versões antigas, precisamos do pipeline mais recente completo para executar com changelog, afterVersion e todos ou seus ganchos chamados durante uma versão mais recente.

    Provavelmente devemos fazer com que os próximos lançamentos tenham a mesma versão após a publicação da versão após a publicação do fluxo de publicação mais recente. Isso também pode fazer parte da v11. Ele deve corresponder ao fluxo de trabalho mais recente para que você possa adicionar automação semelhante.

    O fluxo de trabalho do canário pode permanecer o mesmo, pois nada é confirmado para um canário e você já pode simplesmente tocar no gancho do canário para fazer mais coisas.

    Olá a todos, com a loucura desse ano passado, infelizmente esse assunto me escapou.

    Em relação às diferentes abordagens, acho que pode ajudar a considerar os diferentes casos de uso para os quais esses recursos resolvem. Na minha opinião, posso ver 2 casos de uso:

    • (1) suporte de longo prazo para um ramo antigo (ou seja: versão principal antiga)
    • (2) suporte de curto prazo para uma versão específica (por exemplo: hotfix)

    Com base nessa conversa, acho que faz sentido ter abordagens distintas para cada um desses casos de uso.

    (1) Para suporte de longo prazo de um branch / release track, acredito que versionBranches deve ser capaz de resolver. Se houver um desejo de estender esse comportamento para versões secundárias (como alguns mencionaram acima), isso poderia ser um aprimoramento dessa funcionalidade.

    (2) Para suporte / hotfix de curto prazo, com base nos tópicos acima, acho que deve haver uma maneira padrão para os usuários sempre usarem a parte de compilação do Semver para gerar um lançamento de hotfix. Isso fornece um comportamento consistente para os Proprietários do Código usarem e evita alguns cenários complicados de casos extremos. Para este caso, acho que um novo comando e gancho de hotfix poderiam ser usados. Este poderia ser um aprimoramento distinto. Em geral, esse caso de uso deve ser relativamente raro, pois os consumidores devem ser encorajados a usar a versão mais recente, se possível.

    edit _ (Para o caso de uso de curto prazo, potencialmente versionBranches config poderia ser estendido para permitir um parâmetro / toggle / flag que indica se deve honrar os rótulos semver para os ramos version- ou sempre utilizar a parte de construção do semver e ignorar quaisquer rótulos para esses ramos) _


    Existem outros casos de uso além desses 2 que devem ser considerados?

    Devem ser consideradas diferentes abordagens para diferentes casos de uso?

    (Além disso, ainda posso ajudar com algumas dessas mudanças, mas definitivamente não quero bloquear ninguém de assumir as mudanças para isso)

    também, um pensamento tangencial para padrões de ramificação:

    auto irá gerar uma tag git (lançamento) para lançamentos. Isso significa que um git ref válido é enviado ao github. Para o caso de uso de suporte de curto prazo (ou seja: branch de curta duração / branch de hotfix), isso significa que um usuário pode excluir o branch de curta duração após uma tag release / git ter sido enviada.

    ou seja (clique aqui para ver o cenário de exemplo)

    • dado um branch master com as seguintes tags
      <ul> <li>(tag: v1.3.0) (master)<br /> | </li> <li>(tag: v1.2.3)<br />

  • crie um novo branch de curta duração a partir de um commit específico (ou seja: hotfix-1.2.3 )
    <ul> <li>(tag: v1.3.0) (master)<br /> | </li> <li>(tag: v1.2.3) (hotfix-1.2.3)<br />

  • empurrar mudanças / mesclar PRs em um ramo de curta duração
    <ul> <li>(tag: v1.3.0) (master)<br /> |<br /> | * (hotfix-1.2.3)<br /> | /</li> <li>(tag: v1.2.3)<br />

  • que pode gerar um novo lançamento / tag na fusão de PR
    <ul> <li>(tag: v1.3.0) (master)<br /> |<br /> | * (tag: v1.2.3+1) (hotfix-1.2.3)<br /> | /</li> <li>(tag: v1.2.3)<br />

  • uma vez que a nova tag é uma referência git válida rastreada pelo github, isso significa que os proprietários do código podem excluir o branch de vida curta e ainda ter referência ao novo commit / release por meio da tag ( v1.2.3+1 )
    <ul> <li>(tag: v1.3.0) (master)<br /> |<br /> | * (tag: v1.2.3+1)<br /> | /</li> <li>(tag: v1.2.3)<br />

  • Para ramificações de curta duração, pode ser bom documentar o padrão de ramificação acima ao adicionar um recurso. Eu pessoalmente descobri que muitos não estão cientes de que você pode deletar o branch e ainda ter referência ao novo commit, o que pode ajudar diferentes projetos a reduzir a confusão de branches de vida curta.

    Recentemente, estava brincando com o código para utilizar a parte de compilação do Semver para criar compilações. Enquanto fazia isso, me deparei com o caso de uso em que a versão mais recente do github não era necessariamente a versão semântica mais recente / mais alta.

    Por exemplo, no exemplo mencionado aqui: https://github.com/intuit/auto/issues/1054#issuecomment -780286683, a versão mais recente do github seria exibida como v1.2.3+1 pois foi criada temporariamente após a maior versão versão semântica: v1.3.0 .

    Como alguns lugares na referência de código getLatestRelease , isso pode levar a comportamentos variados se o pipeline não definir explicitamente o parâmetro from . ie:

    • o que está incluído nas notas de lançamento
    • como a versão anterior é calculada
    • potencialmente interrompendo a funcionalidade se a versão mais recente do github não estiver acessível a partir do commit HEAD

    Não testei, mas acredito que esses tipos de cenários também seriam alcançáveis ​​por meio do comportamento existente de versionBranches . Acredito que isso esteja relacionado ao comentário sobre quais fluxos devem gerar tags git / versões do github:

    A última pergunta a ser respondida ainda é o gancho do hotfix ou chama a versão + publicação dos ganchos olhando o código para a implementação do branch da versão antiga atual, fazemos a opção 2 e chamamos a versão + publicar (e acho que isso publica erroneamente a última tag).


    Em termos de resolução, esse problema provavelmente pode ser resolvido independentemente da refatoração de gancho, substituindo a lógica getLatestRelease por:

    • (1) buscar lançamentos do github usando listReleases e, em seguida, classificar para encontrar a versão de lançamento mais alta (sem pré-lançamento ou partes de compilação) que esteja acessível
    • (2) ou busque as tags git e, em seguida, classifique para encontrar a versão mais recente (sem pré-lançamento ou partes de compilação) que esteja acessível

    A diferença aqui seria se auto vê lançamentos github ou tags git como fonte da verdade, o que está relacionado à discussão https://github.com/intuit/auto/discussions/1867#discussioncomment -684192.

    Eu inicialmente me inclinaria para (2), como

    • (a) estamos, em última análise, atrás do git ref (tag) e não dos outros elementos do lançamento do github
    • (b) reduziria o número de chamadas de rede

    @hipstersmoothie ,
    Se precisarmos modificar a lógica getLatestRelease , o que você acha de (1) usar versões do github vs (2) usar tags git vs (3) outra coisa?

    Sim, para que o multi package auto funcione, será necessário refatorar todas as últimas versões do GitHub para apenas tags. 2 é def a opção a seguir para concluir este trabalho.

    Esta página foi útil?
    0 / 5 - 0 avaliações