10 min de leituraIntegrações

Encurte links nas notas de release e rastreie cada download

Encurte links nas notas de release com um link estável para a versão mais recente, que você redireciona a cada release, um link marcado por canal e dados de cliques que mostram o que gerou os downloads.

Marius Voß
DevRel · edge infra
Capa em estilo pixel mostrando como encurtar links nas notas de release: um link estável para a versão mais recente, redirecionado de v2.3 para v2.4, com links marcados separados para Slack, X e a newsletter

As notas de release chegam mais longe do que quase tudo que uma equipe de engenharia escreve. Ninguém as mede. Você cola um link de download no corpo do release, alguém o copia para o Slack, o marketing o coloca na newsletter, um mantenedor publica no X. Seis meses depois, metade desses links aponta para um arquivo que já não existe, e nenhum deles informou coisa alguma. Para encurtar links nas notas de release corretamente, você precisa de três coisas: um link curto estável para a versão mais recente, que você redireciona a cada release, um link marcado separado por canal para cada versão e um workflow no evento release: published que crie ambos, para que ninguém precise se lembrar.

Essa é a resposta inteira. O restante deste post mostra como conectar tudo sem criar uma bagunça e o que os dados de cliques podem e não podem informar depois.

Já vi muitos projetos gerenciarem manualmente os links das notas de release do GitHub, e o modo como dá errado é sempre o mesmo: alguém cria um link para um asset versionado, o link é citado em um tópico de fórum ou em uma resposta no Stack Overflow, e o release seguinte o deixa órfão silenciosamente. Se você já gerencia links como código, a abordagem abaixo se encaixa ao lado de links curtos gerenciados no Terraform, com a diferença de que os links de release mudam em uma agenda que você não controla manualmente.

Há dois problemas separados aqui. Eles precisam de correções diferentes.

O primeiro é a deterioração dos links. O GitHub oferece URLs estáveis para a página do release (/releases/latest) e para arquivos, por meio de /releases/latest/download/asset-name, mas o segundo só funciona quando o asset mantém um nome idêntico entre os releases, de acordo com a documentação do próprio GitHub sobre links para releases. A maioria dos pipelines de build coloca a versão no nome do arquivo, então app-2.3.0.dmg vira app-2.4.0.dmg, e a URL de download da versão mais recente que funcionava na semana passada agora retorna um 404. Links da documentação também quebram quando um site de documentação é reorganizado. Os padrões mais amplos estão na nossa estratégia de prevenção de deterioração de links; as notas de release são apenas o lugar onde isso dói mais, porque os links chegam mais longe.

O segundo problema é a atribuição, e ele é mais silencioso. A API REST do GitHub informa um download_count em cada asset de release, o que já é mais do que a maioria das pessoas imagina. O que ela não informa é de onde veio o download. Um pico de 4.000 downloads no dia seguinte ao release pode ser a newsletter, um tópico no Hacker News ou o CI de um único cliente corporativo baixando o binário em loop. Links colados no Slack e em DMs removem completamente o referenciador, que é o problema de atribuição do dark social em miniatura.

Crie um link curto, por exemplo get.example.dev/latest, e trate-o como um ponteiro. Todas as páginas da documentação, badges do README e scripts de instalação usam esse link. A cada release estável, você atualiza o destino para o qual ele aponta. O slug nunca muda, então nada que o tenha citado deixa de funcionar.

No Elido, esse ponteiro é um link comum. Você o cria uma vez com POST /v1/workspaces/{workspace_id}/links, passando o domain_id do seu domínio com marca própria, o slug e o destination_url. Salve o id da resposta 201. O redirecionamento é um PATCH /v1/workspaces/{workspace_id}/links/{link_id} com um novo destination_url e nada mais; o slug, as tags e o histórico de cliques permanecem.

Mantenha-o como 302. Os links do Elido usam 302 por padrão, e há um motivo para não mudar isso neste caso: um 301 pode ser armazenado em cache por padrão segundo a RFC 9110, então um navegador que viu o redirecionamento do mês passado talvez nunca pergunte de novo. Um ponteiro que os navegadores lembram para sempre deixa de ser um ponteiro. Saiba mais em redirecionamentos 301 vs 302 para links curtos.

Diagrama de um link curto estável para a versão mais recente sendo redirecionado do download de v2.3.0 para o download de v2.4.0 quando um release é publicado, enquanto os links por release de v2.3.0 continuam apontando para a própria tag

Decida uma coisa de antemão. O link para a versão mais recente deve apontar para o arquivo ou para a página do release? Eu o apontaria para a página do release em qualquer caso com mais de um build de plataforma e manteria links para a versão mais recente por plataforma (/latest-mac, /latest-linux) apenas se a documentação de instalação realmente precisar de um arquivo direto. Menos ponteiros móveis significam menos coisas para redirecionar errado.

O link para a versão mais recente responde a "o link ainda funciona". Ele não pode responder a "qual canal funcionou", porque todo mundo clica no mesmo slug. Para isso, cada release recebe seu próprio pequeno conjunto de links, um por canal, criados no momento da publicação.

Esta é a parte que a maioria dos guias de UTM deixa de fora. Acrescentar utm_source=slack a uma URL do github.com não faz nada útil, porque você nunca verá as análises do GitHub. Os UTMs só merecem seu lugar quando o destino é um site que você mede, como a sua documentação ou a sua própria página de download. Quando o destino é o GitHub, o link curto separado por canal é a atribuição: o clique é contado no redirecionamento, antes de o GitHub sequer vê-lo.

CanalSlug para v2.4.0DestinoO que os cliques informam
Comunidade do Slackv2-4-0-slackPágina do release no GitHubCliques da sua própria comunidade
X / Mastodonv2-4-0-socialPágina do release no GitHubAlcance além dos usuários atuais
Newsletterv2-4-0-newsGuia de atualização da documentação + UTMsCliques e comportamento no site nas suas análises
Mais recente (estável)latestRelease atual, redirecionadoDemanda total em todas as versões

Marque cada link por release com a versão e o canal (["release", "v2.4.0", "slack"]), porque é assim que você recuperará o conjunto mais tarde: GET .../links?tags=v2.4.0 lista tudo de um release. Mantenha os valores de UTM simples e idênticos entre os releases. O guia de convenções de nomenclatura de UTM traz as regras que eu copiaria.

Um guia relacionado aborda a criação genérica de links no CI, então esta seção fica apenas com as partes específicas de releases. O gatilho é release com o tipo de atividade published. De acordo com a lista de eventos de workflow do GitHub, published é acionado tanto para releases estáveis quanto para pré-releases, incluindo pré-releases publicados a partir de um rascunho, exatamente por isso a etapa de redirecionamento abaixo verifica a flag prerelease.

name: release-links
on:
  release:
    types: [published]

jobs:
  links:
    runs-on: ubuntu-latest
    env:
      API: https://api.elido.app/v1/workspaces/${{ vars.ELIDO_WORKSPACE_ID }}
      DOMAIN_ID: ${{ vars.ELIDO_DOMAIN_ID }}
      TAG: ${{ github.event.release.tag_name }}
      PAGE: ${{ github.event.release.html_url }}
      ELIDO_TOKEN: ${{ secrets.ELIDO_TOKEN }}
    steps:
      - name: Create one link per channel
        run: |
          v=$(echo "$TAG" | tr '.' '-')
          for ch in slack social news; do
            body=$(jq -n --argjson d "$DOMAIN_ID" --arg s "$v-$ch" \
              --arg u "$PAGE" --arg t "$TAG" --arg c "$ch" \
              '{domain_id:$d, slug:$s, destination_url:$u, tags:["release",$t,$c]}')
            code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "$API/links" \
              -H "Authorization: Bearer $ELIDO_TOKEN" \
              -H "Content-Type: application/json" -d "$body")
            case "$code" in 201|409) ;; *) echo "create $ch failed: $code"; exit 1;; esac
            echo "- $ch: https://get.example.dev/$v-$ch" >> "$GITHUB_STEP_SUMMARY"
          done

      - name: Repoint the latest link
        if: ${{ !github.event.release.prerelease }}
        run: |
          curl -sf -X PATCH "$API/links/${{ vars.ELIDO_LATEST_LINK_ID }}" \
            -H "Authorization: Bearer $ELIDO_TOKEN" \
            -H "Content-Type: application/json" \
            -d "$(jq -n --arg u "$PAGE" '{destination_url:$u}')"

O resumo do job fornece a quem publica o anúncio uma lista pronta de links, e um 409 em uma nova execução significa que o slug já existe, então um workflow repetido não falha nem duplica nada. O link da newsletter apontaria para a sua documentação com UTMs no destino; eu o deixei na página do release aqui para manter o exemplo curto.

Três armadilhas que me custaram uma tarde

A primeira é silenciosa. Se o pipeline de release publicar o release usando o GITHUB_TOKEN padrão, este workflow nunca será executado, porque eventos criados com GITHUB_TOKEN não acionam novas execuções de workflow. Nenhum erro, nenhum job ignorado, nada. Publique usando um token de GitHub App.

Segundo, os pontos. Eu converto v2.4.0 em v2-4-0 para o slug porque strings de versão com pontos parecem extensões de arquivo nas prévias de chat, e alguns clientes as transformam em links de maneira estranha.

Terceiro, não deixe o workflow editar o corpo do release a menos que seja necessário. Funciona (gh release edit --notes-file), mas reescreve um texto que uma pessoa acabou de aprovar e dispara eventos edited aos quais outras automações podem reagir. O resumo da etapa é menos engenhoso e muito mais seguro. Os retries ficam para outro post: limites de taxa e idempotência da API.

Se você ainda cola links de release manualmente, o workflow acima leva cerca de vinte minutos para ser configurado. Comece um workspace Elido gratuito, aponte um domínio com marca própria para ele e deixe a próxima tag criar seus próprios links.

Como rastrear cliques nas notas de release por canal

Depois de dois ou três releases, os dados começam a responder a perguntas que o contador do GitHub não consegue responder.

A comparação por canal é a mais simples. Busque os links marcados com uma versão e depois leia o resumo de cliques de cada link com escopo por link_id. Se v2-4-0-news superar v2-4-0-social por cinco a um durante três releases seguidos, você descobriu onde seus usuários realmente estão, e raramente é onde a equipe imaginava. O anúncio com mais curtidas muitas vezes não é o que envia pessoas para o download, então espere resistência na primeira vez que mostrar os números e aguarde o terceiro release consecutivo antes de alguém reescrever o plano de lançamento com base neles.

O link para a versão mais recente tem um truque menos óbvio. Cada clique registra o destino que foi resolvido naquele momento, então a divisão das análises por destino, com escopo no link para a versão mais recente, separa o tráfego por versão. Depois de um redirecionamento, você pode observar a participação do destino antigo cair e ver por quanto tempo pessoas atrasadas continuam chegando por páginas armazenadas em cache e favoritos antigos. Essa é a sua curva real de atualização, medida no topo do funil.

Diagrama mostrando como rastrear cliques nas notas de release: links do Slack, das redes sociais e da newsletter para um release alimentam contagens de cliques por link, enquanto o link para a versão mais recente divide os cliques por versão de destino

Há duas limitações honestas. Cliques não são downloads: alguém pode clicar até a página do release e sair, e o download_count do GitHub continua sendo a fonte de verdade para os downloads concluídos. Além disso, bots clicam em links de release, especialmente buscadores de prévias de links em aplicativos de chat, então leia as tendências entre os releases em vez de confiar em um único dia. A página do recurso de análises lista quais divisões estão disponíveis em cada plano.

Os links por release nunca mudam. v2-3-0-slack aponta para a tag v2.3.0 em março e continua apontando para ela daqui a cinco anos, que é o que alguém lendo um tópico antigo de fórum espera. Apenas o link para a versão mais recente muda, e somente em releases estáveis.

O único caso em que você deve mexer em um link antigo é quando um release é retirado. Se v2.4.0 for lançado com um bug de perda de dados, não exclua os links; redirecione todos os links v2-4-0-* para v2.4.1 com a mesma chamada PATCH e uma nota curta no corpo do release. Excluir deixa quem salvou o link sem saída exatamente no momento em que mais precisa da correção. Uma versão mais nova é melhor do que um 404. Sempre.

Para projetos que também mantêm links antigos de release em READMEs, scripts de instalação e metadados de gerenciadores de pacotes, o guia de encurtadores de URL voltado para desenvolvedores mostra onde mais os links curtos são úteis. A superfície REST completa está na página de API e SDKs.

Leia o artigo principal → Gerencie seus links curtos como Terraform

Relacionado no Blog

Perguntas frequentes

Como faço um link para o release mais recente do GitHub?

O GitHub oferece /releases/latest para a página do release e /releases/latest/download/asset-name para um arquivo, desde que o asset mantenha o mesmo nome em todos os releases. Se os nomes dos seus assets contêm o número da versão, coloque um link curto na frente e redirecione-o a cada release.

É possível rastrear cliques nos downloads de releases do GitHub?

Parcialmente. A API REST do GitHub informa um download_count por asset de release, mas não traz dados de referenciador, país ou canal, então não é possível saber se o download veio do Slack, do X ou de uma newsletter. Um link curto por canal na frente do asset fornece essa divisão.

Um link curto para o release mais recente deve usar um redirecionamento 301 ou 302?

Use um 302. Os navegadores podem armazenar um 301 em cache indefinidamente, então alguém que clicou no mês passado pode continuar chegando à versão antiga depois que você redirecionar o link. Os links do Elido usam 302 por padrão, mantendo o destino sob seu controle a cada clique.

Por que meu workflow de release não é executado quando outro workflow publica o release?

Eventos criados com o GITHUB_TOKEN do repositório não iniciam novas execuções de workflow, exceto workflow_dispatch e repository_dispatch. Se um pipeline de release publica com GITHUB_TOKEN, o gatilho release: published nunca é acionado. Publique usando um token de GitHub App ou um token pessoal com permissões granulares.

Os parâmetros UTM funcionam em links para github.com?

Eles são transmitidos, mas não fazem nada por você, porque você nunca vê as análises do GitHub. Os UTMs só valem a pena quando o destino é um site que você mede, como a sua documentação ou a sua página de download. Para destinos em github.com, o link curto separado por canal é a atribuição.

O que acontece com os links antigos de release quando uma nova versão é lançada?

Nada, se você configurar tudo dessa forma. Os links por release continuam apontando para a própria tag para sempre, e apenas o link para a versão mais recente muda. Se um release for retirado, redirecione os links dele para a versão corrigida em vez de excluí-los, para que quem salvou o link antigo ainda chegue a algum lugar útil.

Experimente Elido

Cole uma URL, obtenha um link curto

Sem cadastro. O link vive 30 dias. Cadastre-se para mantê-lo para sempre.

Grátis, sem necessidade de registo · 2 por dia

Experimente o Elido

Encurtador de URL hospedado na UE: domínios personalizados, análises profundas e API aberta. Plano gratuito - sem cartão de crédito.

Tags
shorten links in release notes
github release notes links
track clicks on release notes
github actions
release automation
link rot

Continuar lendo