9 min czytaniaIntegracje

Skracanie linków w informacjach o wydaniu i śledzenie każdego pobrania

Skracaj linki w informacjach o wydaniu za pomocą stabilnego linku latest, który przekierowujesz przy każdym wydaniu, jednego otagowanego linku na kanał oraz danych o kliknięciach pokazujących, co wygenerowało pobrania.

Marius Voß
DevRel · edge infra
Okładka w stylu pikselowym pokazująca skracanie linków w informacjach o wydaniu: jeden stabilny link latest przekierowany z v2.3 do v2.4 oraz osobne otagowane linki dla Slacka, X i newslettera

Informacje o wydaniu docierają dalej niż niemal wszystko, co publikuje zespół inżynieryjny. Nikt tego nie mierzy. Wklejasz link do pobrania w treści wydania, ktoś kopiuje go do Slacka, marketing umieszcza go w newsletterze, a opiekun projektu publikuje go na X. Po sześciu miesiącach połowa tych linków prowadzi do pliku, który już nie istnieje, a żaden z nich niczego Ci nie powiedział. Żeby prawidłowo skracać linki w informacjach o wydaniu, potrzebujesz trzech rzeczy: jednego stabilnego krótkiego linku "latest", który przekierowujesz przy każdym wydaniu, osobnego otagowanego linku na kanał dla każdej wersji oraz workflow uruchamianego przez zdarzenie release: published, które tworzy oba linki, żeby nikt nie musiał o tym pamiętać.

To cała odpowiedź. Reszta tego wpisu pokazuje, jak połączyć te elementy bez bałaganu oraz co dane o kliknięciach mogą, a czego nie mogą Ci później powiedzieć.

Widziałem wiele projektów, które ręcznie obsługiwały linki w informacjach o wydaniu GitHub, a schemat awarii zawsze wygląda tak samo: ktoś linkuje do wersjonowanego zasobu, link zostaje zacytowany na forum albo w odpowiedzi na Stack Overflow, a następne wydanie po cichu go osieroca. Jeśli już zarządzasz linkami jako kodem, poniższe podejście pasuje obok krótkich linków zarządzanych w Terraformie, z tą różnicą, że linki wydań zmieniają się według harmonogramu, którego ręcznie nie kontrolujesz.

Dlaczego linki w informacjach o wydaniu wygasają i tracą atrybucję

Kryją się tu dwa osobne problemy. Potrzebują różnych rozwiązań.

Pierwszy to wygasanie linków. GitHub daje Ci stabilne URL-e do strony wydania (/releases/latest) oraz do plików za pomocą /releases/latest/download/asset-name, ale to drugie działa tylko wtedy, gdy zasób zachowuje identyczną nazwę w kolejnych wydaniach, zgodnie z własną dokumentacją GitHub dotyczącą linkowania do wydań. Większość potoków budowania umieszcza wersję w nazwie pliku, więc app-2.3.0.dmg zmienia się w app-2.4.0.dmg, a działający w zeszłym tygodniu URL pobierania "latest" zwraca teraz 404. Linki do dokumentacji też wygasają, gdy witryna z dokumentacją zostaje przeorganizowana. Szersze wzorce opisuje nasza strategia zapobiegania wygasaniu linków; informacje o wydaniu są po prostu miejscem, w którym problem najbardziej daje się we znaki, bo linki docierają najdalej.

Drugi problem to atrybucja i jest mniej widoczny. GitHub REST API rzeczywiście zwraca download_count dla każdego zasobu wydania, co jest czymś więcej, niż większość osób sobie z tego zdaje sprawę. Nie informuje jednak, skąd pochodziło pobranie. Skok o 4000 pobrań dzień po wydaniu może być zasługą newslettera, wątku na Hacker News albo pojedynczego klienta enterprise, którego CI pobiera binarkę w pętli. Linki wklejane do Slacka i wiadomości prywatnych całkowicie usuwają stronę odsyłającą, co jest problemem atrybucji dark social w miniaturze.

Utwórz jeden krótki link, na przykład get.example.dev/latest, i traktuj go jak wskaźnik. Używa go każda strona dokumentacji, odznaka w README i skrypt instalacyjny. Przy każdym stabilnym wydaniu aktualizujesz jego miejsce docelowe. Slug nigdy się nie zmienia, więc nic, co go zacytowało, się nie psuje.

W Elido taki wskaźnik jest zwykłym linkiem. Tworzysz go raz za pomocą POST /v1/workspaces/{workspace_id}/links, przekazując domain_id swojej brandowanej domeny, slug i destination_url. Zapisz id z odpowiedzi 201. Ponowne przekierowanie to PATCH /v1/workspaces/{workspace_id}/links/{link_id} z nowym destination_url i niczym więcej; slug, tagi oraz historia kliknięć pozostają bez zmian.

Zostaw 302. Linki Elido domyślnie używają 302 i jest powód, żeby tego nie zmieniać w tym przypadku: 301 jest domyślnie przechowywane w pamięci podręcznej zgodnie z RFC 9110, więc przeglądarka, która widziała przekierowanie z zeszłego miesiąca, może już nigdy nie zapytać ponownie. Wskaźnik, który przeglądarki pamiętają na zawsze, przestaje być wskaźnikiem. Więcej informacji znajdziesz w artykule Przekierowania 301 i 302 dla krótkich linków.

Schemat stabilnego krótkiego linku latest przekierowywanego z pobrania v2.3.0 do pobrania v2.4.0 po opublikowaniu wydania, podczas gdy linki per wydanie dla v2.3.0 nadal prowadzą do własnego tagu

Ustal z góry jedną rzecz. Czy link latest ma prowadzić do pliku, czy do strony wydania? Kierowałbym go do strony wydania, jeśli wydanie obejmuje buildy na więcej niż jedną platformę, a linki latest per platforma (/latest-mac, /latest-linux) zachowałbym tylko wtedy, gdy dokumentacja instalacji naprawdę potrzebuje bezpośredniego pliku. Mniej zmienianych wskaźników oznacza mniej rzeczy, które można źle przekierować.

Otagowanie per wydanie dla linków w informacjach o wydaniu GitHub

Link latest odpowiada na pytanie "czy link nadal działa". Nie odpowie na pytanie "który kanał zadziałał", bo wszyscy klikają ten sam slug. Dlatego każde wydanie otrzymuje własny niewielki zestaw linków, po jednym na kanał, tworzony w chwili publikacji.

Oto część pomijana przez większość poradników UTM. Dopisanie utm_source=slack do URL-a github.com niczego użytecznego nie daje, bo nigdy nie zobaczysz analityki GitHub. UTM-y mają sens tylko wtedy, gdy miejscem docelowym jest mierzona przez Ciebie witryna, na przykład dokumentacja albo własna strona pobierania. Gdy miejscem docelowym jest GitHub, osobny krótki link na kanał jest atrybucją: kliknięcie jest zliczane przy przekierowaniu, zanim GitHub w ogóle je zobaczy.

KanałSlug dla v2.4.0Miejsce doceloweCo mówią Ci kliknięcia
Społeczność Slackv2-4-0-slackStrona wydania GitHubKliknięcia z własnej społeczności
X / Mastodonv2-4-0-socialStrona wydania GitHubZasięg poza obecnymi użytkownikami
Newsletterv2-4-0-newsPrzewodnik aktualizacji dokumentacji + UTM-yKliknięcia i zachowanie w witrynie w analityce
Latest (stabilne)latestBieżące wydanie, przekierowywaneŁączny popyt na wszystkie wersje

Otaguj każdy link per wydanie wersją i kanałem (["release", "v2.4.0", "slack"]), bo właśnie dzięki tagom później wyciągniesz cały zestaw: GET .../links?tags=v2.4.0 wyświetla wszystko dla jednego wydania. Zachowaj wszystkie wartości UTM proste i identyczne między wydaniami. Przewodnik po konwencjach nazewnictwa UTM zawiera reguły, które sam bym zastosował.

Tworzenie linków przy zdarzeniu opublikowania wydania

Powiązany przewodnik omawia ogólne tworzenie linków w CI, więc ta sekcja skupia się na elementach specyficznych dla wydań. Wyzwalaczem jest release z typem aktywności published. Zgodnie z listą zdarzeń workflow GitHub, published uruchamia się zarówno dla wydań stabilnych, jak i wersji wstępnych, w tym wersji wstępnych opublikowanych ze szkicu, dlatego poniższy krok przekierowania sprawdza 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}')"

Podsumowanie zadania daje osobie publikującej ogłoszenie gotową listę linków, a kod 409 przy ponownym uruchomieniu oznacza, że slug już istnieje, więc ponowiony workflow nie kończy się błędem ani nie duplikuje niczego. Link newslettera prowadziłby do dokumentacji z UTM-ami w miejscu docelowym; tutaj zostawiłem go na stronie wydania, żeby przykład był krótki.

Trzy pułapki, które kosztowały mnie całe popołudnie

Pierwsza jest cicha. Jeśli potok wydania publikuje wydanie za pomocą domyślnego GITHUB_TOKEN, ten workflow nigdy się nie uruchomi, ponieważ zdarzenia utworzone przez GITHUB_TOKEN nie uruchamiają nowych workflow. Żadnego błędu, żadnego pominiętego zadania, nic. Publikuj za pomocą tokena aplikacji GitHub.

Po drugie, kropki. Zamieniam v2.4.0 na v2-4-0 w slugu, ponieważ ciągi wersji z kropkami wyglądają w podglądach czatu jak rozszerzenia plików, a niektóre klienty dziwnie zamieniają je w linki.

Po trzecie, nie pozwalaj workflow edytować treści wydania, chyba że musisz. Działa (gh release edit --notes-file), ale przepisuje tekst, który człowiek właśnie zatwierdził, i uruchamia zdarzenia edited, na które mogą reagować inne automatyzacje. Podsumowanie zadania jest mniej sprytne i znacznie bezpieczniejsze. Ponowienia mają własny wpis: Limity szybkości API i idempotencja.

Jeśli nadal ręcznie wklejasz linki do wydań, konfiguracja powyższego workflow zajmuje około dwudziestu minut. Utwórz darmowy workspace Elido, podłącz do niego brandowaną domenę i pozwól, by następny tag utworzył własne linki.

Jak śledzić kliknięcia w informacjach o wydaniu według kanału

Po dwóch lub trzech wydaniach dane zaczynają odpowiadać na pytania, na które licznik GitHub nie potrafi odpowiedzieć.

Porównanie kanałów jest najprostsze. Pobierz linki otagowane daną wersją, a następnie odczytaj podsumowanie kliknięć każdego linku z zakresem link_id. Jeśli v2-4-0-news przez trzy wydania z rzędu wyprzedza v2-4-0-social w stosunku pięć do jednego, wiesz już, gdzie naprawdę są Twoi użytkownicy, i rzadko jest to miejsce założone przez zespół. Ogłoszenie z największą liczbą polubień często nie jest tym, które kieruje ludzi do pobrania, więc spodziewaj się sprzeciwu, gdy pierwszy raz pokażesz te liczby, i poczekaj na trzecie wydanie z rzędu, zanim ktoś przebuduje wokół nich plan uruchomienia.

Link latest ma mniej oczywisty trik. Każde kliknięcie zapisuje miejsce docelowe, do którego w danym momencie rozwiązano link, więc zestawienie analityki według miejsca docelowego, ograniczone do linku latest, dzieli jego ruch według wersji. Po ponownym przekierowaniu możesz obserwować spadek udziału starego miejsca docelowego i sprawdzić, jak długo spóźnieni użytkownicy nadal przychodzą z zapisanych stron i starych zakładek. To Twoja rzeczywista krzywa aktualizacji, zmierzona na szczycie lejka.

Schemat pokazujący śledzenie kliknięć w informacjach o wydaniu: linki ze Slacka, mediów społecznościowych i newslettera dla jednego wydania dostarczają liczby kliknięć per link, a link latest dzieli kliknięcia według wersji miejsca docelowego

Dwa uczciwe ograniczenia. Kliknięcia to nie pobrania: ktoś może przejść do strony wydania i ją opuścić, a download_count GitHub pozostaje źródłem prawdy o ukończonych pobraniach. Boty również klikają linki do wydań, szczególnie pobierające podglądy linków w aplikacjach czatowych, więc czytaj trendy między wydaniami, zamiast ufać pojedynczemu dniu. Strona funkcji analityki zawiera listę zestawień dostępnych w każdym planie.

Utrzymywanie starych linków do wydań

Linki per wydanie nigdy się nie zmieniają. v2-3-0-slack prowadzi do tagu v2.3.0 w marcu i nadal prowadzi tam po pięciu latach, czego oczekuje osoba czytająca stary wątek na forum. Zmienia się tylko link latest i tylko przy stabilnych wydaniach.

Jedynym przypadkiem, w którym warto ruszyć stary link, jest wycofane wydanie. Jeśli v2.4.0 zostanie opublikowane z błędem powodującym utratę danych, nie usuwaj jego linków; przekieruj każdy link v2-4-0-* do v2.4.1 za pomocą tego samego wywołania PATCH i krótkiej notatki w treści wydania. Usunięcie pozostawia osoby, które zapisały link, bez wyjścia dokładnie wtedy, gdy najbardziej potrzebują poprawki. Nowsza wersja zawsze wygrywa z 404.

W przypadku projektów, które przechowują stare linki do wydań także w README, skryptach instalacyjnych i metadanych menedżerów pakietów, przewodnik po skracaczach URL dla developerów omawia inne miejsca, w których krótkie linki się przydają. Pełny interfejs REST znajdziesz na stronie API i SDK.

Przeczytaj artykuł filarowy → Zarządzaj krótkimi linkami jako Terraformem

Powiązane wpisy na blogu

Najczęściej zadawane pytania

Jak utworzyć link do najnowszego wydania GitHub?

GitHub obsługuje /releases/latest dla strony wydania oraz /releases/latest/download/asset-name dla pliku, o ile zasób zachowuje tę samą nazwę w każdym wydaniu. Jeśli nazwy zasobów zawierają numer wersji, umieść przed nimi krótki link i przekierowuj go przy każdym wydaniu.

Czy można śledzić kliknięcia pobrań wydań GitHub?

Częściowo. GitHub REST API zwraca download_count dla każdego zasobu wydania, ale nie zawiera danych o stronie odsyłającej, kraju ani kanale, więc nie powie Ci, czy pobranie pochodziło ze Slacka, X czy newslettera. Krótki link na kanał umieszczony przed zasobem daje taki podział.

Czy krótki link do najnowszego wydania powinien używać przekierowania 301 czy 302?

Użyj 302. Przeglądarki mogą przechowywać przekierowanie 301 w pamięci podręcznej bezterminowo, więc czytelnik, który kliknął link w zeszłym miesiącu, może nadal trafiać na starą wersję po przekierowaniu linku. Linki Elido domyślnie używają 302, dzięki czemu miejsce docelowe pozostaje pod Twoją kontrolą przy każdym kliknięciu.

Dlaczego mój workflow wydania nie uruchamia się, gdy inne workflow publikuje wydanie?

Zdarzenia utworzone za pomocą GITHUB_TOKEN repozytorium nie uruchamiają nowych workflow, z wyjątkiem workflow_dispatch i repository_dispatch. Jeśli potok wydania publikuje za pomocą GITHUB_TOKEN, wyzwalacz release: published nigdy nie zadziała. Publikuj za pomocą tokena aplikacji GitHub albo osobistego tokena dostępu o szczegółowych uprawnieniach.

Czy parametry UTM działają w linkach do github.com?

Są przekazywane dalej, ale nic Ci nie dają, ponieważ nie widzisz analityki GitHub. UTM-y mają sens tylko wtedy, gdy miejscem docelowym jest mierzona przez Ciebie witryna, na przykład dokumentacja albo strona pobierania. W przypadku miejsc docelowych w github.com atrybucję zapewnia osobny krótki link na kanał.

Co dzieje się ze starymi linkami do wydań po opublikowaniu nowej wersji?

Nic, jeśli skonfigurujesz to w ten sposób. Linki per wydanie zawsze prowadzą do własnego tagu, a zmienia się tylko jeden link latest. Jeśli wydanie zostanie wycofane, przekieruj jego linki do wersji z poprawką zamiast ich usuwać, aby osoby, które zapisały stary link, nadal trafiały w użyteczne miejsce.

Wypróbuj Elido

Wklej URL, otrzymaj krótki link

Bez rejestracji. Link działa 30 dni. Zarejestruj się, aby zachować go na zawsze.

Za darmo, bez rejestracji · 2 dziennie

Wypróbuj Elido

Skracarka URL hostowana w UE: własne domeny, głęboka analityka i otwarte API. Darmowy plan - bez karty kredytowej.

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

Czytaj dalej