Notele de lansare ajung mai departe decât aproape orice scrie o echipă de inginerie. Nimeni nu le măsoară. Lipești un link de descărcare în corpul lansării, cineva îl copiază în Slack, marketingul îl pune în newsletter, un maintainer îl postează pe X. Șase luni mai târziu, jumătate din acele linkuri indică un fișier care nu mai există, iar niciunul nu ți-a spus nimic. Ca să scurtezi corect linkurile din notele de lansare, ai nevoie de trei lucruri: un singur link scurt „latest" stabil, pe care îl repoziționezi la fiecare lansare, un link etichetat separat per canal pentru fiecare versiune și un workflow pe evenimentul release: published care le creează pe amândouă, ca nimeni să nu trebuiască să își amintească.
Acesta este răspunsul întreg. Restul articolului arată cum le conectezi fără să faci dezordine și ce îți pot și ce nu îți pot spune datele de clic după aceea.
Am văzut multe proiecte gestionând de mână linkurile din notele de lansare GitHub, iar modul de eșec e mereu același: cineva face link către un asset cu versiune, linkul e citat într-un thread de forum sau într-un răspuns Stack Overflow, iar următoarea lansare îl lasă orfan în tăcere. Dacă îți gestionezi deja linkurile ca cod, abordarea de mai jos se așază lângă linkurile scurte gestionate în Terraform, cu diferența că linkurile de lansare se schimbă după un program pe care nu îl controlezi de mână.
De ce putrezesc linkurile din notele de lansare și pierd atribuirea
Aici se ascund două probleme separate. Au nevoie de remedii diferite.
Prima este putrezirea linkurilor. GitHub îți oferă URL-uri stabile pentru pagina lansării (/releases/latest) și pentru fișiere, prin /releases/latest/download/asset-name, dar al doilea funcționează doar când asset-ul păstrează un nume identic între lansări, conform documentației GitHub despre linkurile către lansări. Majoritatea pipeline-urilor de build pun versiunea în numele fișierului, deci app-2.3.0.dmg devine app-2.4.0.dmg, iar URL-ul de descărcare „latest" care funcționa săptămâna trecută returnează acum 404. Linkurile către documentație putrezesc și ele, ori de câte ori un site de documentație e reorganizat. Tiparele mai largi sunt în strategia noastră de prevenire a putrezirii linkurilor; notele de lansare sunt doar locul unde mușcă cel mai tare, pentru că linkurile lor călătoresc cel mai departe.
A doua problemă este atribuirea, și e mai discretă. API-ul REST GitHub raportează un download_count pe fiecare asset de lansare, ceea ce e mai mult decât realizează majoritatea oamenilor. Ce nu raportează este de unde a venit descărcarea. Un vârf de 4.000 de descărcări în ziua de după lansare poate fi newsletterul, un thread pe Hacker News sau CI-ul unui singur client enterprise care trage binarul în buclă. Linkurile lipite în Slack și în mesaje directe pierd complet referrerul, adică problema atribuirii dark social în miniatură.
Un link latest stabil, repoziționat la fiecare lansare
Creează un singur link scurt, de exemplu get.example.dev/latest, și tratează-l ca pe un pointer. Fiecare pagină de documentație, insignă din README și script de instalare îl folosește. La fiecare lansare stabilă, actualizezi spre ce indică. Slugul nu se schimbă niciodată, așa că nimic din ce l-a citat nu se rupe.
În Elido, acel pointer este un link obișnuit. Îl creezi o singură dată cu POST /v1/workspaces/{workspace_id}/links, transmițând domain_id al domeniului tău de brand, slug și destination_url. Salvează id din răspunsul 201. Repoziționarea este un PATCH /v1/workspaces/{workspace_id}/links/{link_id} cu un nou destination_url și nimic altceva; slugul, etichetele și istoricul clicurilor rămân pe loc.
Păstrează-l pe 302. Linkurile Elido folosesc implicit 302 și există un motiv să nu schimbi asta aici: un 301 poate fi reținut în cache implicit conform RFC 9110, deci un browser care a văzut redirecționarea de luna trecută poate să nu mai întrebe niciodată. Un pointer pe care browserele îl rețin pentru totdeauna nu mai este un pointer. Mai mult în redirecționări 301 vs 302 pentru linkuri scurte.
Decide un lucru din start. Ar trebui linkul latest să indice fișierul sau pagina lansării? Eu l-aș îndrepta spre pagina lansării pentru orice are mai mult de un build pe platformă și aș păstra linkuri latest per platformă (/latest-mac, /latest-linux) doar dacă documentația ta de instalare chiar are nevoie de un fișier direct. Mai puține pointere mobile înseamnă mai puține lucruri de repoziționat greșit.
Etichetare per lansare pentru linkurile din notele de lansare GitHub
Linkul latest răspunde la „mai funcționează linkul". Nu poate răspunde la „ce canal a funcționat", pentru că toți dau clic pe același slug. Pentru asta, fiecare lansare primește propriul set mic de linkuri, câte unul pe canal, create în momentul publicării.
Iată partea pe care o sar majoritatea ghidurilor UTM. Să adaugi utm_source=slack la un URL github.com nu face nimic util, pentru că nu vei vedea niciodată analitica GitHub. UTM-urile își merită locul doar când destinația este un site pe care îl măsori, precum documentația sau propria ta pagină de descărcare. Când destinația este GitHub, linkul scurt separat per canal este atribuirea: clicul este numărat la redirecționare, înainte ca GitHub să îl vadă vreodată.
| Canal | Slug pentru v2.4.0 | Destinație | Ce îți spun clicurile |
|---|---|---|---|
| Comunitate Slack | v2-4-0-slack | Pagina lansării GitHub | Clicuri din propria comunitate |
| X / Mastodon | v2-4-0-social | Pagina lansării GitHub | Acoperire dincolo de utilizatorii existenți |
| Newsletter | v2-4-0-news | Ghidul de upgrade din docs + UTM | Clicuri plus comportament pe site în analitica ta |
| Latest (stabil) | latest | Lansarea curentă, repoziționat | Cererea totală pe toate versiunile |
Etichetează fiecare link per lansare cu versiunea și canalul (["release", "v2.4.0", "slack"]), pentru că etichetele sunt felul în care vei scoate setul înapoi mai târziu: GET .../links?tags=v2.4.0 listează tot ce ține de o lansare. Păstrează valorile UTM banale și identice între lansări. Ghidul convențiilor de denumire UTM conține regulile pe care le-aș copia.
Crearea linkurilor la evenimentul Release Published
Un ghid-soră acoperă crearea generică de linkuri în CI, deci această secțiune rămâne la părțile specifice lansărilor. Triggerul este release cu tipul de activitate published. Conform listei de evenimente de workflow GitHub, published se declanșează atât pentru lansări stabile, cât și pentru pre-lansări, inclusiv pre-lansările publicate dintr-o schiță, motiv pentru care pasul de repoziționare de mai jos verifică flagul 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}')"
Rezumatul jobului îi dă celui care postează anunțul o listă gata de linkuri, iar un 409 la o rerulare înseamnă că slugul există deja, deci un workflow reîncercat nu eșuează și nu duplică nimic. Linkul pentru newsletter ar indica documentația ta cu UTM-uri în destinație; l-am lăsat aici pe pagina lansării ca exemplul să rămână scurt.
Trei capcane care m-au costat o după-amiază
Prima e tăcută. Dacă pipeline-ul tău de lansare publică lansarea cu GITHUB_TOKEN implicit, acest workflow nu rulează niciodată, pentru că evenimentele create cu GITHUB_TOKEN nu declanșează rulări noi de workflow. Nicio eroare, niciun job sărit, nimic. Publică în schimb cu un token de GitHub App.
A doua, punctele. Convertesc v2.4.0 în v2-4-0 pentru slug, pentru că șirurile de versiune cu puncte arată ca extensii de fișier în previzualizările din chat, iar unii clienți le transformă ciudat în linkuri.
A treia, nu lăsa workflowul să editeze corpul lansării decât dacă e nevoie. Merge (gh release edit --notes-file), dar rescrie un text pe care un om tocmai l-a aprobat și declanșează evenimente edited la care pot reacționa alte automatizări. Rezumatul pasului e mai puțin isteț și mult mai sigur. Reîncercările au propriul articol: limite de rată API și idempotență.
Dacă încă lipești linkurile de lansare de mână, workflowul de mai sus înseamnă vreo douăzeci de minute de configurare. Pornește un workspace Elido gratuit, îndreaptă un domeniu de brand spre el și lasă următorul tag să își creeze singur linkurile.
Cum urmărești clicurile din notele de lansare pe canale
După două-trei lansări, datele încep să răspundă la întrebări la care contorul GitHub nu poate.
Compararea pe canale este cea simplă. Extrage linkurile etichetate cu o versiune, apoi citește rezumatul de clicuri al fiecărui link, filtrat după link_id. Dacă v2-4-0-news îl bate pe v2-4-0-social cu cinci la unu timp de trei lansări la rând, ai aflat unde sunt de fapt utilizatorii tăi, și rareori e unde presupunea echipa. Anunțul cu cele mai multe aprecieri nu e adesea cel care trimite oamenii la descărcare, așa că așteaptă-te la obiecții prima dată când arăți cifrele și așteaptă a treia lansare la rând înainte ca cineva să rescrie planul de lansare în jurul lor.
Linkul latest are un truc mai puțin evident. Fiecare clic înregistrează destinația la care s-a rezolvat în acel moment, deci defalcarea analiticii după destinație, filtrată pe linkul latest, împarte traficul lui pe versiuni. După o repoziționare poți urmări cum scade ponderea vechii destinații și cât timp mai sosesc întârziații pe pagini din cache și pe vechi favorite. Aceasta este curba ta reală de upgrade, măsurată în vârful pâlniei.
Două limite sincere. Clicurile nu sunt descărcări: cineva poate da clic pe pagina lansării și pleca, iar download_count de la GitHub rămâne sursa de adevăr pentru descărcările finalizate. Și boții dau clic pe linkurile de lansare, mai ales preluatoarele de previzualizare din aplicațiile de chat, așa că citește tendințele pe mai multe lansări în loc să te încrezi într-o singură zi. Pagina funcției de analitică listează ce defalcări sunt disponibile pe fiecare plan.
Păstrarea în viață a vechilor linkuri de lansare
Linkurile per lansare nu se mută niciodată. v2-3-0-slack indică tagul v2.3.0 în martie și tot acolo indică peste cinci ani, ceea ce se așteaptă cineva care citește un thread vechi de forum. Doar linkul latest se schimbă, și doar la lansările stabile.
Singurul caz în care ar trebui să atingi un link vechi este o lansare retrasă. Dacă v2.4.0 apare cu un bug de pierdere de date, nu șterge linkurile ei; repoziționează fiecare link v2-4-0-* către v2.4.1 cu același apel PATCH și o scurtă notă în corpul lansării. Ștergerea le dă celor care au salvat linkul un punct mort exact în momentul în care au cea mai mare nevoie de remediu. O versiune mai nouă bate un 404. De fiecare dată.
Pentru proiectele care păstrează vechi linkuri de lansare și în README-uri, scripturi de instalare și metadate de pachete, ghidul orientat spre dezvoltatori despre scurtătoarele de URL arată unde mai sunt utile linkurile scurte. Suprafața REST completă este pe pagina API și SDK-uri.
Citește articolul-pilon → Gestionează-ți linkurile scurte ca Terraform
Pe același subiect pe blog
- Strategie de prevenire a putrezirii linkurilor - manualul mai larg pentru linkuri care trebuie să supraviețuiască paginii spre care indică.
- Quickstart API pentru scurtător de URL - autentificare, SDK-uri și apelul de creare folosit în workflow.
- CLI pentru scurtător de URL - aceleași operații dintr-un terminal, pentru lansări punctuale.
- Bot Slack de scurtare a linkurilor - scurtarea linkurilor chiar acolo unde ajunge anunțul de lansare.
- Redirecționări 301 vs 302 - de ce un link repoziționabil trebuie să rămână temporar.
- Linkuri scurte din GitHub Actions - pasul generic de creare sau actualizare pentru orice workflow.
Întrebări frecvente
Cum fac link către ultima lansare GitHub?
GitHub acceptă /releases/latest pentru pagina lansării și /releases/latest/download/asset-name pentru un fișier, atâta timp cât asset-ul păstrează același nume în fiecare lansare. Dacă numele asset-urilor tale conțin numărul versiunii, pune în față un link scurt și repoziționează-l la fiecare lansare.
Pot urmări clicurile pe descărcările din lansările GitHub?
Parțial. API-ul REST GitHub raportează un download_count per asset de lansare, dar nu are date despre referrer, țară sau canal, deci nu îți poate spune dacă descărcarea a venit de pe Slack, de pe X sau dintr-un newsletter. Un link scurt per canal, pus în fața asset-ului, îți dă această împărțire.
Ar trebui un link scurt către ultima lansare să folosească o redirecționare 301 sau 302?
Folosește 302. Browserele pot reține un 301 în cache pe termen nelimitat, deci un cititor care a dat clic luna trecută poate continua să ajungă la versiunea veche după ce repoziționezi linkul. Linkurile Elido folosesc implicit 302, ceea ce ține destinația sub controlul tău la fiecare clic.
De ce nu rulează workflowul meu de lansare când alt workflow publică lansarea?
Evenimentele create cu GITHUB_TOKEN-ul repository-ului nu pornesc rulări noi de workflow, în afară de workflow_dispatch și repository_dispatch. Dacă un pipeline de lansare publică cu GITHUB_TOKEN, triggerul release: published nu se declanșează niciodată. Publică în schimb cu un token de GitHub App sau cu un personal access token cu granulație fină.
Funcționează parametrii UTM pe linkurile către github.com?
Trec mai departe, dar nu îți folosesc la nimic, pentru că nu vezi niciodată analitica GitHub. UTM-urile se răsplătesc doar când destinația este un site pe care îl măsori, precum documentația sau pagina ta de descărcare. Pentru destinațiile github.com, linkul scurt separat per canal este atribuirea.
Ce se întâmplă cu vechile linkuri de lansare când apare o versiune nouă?
Nimic, dacă l-ai configurat așa. Linkurile per lansare continuă să indice pentru totdeauna propriul tag, iar doar linkul latest se mută. Dacă o lansare este retrasă, repoziționează linkurile ei către versiunea corectată în loc să le ștergi, ca cei care au salvat vechiul link să ajungă tot într-un loc util.
Încearcă Elido
Lipește un URL, obții un link scurt funcțional
Fără înregistrare. Linkul este activ timp de 30 de zile. Înregistrează-te ca să-l păstrezi pentru totdeauna.
Fără înregistrare. Creează un cont gratuit pentru 50 linkuri pe lună.