Release notes reizen verder dan bijna alles wat een engineeringteam schrijft. Niemand meet ze. Je plakt een downloadlink in de releasetekst, iemand kopieert hem naar Slack, marketing zet hem in de nieuwsbrief, een maintainer post hem op X. Zes maanden later wijst de helft van die links naar een bestand dat niet meer bestaat en geen enkele heeft je iets verteld. Om links in release notes goed te verkorten heb je drie dingen nodig: één stabiele korte "latest"-link die je bij elke release omzet, een aparte getagde link per kanaal voor elke versie, en een workflow op het event release: published die beide aanmaakt zodat niemand eraan hoeft te denken.
Dat is het hele antwoord. De rest van dit artikel gaat over hoe je dit aansluit zonder rommel te maken, en wat de klikdata je achteraf wel en niet kan vertellen.
Ik heb veel projecten GitHub-releasenoteslinks met de hand zien afhandelen, en de faalwijze is altijd dezelfde: iemand linkt naar een geversioneerd asset, de link wordt geciteerd in een forumthread of een Stack Overflow-antwoord, en de volgende release maakt hem ongemerkt wees. Beheer je links al als code, dan past de aanpak hieronder naast korte links beheerd in Terraform, met dit verschil dat releaselinks veranderen volgens een schema dat je niet met de hand beheert.
Waarom releasenoteslinks verrotten en attributie verliezen
Hier zitten twee aparte problemen. Ze vragen verschillende oplossingen.
Het eerste is linkrot. GitHub geeft je stabiele URL's voor de releasepagina (/releases/latest) en voor bestanden, via /releases/latest/download/asset-name, maar die tweede werkt alleen als het asset in alle releases een identieke naam houdt, volgens de eigen docs van GitHub over linken naar releases. De meeste buildpipelines stempelen de versie in de bestandsnaam, dus app-2.3.0.dmg wordt app-2.4.0.dmg en de "latest"-download-URL die vorige week werkte geeft nu een 404. Doclinks verrotten ook, zodra een docssite wordt herorganiseerd. De bredere patronen staan in onze strategie tegen linkrot; releasenotes zijn gewoon de plek waar het het hardst bijt, omdat de links het verst reizen.
Het tweede probleem is attributie, en dat is stiller. De REST-API van GitHub meldt wel een download_count per release-asset, wat meer is dan de meeste mensen weten. Wat hij niet meldt is waar de download vandaan kwam. Een piek van 4.000 downloads de dag na de release kan de nieuwsbrief zijn, een Hacker News-thread of de CI van één enkele enterpriseklant die het binary in een lus ophaalt. Links die in Slack en DM's worden geplakt, verliezen de referrer volledig, wat het probleem van dark social-attributie in het klein is.
Een stabiele latest-link die je per release omzet
Maak één korte link, bijvoorbeeld get.example.dev/latest, en behandel hem als een wijzer. Elke docspagina, README-badge en installatiescript gebruikt hem. Bij elke stabiele release werk je bij waar hij heen wijst. De slug verandert nooit, dus niets wat hem citeerde gaat ooit kapot.
In Elido is die wijzer een gewone link. Je maakt hem één keer aan met POST /v1/workspaces/{workspace_id}/links, met het domain_id van je eigen domein, de slug en de destination_url. Bewaar de id uit het 201-antwoord. Omzetten is een PATCH /v1/workspaces/{workspace_id}/links/{link_id} met een nieuwe destination_url en verder niets; de slug, tags en klikgeschiedenis blijven staan.
Houd hem op een 302. Elido-links hebben standaard 302, en er is een reden om dat voor deze niet te wijzigen: een 301 is standaard cachebaar onder RFC 9110, dus een browser die de redirect van vorige maand zag, vraagt het misschien nooit meer. Een wijzer die browsers voor altijd onthouden is geen wijzer meer. Meer in 301 vs 302-redirects voor korte links.
Beslis vooraf één ding. Moet de latest-link naar het bestand wijzen of naar de releasepagina? Ik zou hem naar de releasepagina laten wijzen voor alles met meer dan één platformbuild, en latest-links per platform (/latest-mac, /latest-linux) alleen houden als je installatiedocs echt een direct bestand nodig hebben. Minder bewegende wijzers betekent minder dingen die je verkeerd kunt omzetten.
Taggen per release voor GitHub-releasenoteslinks
De latest-link beantwoordt "werkt de link nog". Hij kan niet beantwoorden "welk kanaal werkte", omdat iedereen dezelfde slug aanklikt. Daarvoor krijgt elke release een eigen kleine set links, één per kanaal, aangemaakt op het moment van publiceren.
Dit is het deel dat de meeste UTM-gidsen overslaan. utm_source=slack achter een github.com-URL plakken doet niets nuttigs, omdat je de analytics van GitHub nooit ziet. UTM's verdienen hun plek alleen als de bestemming een site is die je meet, zoals je docs of je eigen downloadpagina. Is de bestemming GitHub, dan is de aparte korte link per kanaal de attributie: de klik wordt geteld bij de redirect, voordat GitHub hem ooit ziet.
| Kanaal | Slug voor v2.4.0 | Bestemming | Wat de klikken vertellen |
|---|---|---|---|
| Slack-community | v2-4-0-slack | GitHub-releasepagina | Klikken uit je eigen community |
| X / Mastodon | v2-4-0-social | GitHub-releasepagina | Bereik voorbij bestaande gebruikers |
| Nieuwsbrief | v2-4-0-news | Upgradegids in docs + UTM's | Klikken plus gedrag op de site in je analytics |
| Latest (stabiel) | latest | Huidige release, omgezet | Totale vraag over alle versies |
Tag elke link per release met de versie en het kanaal (["release", "v2.4.0", "slack"]), want met tags haal je de set later weer op: GET .../links?tags=v2.4.0 toont alles voor één release. Houd eventuele UTM-waarden saai en identiek tussen releases. De gids over UTM-naamconventies bevat de regels die ik zou overnemen.
Links maken bij het event release published
Een zusterartikel behandelt het generieke aanmaken van links in CI, dus deze sectie blijft bij de releasespecifieke delen. De trigger is release met het activiteitstype published. Volgens de lijst met workflowevents van GitHub gaat published af voor stabiele releases en pre-releases, ook pre-releases die vanuit een concept worden gepubliceerd, en daarom controleert de omzetstap hieronder de vlag 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}')"
De jobsamenvatting geeft wie de aankondiging post een kant-en-klare lijst links, en een 409 bij een herhaalde run betekent dat de slug al bestaat, zodat een opnieuw gestarte workflow niet faalt of iets dubbel maakt. De nieuwsbrieflink zou naar je docs wijzen met UTM's in de bestemming; ik heb hem hier op de releasepagina gelaten om het voorbeeld kort te houden.
Drie valkuilen die me een middag kostten
De eerste is stil. Publiceert je releasepipeline de release met de standaard GITHUB_TOKEN, dan draait deze workflow nooit, omdat events die met GITHUB_TOKEN zijn gemaakt geen nieuwe workflowruns starten. Geen fout, geen overgeslagen job, niets. Publiceer in plaats daarvan met een token van een GitHub App.
Tweede: punten. Ik zet v2.4.0 om in v2-4-0 voor de slug, omdat versiestrings met punten in chatvoorbeelden op bestandsextensies lijken en sommige clients ze vreemd linkificeren.
Derde: laat de workflow de releasetekst niet bewerken tenzij het moet. Het kan (gh release edit --notes-file), maar het herschrijft tekst die een mens net heeft goedgekeurd, en het veroorzaakt edited-events waar andere automatiseringen op kunnen reageren. De stapsamenvatting is minder slim en veel veiliger. Retries krijgen een eigen artikel: API-limieten en idempotentie.
Plak je releaselinks nog met de hand, dan kost de workflow hierboven zo'n twintig minuten instellen. Start een gratis Elido-werkruimte, wijs een eigen domein ernaartoe en laat de volgende tag zijn eigen links maken.
Klikken op release notes per kanaal volgen
Na twee of drie releases begint de data vragen te beantwoorden die de teller van GitHub niet kan.
Vergelijking per kanaal is de eenvoudige. Haal de links met een versietag op en lees dan de kliksamenvatting van elke link, afgebakend op link_id. Als v2-4-0-news drie releases op rij vijf keer zoveel oplevert als v2-4-0-social, dan weet je waar je gebruikers echt zitten, en dat is zelden waar het team van uitging. De aankondiging met de meeste likes is vaak niet die welke mensen naar de download stuurt, dus verwacht tegenwerping de eerste keer dat je de cijfers laat zien, en wacht tot de derde release op rij voordat iemand het lanceringsplan eromheen herschrijft.
De latest-link heeft een minder voor de hand liggende truc. Elke klik legt de bestemming vast waar hij op dat moment naartoe oploste, dus de analyse per bestemming, afgebakend op de latest-link, splitst zijn verkeer per versie. Na een omzetting zie je het aandeel van de oude bestemming wegvallen en hoe lang nakomers op gecachete pagina's en oude bladwijzers blijven binnenkomen. Dat is je echte upgradecurve, gemeten bovenaan de funnel.
Twee eerlijke grenzen. Klikken zijn geen downloads: iemand kan doorklikken naar de releasepagina en weggaan, en de download_count van GitHub blijft de bron van waarheid voor voltooide downloads. En bots klikken wel degelijk op releaselinks, vooral de linkpreview-fetchers in chat-apps, dus lees trends over releases heen in plaats van één enkele dag te vertrouwen. De pagina over analytics vermeldt welke uitsplitsingen op elk abonnement beschikbaar zijn.
Oude releaselinks in leven houden
Links per release bewegen nooit. v2-3-0-slack wijst in maart naar de tag v2.3.0 en wijst er over vijf jaar nog steeds heen, wat iemand die een oude forumthread leest verwacht. Alleen de latest-link verandert, en alleen bij stabiele releases.
Het enige geval waarin je een oude link moet aanraken is een ingetrokken release. Komt v2.4.0 uit met een dataverliesbug, verwijder dan de links niet; zet elke v2-4-0-*-link om naar v2.4.1 met dezelfde PATCH-aanroep en een korte notitie in de releasetekst. Verwijderen geeft mensen die de link bewaarden een doodlopende weg op precies het moment dat ze de oplossing het hardst nodig hebben. Een nieuwere versie wint van een 404. Altijd.
Voor projecten die ook oude releaselinks in README's, installatiescripts en metadata van pakketbeheerders bewaren, behandelt de gids over URL-verkorters voor ontwikkelaars waar korte links nog meer hun waarde bewijzen. Het volledige REST-oppervlak staat op de pagina API en SDK's.
Lees de cornerstone → Beheer je korte links als Terraform
Gerelateerd op de blog
- Strategie tegen linkrot - het bredere draaiboek voor links die langer moeten leven dan de pagina waar ze naar wijzen.
- Quickstart voor de URL-verkorter-API - authenticatie, SDK's en de aanmaakaanroep uit de workflow.
- URL-verkorter-CLI - dezelfde handelingen vanuit een terminal, voor losse releases.
- Slack-bot voor URL-verkorting - links verkorten waar de releaseaankondiging echt landt.
- 301 vs 302-redirects - waarom een omzetbare link tijdelijk moet blijven.
- Korte links vanuit GitHub Actions - de generieke stap voor aanmaken of bijwerken in elke workflow.
Veelgestelde vragen
Hoe link ik naar de nieuwste GitHub-release?
GitHub ondersteunt /releases/latest voor de releasepagina en /releases/latest/download/asset-name voor een bestand, zolang het asset in elke release dezelfde naam houdt. Staat het versienummer in je assetnamen, zet dan een korte link ervoor en zet die bij elke release om.
Kun je klikken op GitHub-releasedownloads volgen?
Deels. De GitHub REST-API meldt een download_count per release-asset, maar heeft geen data over referrer, land of kanaal, dus je kunt er niet uit afleiden of de download uit Slack, X of een nieuwsbrief kwam. Een korte link per kanaal vóór het asset geeft je die splitsing.
Moet een korte link naar de nieuwste release een 301 of een 302 gebruiken?
Gebruik een 302. Browsers mogen een 301 onbeperkt cachen, dus een lezer die vorige maand klikte kan op de oude versie blijven landen nadat je de link hebt omgezet. Elido-links hebben standaard 302, waardoor de bestemming bij elke klik onder jouw controle blijft.
Waarom draait mijn releaseworkflow niet als een andere workflow de release publiceert?
Events die met de GITHUB_TOKEN van de repository worden gemaakt, starten geen nieuwe workflowruns, behalve workflow_dispatch en repository_dispatch. Publiceert een releasepipeline met GITHUB_TOKEN, dan gaat de trigger release: published nooit af. Publiceer in plaats daarvan met een token van een GitHub App of een fijnmazig persoonlijk toegangstoken.
Werken UTM-parameters op links naar github.com?
Ze worden doorgegeven, maar doen niets voor je, omdat je de analytics van GitHub nooit ziet. UTM's lonen alleen als de bestemming een site is die je meet, zoals je docs of downloadpagina. Voor bestemmingen op github.com is de aparte korte link per kanaal de attributie.
Wat gebeurt er met oude releaselinks als er een nieuwe versie uitkomt?
Niets, als je het zo inricht. Links per release blijven voor altijd naar hun eigen tag wijzen, en alleen de ene latest-link beweegt mee. Wordt een release ingetrokken, zet de links dan om naar de herstelde versie in plaats van ze te verwijderen, zodat mensen die de oude link bewaarden toch ergens nuttig uitkomen.
Probeer Elido
Plak een URL, krijg een werkende korte link
Geen aanmelding nodig. Link blijft 30 dagen actief. Meld je aan om hem voor altijd te bewaren.
Geen account nodig. Meld je gratis aan voor 50 links per maand.