リリースノートは、エンジニアリングチームが書くものの中でも、ほとんど何より遠くまで届きます。それなのに、誰も計測していません。リリース本文にダウンロードリンクを貼り、誰かがSlackにコピーし、マーケティング担当者がニュースレターに載せ、メンテナーがXに投稿します。半年後には、その半分がもう存在しないファイルを指し、どのリンクも何も教えてくれません。リリースノートのリンクを正しく短縮するには、3つ必要です。リリースごとに遷移先を変更する安定した「最新」短縮リンク、各バージョンのチャネルごとに分けたタグ付きリンク、そして両方を作成してくれるrelease: publishedイベント用のワークフローです。誰かが覚えておく必要はありません。
答えはこれだけです。この記事の残りでは、混乱を招かずにこれを組み込む方法と、その後でクリックデータから分かること、分からないことを説明します。
私はこれまで、多くのプロジェクトがGitHubのリリースノートリンクを手作業で扱うのを見てきました。その失敗パターンはいつも同じです。誰かがバージョン付きアセットにリンクし、そのリンクがフォーラムのスレッドやStack Overflowの回答に引用され、次のリリースで気付かないうちに孤立します。すでにリンクをコードとして管理しているなら、以下の方法はTerraformで管理するショートリンクと並べて使えます。ただし、リリースリンクが変わるタイミングは、手作業で管理するスケジュールではない点が異なります。
リリースノートのリンクが切れ、アトリビューションを失う理由
ここには別々の問題が2つあります。それぞれに異なる対策が必要です。
1つ目はリンク切れです。GitHubでは、リリースページには安定したURL(/releases/latest)を、ファイルには/releases/latest/download/asset-nameを使えます。しかし、リリースへのリンクに関するGitHub公式ドキュメントによると、後者が機能するのは、リリース間でアセット名が完全に同じ場合だけです。ほとんどのビルドパイプラインはファイル名にバージョンを入れるため、app-2.3.0.dmgはapp-2.4.0.dmgになり、先週機能していた「最新」ダウンロードURLが404を返すようになります。ドキュメントサイトが再編成されると、ドキュメントのリンクも切れます。より広いパターンについてはリンク切れを防ぐ戦略で説明しています。リリースノートで問題が深刻になるのは、リンクが最も遠くまで広がるからです。
2つ目はアトリビューションで、こちらはより気付きにくい問題です。GitHub REST APIは、各リリースアセットに対してdownload_countを返します。これは多くの人が思う以上に便利です。しかし、ダウンロード元は返しません。リリース翌日に4,000件のダウンロードがあっても、それがニュースレター、Hacker Newsのスレッド、あるいはバイナリをループで取得する1社の顧客のCIによるものかは分かりません。SlackやDMに貼ったリンクはリファラーを完全に失わせます。これは、ダークソーシャルのアトリビューション問題を小さくしたものです。
リリースごとに遷移先を変更する安定した最新リンク
たとえばget.example.dev/latestという短縮リンクを1つ作り、ポインターとして扱います。すべてのドキュメントページ、READMEのバッジ、インストールスクリプトでこれを使います。安定版をリリースするたびに、遷移先を更新します。スラッグは変わらないので、これを引用したものが壊れることはありません。
Elidoでは、このポインターは通常のリンクです。POST /v1/workspaces/{workspace_id}/linksを使い、独自ブランドのドメインのdomain_id、slug、destination_urlを渡して一度作成します。201レスポンスのidを保存します。遷移先の変更には、新しいdestination_urlだけを指定するPATCH /v1/workspaces/{workspace_id}/links/{link_id}を使います。スラッグ、タグ、クリック履歴はそのまま残ります。
302のままにしてください。Elidoのリンクはデフォルトで302です。この用途で変更しない方がよい理由があります。301はRFC 9110ではデフォルトでキャッシュ可能なので、先月のリダイレクトを見たブラウザーが二度と確認しない可能性があります。ブラウザーが永遠に覚えているポインターは、もはやポインターではありません。詳しくはショートリンクの301と302リダイレクトをご覧ください。
最初に1つ決めてください。最新リンクはファイルとリリースページのどちらを指すべきでしょうか。複数のプラットフォーム用ビルドがある場合はリリースページを指すようにし、インストール手順で直接ファイルが本当に必要な場合だけ、プラットフォームごとの最新リンク(/latest-mac、/latest-linux)を用意することをおすすめします。移動させるポインターを減らせば、誤った遷移先を変更するものも減ります。
GitHubリリースノートリンクにリリースごとのタグを付ける
最新リンクは「リンクがまだ機能するか」という問いに答えます。しかし、全員が同じスラッグをクリックするため、「どのチャネルが機能したか」には答えられません。そのため、リリースごとに、公開時に作成するチャネル別の小さなリンクセットを用意します。
ここが、ほとんどのUTMガイドが省略する部分です。github.comのURLにutm_source=slackを付けても役に立ちません。GitHubのアナリティクスを見ることができないからです。UTMが意味を持つのは、ドキュメントサイトや自分のダウンロードページなど、計測しているサイトが遷移先の場合だけです。遷移先がGitHubの場合は、チャネルごとの短縮リンクがアトリビューションになります。GitHubが見るより前に、リダイレクトでクリックがカウントされるためです。
| チャネル | v2.4.0用のスラッグ | 遷移先 | クリックから分かること |
|---|---|---|---|
| Slackコミュニティ | v2-4-0-slack | GitHubリリースページ | 自分のコミュニティからのクリック |
| X / Mastodon | v2-4-0-social | GitHubリリースページ | 既存ユーザー以外へのリーチ |
| ニュースレター | v2-4-0-news | ドキュメントのアップグレードガイド + UTM | クリックと、アナリティクスでのサイト内行動 |
| 最新(安定版) | latest | 現在のリリース、遷移先を変更 | すべてのバージョンを通じた総需要 |
各リリースのリンクには、バージョンとチャネル(["release", "v2.4.0", "slack"])をタグ付けしてください。後でセットを取り出すときにタグを使うためです。GET .../links?tags=v2.4.0で、1つのリリースに属するすべてのリンクを一覧表示できます。UTMの値は、面白みがなくてもリリース間で同一にしてください。私ならUTMの命名規則ガイドのルールを使います。
リリース公開イベントでリンクを作成する
CIでリンクを作成する一般的な方法は姉妹記事で扱っているため、ここではリリース固有の部分に絞ります。トリガーは、アクティビティタイプpublishedのreleaseです。GitHubのワークフローイベント一覧によると、publishedは安定版とプレリリースの両方で発火します。下書きから公開されたプレリリースも含まれるため、下の遷移先変更ステップでは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}')"
ジョブサマリーには、告知を投稿する人がすぐ使えるリンク一覧が表示されます。再実行時の409はスラッグがすでに存在することを意味するため、ワークフローを再試行しても失敗したり重複したりしません。ニュースレターのリンクは遷移先でUTMを付けたドキュメントを指す想定ですが、例を短くするため、ここではリリースページを指しています。
私が午後を費やした3つの落とし穴
1つ目は、気付きにくいものです。リリースパイプラインがデフォルトのGITHUB_TOKENを使ってリリースを公開すると、GITHUB_TOKENで作成されたイベントは新しいワークフロー実行を発火させないため、このワークフローは実行されません。エラーも、スキップされたジョブも、何もありません。代わりにGitHub Appトークンで公開してください。
2つ目は、ドットです。スラッグではv2.4.0をv2-4-0に変換します。ドット付きのバージョン文字列はチャットのプレビューでファイル拡張子のように見え、一部のクライアントでは奇妙にリンク化されるためです。
3つ目は、必要がない限り、ワークフローでリリース本文を編集させないことです。機能はします(gh release edit --notes-file)。しかし、人が承認したばかりの文章を書き換え、他の自動化が反応する可能性のあるeditedイベントを発火させます。ジョブサマリーの方が賢さは控えめですが、はるかに安全です。再試行については、別記事のAPIレート制限と冪等性をご覧ください。
まだリリースリンクを手作業で貼っているなら、上のワークフローは設定に約20分かかります。Elidoの無料ワークスペースを始め、独自ブランドのドメインを設定し、次のタグにリンクを作らせてください。
チャネルごとにリリースノートのクリックを追跡する方法
2、3回リリースすると、GitHubのカウンターでは答えられない問いにもデータが答え始めます。
チャネルごとの比較は簡単です。あるバージョンでタグ付けされたリンクを取り出し、各リンクのクリック概要をlink_idで絞り込んで読み取ります。3回のリリースでv2-4-0-newsがv2-4-0-socialを5対1で上回ったなら、ユーザーが実際にいる場所が分かります。そこは、チームが想定していた場所ではないことがほとんどです。最も「いいね」が多い告知が、ダウンロードへ最も多く送る告知とは限りません。初めて数字を見せるときは反発を予想し、連続する3回目のリリースまでは、その数字を中心にローンチ計画を書き換えないでください。
最新リンクには、あまり知られていない仕組みがあります。すべてのクリックは、その時点で解決された遷移先を記録するため、最新リンクに絞った遷移先別のアナリティクス内訳で、トラフィックをバージョン別に分けられます。遷移先を変更した後は、古い遷移先の割合が下がる様子や、キャッシュされたページや古いブックマークからどのくらい長く訪問が続くかを確認できます。これが、ファネルの最上部で測定した実際のアップグレード曲線です。
正直な限界が2つあります。クリックはダウンロードではありません。リリースページへクリックして移動した人が、そのまま離れることもあります。完了した取得の正確な情報源は、GitHubのdownload_countです。また、ボットもリリースリンクをクリックします。特にチャットアプリのリンクプレビュー取得ボットには注意が必要です。そのため、1日だけの数字を信じるのではなく、リリースをまたいだ傾向を読んでください。アナリティクス機能ページには、各プランで利用できる内訳が掲載されています。
古いリリースリンクを有効なまま保つ
リリースごとのリンクは移動しません。v2-3-0-slackは3月にはv2.3.0のタグを指し、5年後もそこを指します。古いフォーラムスレッドを読む人にとって、それが期待される動作です。移動するのは最新リンクだけで、安定版のリリース時だけです。
古いリンクに手を入れるべき唯一のケースは、リリースを取り下げた場合です。v2.4.0にデータ損失のバグがあった場合は、そのリンクを削除しないでください。同じPATCH呼び出しを使い、すべてのv2-4-0-*リンクの遷移先をv2.4.1に変更し、リリース本文に短い注記を入れます。削除すると、リンクを保存していた人が、修正を最も必要としているまさにそのタイミングで行き止まりに突き当たります。新しいバージョンは404に勝ります。毎回です。
README、インストールスクリプト、パッケージマネージャーのメタデータにも古いリリースリンクを残すプロジェクトでは、開発者向けURL短縮サービスガイドで、ショートリンクが役立つその他の場所を説明しています。REST APIの全体像はAPIとSDKのページにあります。
コーナーストーン記事を読む → ショートリンクをTerraformとして管理する
ブログの関連記事
- リンク切れを防ぐ戦略 - リンク先のページより長く存続させる必要があるリンクのための、より広い実践ガイドです。
- URL短縮サービスAPIクイックスタート - ワークフローで使う認証、SDK、作成呼び出しを解説します。
- URL短縮サービスCLI - 1回限りのリリースで、ターミナルから同じ操作を行う方法です。
- Slack URL短縮ボット - リリース告知が実際に届く場所でリンクを短縮します。
- 301と302のリダイレクト - 遷移先を変更できるリンクを一時的なものにする必要がある理由を説明します。
- GitHub Actionsからショートリンクを作成する - どのワークフローでも使える、作成または更新の一般的なステップです。
よくある質問
最新のGitHubリリースへのリンクを作るにはどうすればよいですか?
GitHubでは、リリースページには /releases/latest を、ファイルには /releases/latest/download/asset-name を使えます。ただし、すべてのリリースでアセット名が同じであることが条件です。アセット名にバージョン番号が含まれる場合は、前段に短縮リンクを置き、リリースごとに遷移先を変更してください。
GitHubリリースのダウンロード数を追跡できますか?
一部は可能です。GitHub REST APIはリリースアセットごとのdownload_countを返しますが、リファラー、国、チャネルのデータはないため、ダウンロードがSlack、X、ニュースレターのどこから来たかは分かりません。アセットの前段にチャネルごとの短縮リンクを置けば、その内訳を確認できます。
最新リリースの短縮リンクには301と302のどちらのリダイレクトを使うべきですか?
302を使ってください。ブラウザーは301を無期限にキャッシュすることがあるため、先月クリックした読者が、リンクの遷移先を変更した後も古いバージョンにアクセスし続ける可能性があります。Elidoのリンクはデフォルトで302なので、クリックのたびに遷移先を管理できます。
別のワークフローがリリースを公開したとき、なぜリリースのワークフローが実行されないのですか?
リポジトリのGITHUB_TOKENで作成されたイベントは、workflow_dispatchとrepository_dispatchを除き、新しいワークフロー実行を開始しません。リリースパイプラインがGITHUB_TOKENで公開すると、release: publishedトリガーは発火しません。代わりにGitHub Appトークンまたはきめ細かい個人アクセストークンで公開してください。
UTMパラメーターはgithub.comへのリンクで機能しますか?
引き渡されますが、GitHubのアナリティクスを見ることはできないため、役に立ちません。UTMが効果を発揮するのは、ドキュメントサイトやダウンロードページなど、自分で計測しているサイトが遷移先の場合だけです。github.comが遷移先の場合は、チャネルごとに分けた短縮リンクがアトリビューションになります。
新しいバージョンが公開されたとき、古いリリースリンクはどうなりますか?
この方法で設定していれば、何も変わりません。リリースごとのリンクはそれぞれのタグを指し続け、移動するのは最新リンクだけです。リリースを取り下げる場合は、削除するのではなく修正版へリンクの遷移先を変更してください。そうすれば、古いリンクを保存していた人も有用なページにたどり着けます。
Elidoを試す
URLを貼り付けて短縮リンクを取得
登録不要。リンクは30日間有効。永久に保存するには登録してください。
Free、登録不要 · 1日あたり2件