GitHub Releasesは、Gitタグにリリースノートと配布ファイル(アセット)を束ねて、リポジトリの「Releases」ページで公開する機能です。タグ自体はGitの機能ですが、リリースノート、バイナリの添付、「Latest」表示、ダウンロード数の集計はGitHub側の機能で、git push --tags だけではリリースは作られません。
この記事では、Web画面とGitHub CLI(gh)での作成手順、リリースノートに書く項目と .github/release.yml による自動生成、pre-release・draft・Latestの違い、アセットの上限と固定ダウンロードリンク、新しいリリースの受け取り方、GitHub Actionsでの自動化を、GitHub公式ドキュメントとgh CLI v2.103.0(2026年10月21日公開)の仕様に沿って整理します。
まとめ:GitHub Releasesを使う前に押さえる要点
- リリースはGitタグを土台にしたGitHubの機能です。リリースを削除してもタグは残ります(
gh release delete --cleanup-tagで同時に削除)。 - リリースノートは「Generate release notes」で、前回タグ以降にマージされたプルリクエスト・コントリビューター・差分リンクから自動生成できます。破壊的変更と移行手順は自動生成では書かれないので、手書きの段落を先頭に足します。
releases/latestが返すのはdraftとpre-releaseを除いた正式リリースだけです。旧系統のパッチを後から公開するときは--latest=falseを明示します。- 1リリースあたりアセットは1,000個まで、1ファイルは2GiB未満です。リリース全体の容量と帯域には上限がなく、料金もかかりません。
releases/latest/download/ファイル名の固定リンクは、アセット名に版番号を含めると次の版で404になります。- 新しいリリースは「Watch」→「Custom」→「Releases」か、
releases.atomのフィードで受け取れます。フィードにはpre-releaseも載ります。
GitHub Releasesの仕組みとタグとの違い
リリースとGitタグの関係
GitHub公式ドキュメント「リリースについて」は、リリースを「Gitタグに基づく」ものと定義し、タグの日付とリリースの日付は別々に作れるので一致しないことがあると明記しています。Git自体にはタグ(git tag v1.2.0)はあっても「リリース」という概念はなく、「git release」で探している機能はGitHubやGitLabなどホスティング側のものです。
| 項目 | Gitタグ | GitHubリリース |
|---|---|---|
| 実体 | コミットを指す参照 | タグ+ノート+アセット |
| 作り方 | git tag・git push |
Web画面・gh・REST API |
| リリースノート | 注釈付きタグのメッセージのみ | Markdown・自動生成可 |
| 配布ファイル | なし | アセットとして添付 |
| ソースコードzip/tar.gz | Tagsページから取得可 | 自動で添付 |
| Latest表示・通知 | なし | あり |
リリースを作ると、GitHubはタグ時点のリポジトリ内容をzipとtarballで自動的に添付します。これは自分でアップロードしたアセットとは別扱いで、Git LFSのオブジェクトを含めるかどうかは管理者がリポジトリ設定で選べます。
Releasesページの場所と検索・比較
リリース一覧は https://github.com/OWNER/REPO/releases にあり、リポジトリトップの右サイドバー「Releases」からも開けます。ページ上部のタブで「Releases」と「Tags」を切り替えられ、リリースを作っていないタグはTagsタブにだけ並びます。閲覧は読み取り権限があれば誰でもでき、作成・編集・削除には書き込み権限が要ります。draft(下書き)はプッシュ権限を持つユーザーにしか見えません。
リリースが数百件あるリポジトリでは、一覧上部の「Find a release」欄に修飾子を入れて絞り込みます。公式ドキュメント「リポジトリのリリースを検索する」に載っている修飾子は次のとおりで、キーワードはタイトル・本文・タグに照合されます。
| 修飾子 | 一致するリリース |
|---|---|
draft:true / draft:false |
下書きのみ / 公開済みのみ |
prerelease:true / prerelease:false |
pre-releaseのみ / 除外 |
tag:v1 |
v1.0・v1.2・v1.2.5などv1系すべて |
created:2026 |
2026年に作成されたもの(範囲指定可) |
2つの版の差分を見るときは、基準にするリリースの横にある「Compare」メニューから比較先のタグを選びます。自動生成ノート末尾の「Full Changelog」リンクも同じ比較画面(compare/v1.3.0...v1.4.0)を開きます。
GitHub PackagesやActionsのアーティファクトとの違い
配布物を置く場所はReleases以外にもあり、受け取る側で使い分けます。
| 置き場所 | 受け取る側 | 向く用途 |
|---|---|---|
| Releasesのアセット | 人・インストールスクリプト | バイナリ・インストーラーの配布 |
| GitHub Packages | npm・Docker・Maven等 | パッケージマネージャー経由の配布 |
| Actionsのアーティファクト | 同じワークフローのジョブ | ビルド結果の一時的な受け渡し |
アーティファクトは保持期間が過ぎると消えるため、利用者向けの配布物には使いません。ジョブ間の受け渡し方は「GitHub Actionsのアーティファクト|受け渡しの設計と同名不可・保持期間の決め方」で扱っています。
リリースの作成手順(Web画面とgh CLI)
Web画面でのリリース作成手順
- リポジトリの「Releases」を開き、「Draft a new release」をクリックします。
- 「Choose a tag」で既存のタグを選ぶか、新しい版番号を入力して「Create new tag」を選びます。新規タグの場合は「Target」でブランチを指定します。
- 必要なら「Previous tag」で前回のリリースのタグを選びます(自動生成ノートの差分の起点になります)。
- 「Release title」と説明を入力するか、「Generate release notes」で自動生成します。
- 配布ファイルをドラッグ&ドロップで添付し、必要に応じて「This is a pre-release」「Set as latest release」を選びます。
- 「Publish release」で公開、「Save draft」で下書き保存です。
説明欄で @メンションしたユーザーは、公開後のリリースに「Contributors」としてアバター付きで並びます。同じフォームはURLのクエリで事前入力でき、releases/new?tag=v1.0.1&title=octo-1.0.1&prerelease=1 のように tag・target・title・body・prerelease を渡せます。
gh release createの作成例と主要オプション
コマンドラインでは gh release create を使います。GitHub CLIをインストールして gh auth login で認証し、対象リポジトリのローカルディレクトリで実行します。タグがリモートに無い場合は --target(既定はデフォルトブランチ)の最新の状態からタグを自動で作ります。
# 自動生成ノートで v1.4.0 を公開し、dist 配下のファイルを添付する
gh release create v1.4.0 dist/* --generate-notes --verify-tag
# 上の例とは別の実行例:未公開の v1.4.0 に手書きの注意書きを付ける
gh release create v1.4.0 --generate-notes --verify-tag --notes "設定ファイルの形式が変わりました。移行手順は docs/migration.md を参照してください。"
# ベータ版をpre-releaseとして公開する
gh release create v1.5.0-beta.1 --prerelease --generate-notes
# 保守ブランチ上に打ってpush済みのタグ v1.3.9 を、Latestを動かさずに公開する
gh release create v1.3.9 --verify-tag --latest=false --notes-file CHANGES-1.3.9.md
| オプション | 働き |
|---|---|
--generate-notes |
Release Notes APIでタイトルとノートを自動生成 |
-n, --notes |
ノート本文(自動生成と併用すると先頭に付く) |
--notes-start-tag |
自動生成の起点にするタグを指定 |
--notes-from-tag |
タグの注釈、軽量タグならコミットメッセージを使用 |
--verify-tag |
リモートにタグが無ければ中止 |
-p, --prerelease |
pre-releaseとして公開 |
-d, --draft |
下書きとして保存 |
--latest=false |
Latestに設定しない |
--fail-on-no-commits |
前回リリース以降のコミットが無ければ失敗 |
--verify-tag を付けないと、タグの打ち忘れに気づかないまま、意図しないコミットにタグが作られます。CIでは必ず付けます。
アセットを渡すと、gh はいったんdraftで作成し、全ファイルをアップロードしてから公開します(gh CLIのソース create.go の draftWhileUploading)。アップロード途中のリリースは利用者に見えません。ただしv2.103.0のヘルプは、この3段階が別々のAPIリクエストで不可分な操作ではないこと、Immutable Releasesの保護は公開した時点から効き、draftの間は権限を持つユーザーやワークフローがアセットを変更できることを明記しています。
リリースの編集・削除とImmutable Releasesの制約
公開後の編集はWeb画面の鉛筆アイコンか gh release edit TAG で行います。削除は gh release delete TAG -y ですが、リリースを消してもタグは残ります。タグごと消すなら --cleanup-tag を付けます。
Immutable Releasesを有効にしたリポジトリでは、公開後にアセットの追加・差し替え・削除ができず、リリースが存在する間はタグの移動・削除もできません。タイトル、ノート、pre-release/Latestの切り替えは可能です。設定手順と検証方法は「GitHub Immutable Releasesとは?Enable release immutabilityの設定手順とgh release verifyでの検証」にまとめています。
リリースノートの記載内容と自動生成の設定
リリースノートに書く項目と並べ方
リリースノートの読み手が知りたいのは「この版に上げる必要があるか、上げたら何が壊れるか」です。そこで破壊的変更と移行手順を一番上に置き、セキュリティ修正、新機能、不具合修正、依存関係の更新の順に並べます。変更履歴の書式として広く参照される Keep a Changelog 1.1.0 は、変更を Added(新機能)・Changed(既存機能の変更)・Deprecated(間もなく削除)・Removed(今回削除)・Fixed(不具合修正)・Security(脆弱性)の6種類に分けています。
手書きと自動生成は組み合わせられます。gh CLI自身のv2.103.0のリリースノートは、新機能の解説を手書きの見出しで先頭に置き、その下に自動生成の「What’s Changed」(マージ済みプルリクエスト)、「New Contributors」、「Full Changelog」(compare/v2.102.1...v2.103.0)が続く構成です。プルリクエストのタイトルの羅列だけでは移行手順や非推奨の予告が伝わらないので、その部分だけを人が書く、という分担です。
## 破壊的変更
- 設定ファイルを config.yml から config.toml に変更しました。移行手順: docs/migration.md
## セキュリティ
- CVE-2026-XXXXX(認証ヘッダーのログ出力)を修正しました。
<!-- ここから下は Generate release notes の出力 -->
## What's Changed
* ...
Generate release notesが出力する内容
公式ドキュメント「自動生成リリースノート」のとおり、自動生成されるのはマージ済みプルリクエストの一覧、そのリリースのコントリビューター、前回タグとの差分(Full Changelog)へのリンクの3つです。起点はフォームの「Previous tag」で指定したタグで、そこから今回のタグまでに入ったプルリクエストが対象になります。プルリクエストを経ずに既定ブランチへ直接pushしたコミットは一覧に出ません。
APIからは POST /repos/{owner}/{repo}/releases/generate-notes で、リリースを作らずに生成結果だけを取れます。リリース作成時に generate_release_notes: true と本文を同時に渡すと、本文が自動生成ノートの先頭に付きます(ghの --notes 併用と同じ結果)。一覧に並ぶのはプルリクエストのタイトルなので、タイトルの書き方をそろえるとノートも読みやすくなります。規約の例は「Conventional Commitsとは?書き方・type一覧とSemVer連携を実例で解説」で扱っています。
release.ymlでカテゴリ分けする設定
既定ブランチに .github/release.yml を置くと、プルリクエストのラベルで見出しを分け、特定のラベルや作成者を除外できます。
# .github/release.yml
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: 破壊的変更
labels:
- breaking-change
- title: 新機能
labels:
- enhancement
- title: バグ修正
labels:
- bug
- title: その他
labels:
- "*"
| キー | 内容 |
|---|---|
changelog.exclude.labels |
全体から除外するラベル |
changelog.exclude.authors |
全体から除外する作成者 |
changelog.categories[*].title |
見出し名(必須) |
changelog.categories[*].labels |
該当ラベル(必須) |
changelog.categories[*].exclude |
カテゴリ単位の除外 |
カテゴリは上から順に照合されます。"*" は「それまでのどのカテゴリにも入らなかったもの」を受ける指定で、これを置かないとラベルの付いていないプルリクエストがノートから消えます。ラベルを付ける運用が定着していないリポジトリでは、最後のカテゴリに必ず入れておきます。
CHANGELOG.mdとの役割分担
GitHubのリリース説明欄に書いたノートは、npmのtarballなどの配布物には自動では含まれません。配布物にも載せるには、ファイルへの保存と同梱が必要です。オフラインや別のミラーでも変更履歴を読ませたいライブラリは、リポジトリ内の CHANGELOG.md を正本にし、リリースノートは「その版の差分とダウンロード」に絞ります。アプリの配布だけなら、CHANGELOG.md を持たずにリリースノートへ集約する構成でも足ります。
pre-release・draft・Latestの違い
| 状態 | 一般公開 | Latestになれるか | Actionsのrelease |
|---|---|---|---|
| draft | 非公開 | 不可 | created等は起動しない |
| pre-release | 公開 | 不可 | prereleased・published |
| 正式リリース | 公開 | 可 | released・published |
Latestの決まり方とreleases/latest API
REST APIのリリース仕様によると、GET /repos/{owner}/{repo}/releases/latest は「pre-releaseでもdraftでもない最新の公開リリース」を返し、並び順の基準は created_at です。この created_at はリリースに使ったコミットの日付で、下書きや公開をした日時ではありません。
リリース作成・更新APIの make_latest は true・false・legacy の3値で、draftとpre-releaseはLatestにできません。legacy は作成日とセマンティックバージョンの大小でLatestを決める旧来の判定です。gh CLIは --latest を省略すると make_latest を送らず、判定をGitHub側に任せます。
注意が要るのは、複数の系統を並行して保守しているときです。Kubernetesは2026年9月23日に v1.36.5・v1.37.1・v1.35.9・v1.34.12 の順で公開し、最後に公開されたのは v1.34.12 ですが、Latestは v1.37.1 です。その後に出た v1.38.0-alpha.1(9月29日)と v1.38.0-alpha.2(10月7日)はpre-releaseなので、10月23日時点でも releases/latest は v1.37.1 へ転送されます。Kubernetesのリリースツール(kubernetes-sigs/release-sdk)はLatestにするかどうかを明示的に渡す実装です。旧系統のパッチを出すときは自動判定に頼らず、--latest=false(APIなら make_latest: "false")を付けます。
pre-releaseとdraftがActionsのreleaseイベントに与える影響
ワークフローの on: release には published・unpublished・created・edited・deleted・prereleased・released の7種類があります。公式ドキュメント「ワークフローをトリガーするイベント」の注記で押さえるべき点は2つです。
- draftに対する
created・edited・deletedではワークフローが起動しません。Web画面で作ったリリースは自動的にdraftとして保存されることがあります。 - draftから公開したpre-releaseでは
prereleasedが発火せず、publishedだけが発火します。正式版とpre-releaseの両方で動かしたいならreleased+prereleasedではなくpublishedを購読します。
前述のとおり、gh はアセット付きのリリースをdraft経由で公開するため、prereleased だけを待つワークフローはgh経由のpre-releaseでは起動しません。
アセットの配布と上限
アセット数とファイルサイズの上限
GitHub.comでは、1つのリリースに関連付けられるアセットは1,000個まで、各ファイルは2GiB未満です。リリース全体の合計サイズと帯域の使用量には上限がありません(「リリースについて」の「Storage and bandwidth quotas」)。リリース機能自体に料金はかかりません。
2GiB以上の配布物は分割するか、クラウドストレージやコンテナレジストリに置きます。アセットごとの download_count はREST APIのリリース取得結果に含まれ、ダウンロード数の推移を追う材料になります。
最新版への固定リンクとrelease-assets.githubusercontent.com
公式ドキュメント「リリースへのリンク」のとおり、最新リリースのページは https://github.com/OWNER/REPO/releases/latest、手動でアップロードしたアセットの直リンクは .../releases/latest/download/ファイル名 で張れます。2026年10月23日に cli/cli(Latest=v2.103.0)で叩いた結果は次のとおりです。
$ curl -sI https://github.com/cli/cli/releases/latest/download/gh_2.103.0_checksums.txt
HTTP/2 302
location: https://github.com/cli/cli/releases/download/v2.103.0/gh_2.103.0_checksums.txt
$ curl -sI https://github.com/cli/cli/releases/download/v2.103.0/gh_2.103.0_checksums.txt
HTTP/2 302
location: https://release-assets.githubusercontent.com/github-production-release-asset/212613049/...
$ curl -sI https://github.com/cli/cli/releases/latest/download/gh_2.101.0_checksums.txt
HTTP/2 302
location: https://github.com/cli/cli/releases/download/v2.103.0/gh_2.101.0_checksums.txt
# 転送先は HTTP/2 404
latest/download はまずLatestのタグのURLへ転送され、実ファイルは release-assets.githubusercontent.com から配信されます。社内プロキシやファイアウォールでGitHubのダウンロードが止まる場合は、許可リストにこのドメインが入っているかを確認します。
3つ目の結果が示すとおり、latest/download はファイル名まではたどってくれません。cli/cli のようにアセット名に版番号を入れる運用では、固定リンクは次の版で404になります。インストールスクリプトやREADMEに固定リンクを載せるなら、app-linux-amd64.tar.gz のように版番号を含まない名前のアセットを添付します。版番号入りの名前を変えたくない場合は、gh release download --pattern '*linux_amd64.tar.gz' のようにパターンで取得させます。
新しいリリースの通知・取得手段(Watch・Atomフィード・API)
使っているOSSの新版を追うだけなら、リポジトリの「Watch」→「Custom」で「Releases」だけを選びます。Issueやプルリクエストの通知を受けずに、リリースの公開だけが通知されます(Web通知かメールかは通知設定で選びます)。
通知を増やしたくない場合やRSSリーダー・Slackに流したい場合は、https://github.com/OWNER/REPO/releases.atom のAtomフィードを購読します。公開リポジトリなら認証は不要で、タグだけを追う tags.atom もあります。注意点は、フィードにはpre-releaseも載ることです。2026年10月23日に kubernetes/kubernetes/releases.atom を取得すると、先頭2件はpre-releaseの v1.38.0-alpha.2 と v1.38.0-alpha.1 で、Latestの v1.37.1 は3件目でした。正式版だけを拾う場合は、APIの prerelease と draft が両方とも false のリリースを選びます。タイトルやタグ名のハイフンだけでは判定できません。
# 正式版の最新だけを取得する(draftとpre-releaseを除外)
gh api repos/kubernetes/kubernetes/releases/latest --jq '.tag_name'
# pre-releaseも含めて新しい順に5件
gh release list -R kubernetes/kubernetes -L 5
GitHub Actionsでリリースを自動化する構成
タグのpushでリリースを作るワークフロー
最小構成は、v で始まるタグのpushを起点に、ビルドした成果物をgh CLIで添付する形です。GitHubホストのUbuntuランナーにはgh CLIが入っているため、リリース用のアクションを追加せずに済みます。make dist は配布ファイルを dist ディレクトリ直下に出力するビルド手順の例で、実際のプロジェクトのビルド手順に置き換えます。タグの "!v*-*" は、v1.5.0-beta.1 のようなハイフン付きタグを除外します。正式版のタグをハイフンなし、pre-releaseのタグをハイフン付きで統一する運用が前提です。
# .github/workflows/release.yml
name: release
on:
push:
tags:
- "v*"
- "!v*-*"
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: make dist
- name: Publish release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$GITHUB_REF_NAME" dist/* --generate-notes --verify-tag
リリースの作成には contents: write が必要で、既定の権限が読み取り専用のリポジトリではこの指定が無いと失敗します。権限の考え方は「GitHub Actionsのpermissions|GITHUB_TOKENの既定権限と最小権限の設計」、タグやブランチの絞り込みは「GitHub Actionsのトリガー(on)|イベント選定とbranches・pathsフィルタの設計」で詳しく扱っています。ビルドからリリースまでのパイプライン全体を組み直す場合は、DevOps・CI/CD導入支援でも相談を受けています。
GITHUB_TOKENによるリリース公開と後続ワークフローの起動制限
公式ドキュメントは、リポジトリの GITHUB_TOKEN で行った操作によるイベントは、workflow_dispatch と repository_dispatch などの例外を除き新しいワークフロー実行を作らないと定めています。再帰的な実行を防ぐための仕様です。
そのため、上のワークフローが GITHUB_TOKEN で公開したリリースを on: release で受けて、Homebrewの更新やSlack通知を行う別のワークフローは動きません。バージョンを上げてタグを打つワークフローを GITHUB_TOKEN で動かした場合も、そのタグのpushで起動するはずのリリース用ワークフローは動きません。対処は、後続処理を同じワークフローのジョブとしてつなぐ、GitHub Appのトークンを使う、必要な権限を付けて workflow_dispatch や repository_dispatch で明示的に起動する、のいずれかです。
タグ命名とバージョン番号の決め方
UIのLatest自動判定はセマンティックバージョニングの大小を使うため、タグは v1.4.0 のようにSemVer形式でそろえます。release-2026-09 のような日付タグと混在させると、どれがLatestになるかを予測しにくくなります。pre-releaseは v1.5.0-beta.1 のようにハイフン以降で表し、pre-releaseの印も付けます。番号の上げ方とブランチ運用は「バージョニングとは?セマンティック/APIバージョニングの意味と運用設計を実装者向けに解説【2026年】」と「Git運用のベストプラクティス|ブランチ戦略・コミット規約・レビュー基準の決め方」を参照してください。
よくある質問
GitHub Releasesとは何ですか?
Gitタグにリリースノートと配布ファイルを加えて、リポジトリの「Releases」ページで公開するGitHubの機能です。タグはGitの機能で特定のコミットを指す名前にすぎず、タグだけをpushしてもリリースはできません。リリースを削除してもタグは残ります。
GitHubのリリースはどうやって作りますか?
Web画面ではリポジトリの「Releases」→「Draft a new release」でタグを選び、ノートを書いて「Publish release」を押します。コマンドラインでは gh release create v1.4.0 --generate-notes --verify-tag のように実行します。
GitHubのリリースはどこにありますか?
https://github.com/OWNER/REPO/releases です。リポジトリトップの右サイドバー「Releases」からも開けます。リリースを作っていないタグは、同じページ上部の「Tags」タブに表示されます。
GitHub Releasesは無料で使えますか?
使えます。リリース機能自体に料金はなく、GitHub.comではリリース全体の容量と帯域にも上限がありません。制限は1リリースあたり1,000アセットと、1ファイル2GiB未満の2つです。
GitHub PackagesとReleasesはどう使い分けますか?
npmやDockerなどパッケージマネージャーから取得させるならPackages、人やスクリプトがバイナリ・インストーラーをダウンロードするならReleasesです。Actionsのアーティファクトはジョブ間の一時的な受け渡し用で、配布には向きません。