GitLab Releaseは、Gitタグ1本にリリースノート・配布ファイルへのリンク・監査用の証跡を束ね、利用者に「この版で何が変わり、どこから入手するか」を示すGitLab標準の機能です。本記事では、画面からの作成手順、.gitlab-ci.ymlのreleaseキーワードでタグ作成時に自動でリリースを作る設定例、非推奨のrelease-cliからglab release createへの移行、Changelog APIと汎用パッケージでのノート生成と配布を解説します。仕様は2026年11月12日時点の公式ドキュメントに基づきます。
まとめ:GitLab Releaseはタグに版の説明と配布物を束ね、CIではglabで作る
GitLab Releaseは全プランで使えます。Gitタグの上に作られるため、容量を食うのは添付するアセットと自動生成される証跡だけです。
CIから作るなら、ジョブにreleaseキーワードを書き、イメージをregistry.gitlab.com/gitlab-org/cli:latestにするのが現在の標準です。旧来のrelease-cliは20.0で削除予定なので、新しく組む構成では使いません。scriptからglabを直接呼ぶ場合は、GLAB_ENABLE_CI_AUTOLOGINをtrueにしてジョブトークンで認証します。
リリースを作る価値があるのは、利用者へ版を配る製品と、版ごとの変更内容を説明する責任がある案件です。社内向けWebアプリを1日に何度もデプロイする運用なら、タグとデプロイ履歴だけで足ります。
GitLab Releaseとは:タグ・リリースノート・アセット・証跡の関係
リリースはGitタグ1本にノートとアセットを結び付けたスナップショット
GitLabのReleasesドキュメントは、リリースを「プロジェクトの節目でコード・バイナリ・ドキュメント・リリースノートをまとめたスナップショット」と定義しています。作成すると、GitLabはタグの付いたソースコードをアーカイブし、監査用のリリース証跡(release evidence)を生成します。
ソースコードはzip・tar.gz・tar.bz2・tarの4形式で自動添付され、読み取り専用です。人が足すのは、Markdownのリリースノート、マイルストーン、ビルド成果物や手順書へのリンク(アセットリンク)です。
タグ名はRelease fieldsのページでセマンティックバージョニングが推奨されています。16.10.1なら16がメジャー、10がマイナー、1がパッチです。後述のChangelog APIもこの形式のタグから版を読み取るので、最初から揃えておくと自動化が楽になります。
タグを消すとリリースも消え、リリースを消してもタグは残る非対称
リリースとタグの削除は対称ではありません。リリースに紐付いたGitタグを削除すると、リリースも一緒に削除されます。一方で、Releases APIのページには「リリースを削除しても関連するタグは削除されない」と明記されています。
誤ったタグを消して打ち直すと、付けていたリリースノートとアセットリンクも消えます。タグを消す前に、ノートの本文を控えておきます。
リリースのreleased_atを未来の日時にすると「Upcoming Release」、過去の日時にすると「Historical release」のバッジが付きます。過去日付のリリースには証跡が作られない点は、監査用に証跡を残したい案件で見落としやすい仕様です。
作成・編集はDeveloper以上、保護タグには作成権限も必要という権限条件
リリースの作成・編集・削除ができるのはDeveloper・Maintainer・Ownerで、Reporterは閲覧とダウンロードだけです。Guestも閲覧できますが、ソースコードと証跡は表示されません。
見落としやすいのは保護タグです。保護タグに紐付くリリースを作るには、ロールに加えて、その保護タグを作成する権限も要ります。権限が無いと403 Forbiddenで失敗するため、v*を保護タグにしているプロジェクトでは、CIジョブを動かすユーザーが許可リストに入っているかを先に確かめます。
画面からGitLab Releaseを作る手順とアセットリンク・固定URLの設定
Deploy>Releasesから既存タグを選びノートを書く画面操作の5手順
CIを組む前に、一度画面で作っておくと各項目の意味がつかめます。手順は次のとおりです。
- プロジェクトの左メニューでDeploy>Releasesを開き、New releaseを選ぶ
- Tag nameで既存のタグを選ぶか、新しいタグ名を入力して作成元のブランチやコミットを指定する
- Release titleを入力する(空欄ならタグ名がタイトルになる)
- 必要ならマイルストーンを選び、リリースノートをMarkdownで書く
- 配布ファイルや手順書のURLをアセットのリンク欄に追加し、作成を確定する
1つのタグに付けられるリリースは1つだけで、別のリリースに紐付いたタグを選ぶとエラーになります。
アセットリンクのlink_type4種と最新版を取得する固定URLの設定
アセットリンクは、nameとurlが必須で、filepathとlink_typeは任意です。link_typeは画面での分類表示に使われるだけで、URLの挙動は変わりません。
| link_type | 想定する添付物 | 実務での使い分け |
|---|---|---|
| package | インストーラやバイナリ | 汎用パッケージに上げた実行ファイル |
| image | コンテナイメージ | コンテナレジストリのタグ付きイメージ |
| runbook | 運用手順書 | 切り戻し手順やリリース判定表のページ |
| other | 上記以外(既定値) | APIドキュメントや移行ガイド |
filepathを/bin/myapp-linux-amd64のように/始まりで指定すると、/-/releases/v1.2.0/downloads/bin/myapp-linux-amd64という固定URLで配れます。さらにタグ名の部分をpermalink/latestにすると常に最新リリースのファイルへ届くので、READMEのダウンロードリンクを版ごとに書き換える作業が無くなります。
.gitlab-ci.ymlのreleaseキーワードでタグ作成時に自動リリースする設定例
タグpushで動くrelease_jobの最小構成とcli:latestイメージの指定
最も単純な構成は、タグがpushされたパイプラインでだけリリースジョブを動かす形です。Release CI/CD examplesの1つ目の例と同じ考え方で書くと、次のようになります。
stages:
- release
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
rules:
- if: $CI_COMMIT_TAG
script:
- echo "Creating release for $CI_COMMIT_TAG"
release:
tag_name: $CI_COMMIT_TAG
name: "Release $CI_COMMIT_TAG"
description: "Release $CI_COMMIT_TAG"
releaseを使うジョブにもscriptは必須です。releaseの処理はscriptの後、after_scriptの前に走り、scriptが成功したときだけリリースが作られます。Shell executorのRunnerではイメージ指定が効かないため、Runnerのサーバーにglabをインストールし、実行時に参照される$PATHに通しておく設定が必要です。自前Runnerのexecutorの違いはGitLab Runnerのexecutorの選び方と登録手順で整理しています。
CI/CD YAML構文リファレンスのとおり、同じタグのリリースが既にあるとジョブは失敗します。画面でタグを作るときにノートまで入力するとその時点でリリースができるため、CIで作る運用では画面でタグだけを作ります。
releaseキーワードに指定する8つのサブキーと必須・任意の区別
releaseの下に書けるキーは8つです。実務で毎回書くのはtag_nameとdescriptionで、残りは用途に応じて足します。
| サブキー | 必須 | 内容 |
|---|---|---|
| tag_name | 必須 | 対象のタグ。無ければリリースと同時に作られる |
| description | 必須 | リリースノート。文字列かファイルパス |
| name | 任意 | リリース名。省略時はtag_name |
| tag_message | 任意 | 注釈付きタグのメッセージ。省略で軽量タグ |
| ref | 任意 | タグが無いときの作成元(SHA・ブランチ・タグ) |
| milestones | 任意 | 関連付けるマイルストーンのタイトル |
| released_at | 任意 | ISO 8601形式の日時。引用符で囲む |
| assets:links | 任意 | アセットリンクの4属性を持つ配列 |
表のassets:linksで指定する4属性は、name・url・filepath・link_typeです。各リンクの名前と参照先URL、固定URL用のパス、画面表示の分類を配列の要素として記述します。
descriptionにファイルを渡すときは、プロジェクトディレクトリからの相対パスを空白なしで書きます。前段のジョブで生成したMarkdownをそのまま渡せます。
デフォルトブランチへのマージでタグとリリースを同時に作る構成と二重実行の回避
タグを人が打たず、mainへのマージごとに版を進めたいチームもあります。この場合はrefにコミットSHAを渡し、タグとリリースを同時に作らせます。
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
rules:
- if: $CI_COMMIT_TAG
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- echo "Creating release v0.$CI_PIPELINE_IID"
release:
tag_name: "v0.$CI_PIPELINE_IID"
description: "v0.$CI_PIPELINE_IID"
ref: $CI_COMMIT_SHA
1つ目のルールが肝心です。リリースがタグを作るとタグのパイプラインが走るため、when: neverで除外しないとrelease_jobが再び動いて失敗します。CI_PIPELINE_IIDは増え続ける通し番号なので、意味のある版番号が要る製品にはタグ起点の方式が向きます。
リリースを切るブランチ自体の設計、たとえばマイナー版ごとに安定ブランチを持つかどうかは、GitLab Flowのリリースブランチの切り方で扱っています。rulesとworkflow:rulesの評価順はGitLab CI/CDの.gitlab-ci.ymlの書き方が詳しいです。
release-cliからglabへの移行時に必要なコマンドと認証設定の注意点
release-cliは18.0で非推奨・20.0で削除予定という時点の整理
GitLab Release CLI toolのページは、release-cliを「GitLab 18.0で非推奨、20.0で削除予定」とし、破壊的変更だと明記しています。releaseキーワードの中身も18.0からglabを使う方式に切り替わり、18.4で一般提供になりました。
移行の作業は書き方で2つに分かれます。releaseキーワードを使っているジョブは、イメージをregistry.gitlab.com/gitlab-org/release-cli:latestからregistry.gitlab.com/gitlab-org/cli:latestへ変えるだけです。scriptの中でrelease-cli createを直接呼んでいるジョブは、glab release createへの書き換えと認証の設定が要ります。
Runnerに必要な版のglabが無いと、releaseキーワードはrelease-cliへ切り替えて動くため、古いイメージでも今は動きます。この切り替えも20.0で削除される予定です。Releasesのページにはglabはv1.58.0以上が必要とあるので、Shell executorのRunnerではglab --versionで版を確かめます。
scriptからglabでリリースを作成する際のジョブトークン自動認証設定
アセットのファイルをまとめて上げたい、既存リリースを上書きしたいといった理由でscriptからglabを呼ぶ場合は、次のように書きます。
release_by_glab:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
variables:
GLAB_ENABLE_CI_AUTOLOGIN: "true"
rules:
- if: $CI_COMMIT_TAG
script:
- glab release create "$CI_COMMIT_TAG" --notes-file release_notes.md --no-update
GLAB_ENABLE_CI_AUTOLOGINをtrueにすると、glabはジョブトークンをJOB-TOKENヘッダーで送ります。CI/CD job tokenのページによれば、ジョブトークンはReleases APIのすべてのエンドポイントに使えるため、個人のアクセストークンをCI変数に置く必要はありません。
glab release createは、同じタグのリリースがあれば上書きします。releaseキーワードとは逆の挙動なので、再実行でノートを書き換えたくないなら--no-updateを付けます。
GITLAB_TOKENに$CI_JOB_TOKENを入れると404になる理由と回避策
移行で最も多い詰まりがこれです。GITLAB_TOKEN: $CI_JOB_TOKENと書くと、glabはそれを個人アクセストークンとしてPRIVATE-TOKENヘッダーで送ります。Releases APIはこのヘッダーでジョブトークンを受け付けないため、エラーの理由が分かりにくい404 Not Foundが返ります。
回避策は2つあります。ジョブトークンで済ませるならGLAB_ENABLE_CI_AUTOLOGINを使い、GITLAB_TOKENは定義しません。releaseキーワード側も、GITLAB_TOKEN・GITLAB_ACCESS_TOKEN・OAUTH_TOKENのどれかが定義されているとジョブトークンよりそちらを優先するため、プロジェクトのCI変数に古いGITLAB_TOKENが残っていないかも確認します。
もう1つは、apiスコープのプロジェクトアクセストークンをGITLAB_TOKENに入れる方法です。--milestoneでマイルストーンを閉じたい場合はこちらを選びます。Milestones APIはジョブトークンを受け付けないので、ジョブトークンのままだとリリースはできてもマイルストーンは開いたまま残り、ログにエラーが出ます。
リリースノートとバイナリ配布を自動化するChangelog APIと汎用パッケージ
ChangelogトレーラーとAPIによるリリースノート生成ジョブの構成
リリースノートを手で書く運用は、版が増えると続きません。GitLabのChangelogs機能は、コミットにChangelog: addedのようなGitトレーラーを付けておくと、それを集めてMarkdownのノートを作ります。カテゴリはadded・fixed・changed・deprecated・removed・security・performance・otherの8種類です。
Repositories APIのGET /projects/:id/repository/changelogは、ファイルへコミットせずにノートだけを返します。.txtを付けるとJSONではなくMarkdownの本文が返るので、そのままファイルに保存できる形式です。ジョブトークンで呼べるエンドポイントにも含まれています。
stages:
- prepare
- release
release_notes:
stage: prepare
image: alpine:latest
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
before_script:
- apk add --no-cache curl
script:
- VERSION="${CI_COMMIT_TAG#v}"
- curl --fail --silent --show-error --header "JOB-TOKEN: $CI_JOB_TOKEN" --output release_notes.md "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/changelog.txt?version=$VERSION&to=$CI_COMMIT_SHA"
artifacts:
paths:
- release_notes.md
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
needs:
- job: release_notes
artifacts: true
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
script:
- echo "Creating release for $CI_COMMIT_TAG"
release:
tag_name: $CI_COMMIT_TAG
description: ./release_notes.md
versionはセマンティックバージョンの形式が必須なので、タグの先頭のvを外して渡しています。fromを省くと直前の安定版タグが起点として自動検出され、-rc1のようなプレリリースのタグは対象外です。トレーラーが無いと空のノートになるので、マージリクエストのテンプレートで付け方を案内します。squashマージを使う場合の扱いはGitLabのマージリクエストのマージ方式の設定とあわせて決めます。
ビルド成果物を汎用パッケージへ上げてassets:linksから配る構成
リリースにジョブのアーティファクトのURLを直接添付する方法は、アーティファクトの期限切れや削除で404になるため推奨されていません。代わりに、汎用パッケージリポジトリへ上げたファイルをアセットリンクに載せます。
upload_binary:
stage: upload
image: alpine:latest
rules:
- if: $CI_COMMIT_TAG
before_script:
- apk add --no-cache curl
script:
- curl --fail --location --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file dist/myapp-linux-amd64 "$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/myapp/$CI_COMMIT_TAG/myapp-linux-amd64"
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
needs: ["upload_binary"]
rules:
- if: $CI_COMMIT_TAG
script:
- echo "Creating release for $CI_COMMIT_TAG"
release:
tag_name: $CI_COMMIT_TAG
description: "Release $CI_COMMIT_TAG"
assets:
links:
- name: myapp-linux-amd64
url: "$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/myapp/$CI_COMMIT_TAG/myapp-linux-amd64"
filepath: /bin/myapp-linux-amd64
link_type: package
アップロードが成功すると201 Createdが返ります。ファイル名に使えるのは英数字と.・_・-・+・~・@・/で、空白は使えません。filepathを付けたので、利用者は/-/releases/permalink/latest/downloads/bin/myapp-linux-amd64で常に最新版を取得できます。プライベートなプロジェクトでは、この固定URLの取得にread_api以上のスコープを持つトークンが要る点に注意します。
GitLab Releaseを作る条件とタグだけで済ませる場面の判断基準
利用者へ版を配る製品と版ごとに変更を説明する受託案件で採用する条件
リリースを作るべきなのは、次のどれかに当てはまる場合です。版番号で問い合わせが来るCLIやライブラリ、オンプレミスに納めるパッケージのように、利用者が版を選んで入手する製品。納品のたびに「この版で直した不具合」を発注元へ説明する受託開発。そして、版ごとのコミットとパイプラインの記録を証跡として残す必要がある案件です。
タグだけだと、正式な配布物と入った修正を毎回別の場所で説明することになります。リリースに集めておけば、答えはURL1本です。リリース工程をCIに組み込み、ノート生成から配布までを自動で回す構成づくりは、DevOps・CI/CD導入支援で設計から支援しています。
利用者側の立場でGitLab本体のセキュリティリリースを読み、いつ上げるかを決める手順はGitLab脆弱性の対応手順と修正版の判断基準にあります。
社内向けWebアプリを常時デプロイする運用でリリースを作らない判断
社内向けのWebアプリを1日に何度もmainからデプロイしている運用では、リリースは作りません。利用者が版を選ばないので、ノートを読む人がいないからです。デプロイの記録は環境ごとのデプロイ履歴で追え、切り戻しはコミット単位で足ります。
この運用でマージごとにリリースを作ると、一覧が数百件に膨らみ、節目の版が埋もれます。節目の版だけにリリースを付け、それ以外はデプロイ履歴に任せる線引きにします。
よくある質問:GitLab Releaseの作成・更新・配布で迷う5つの点
GitLab Releaseを使い始めるときによく出る疑問を、2026年11月時点の公式ドキュメントに沿ってまとめました。
GitLab ReleaseとGitHub Releasesの違いは何ですか?
タグにノートと配布物を束ねる考え方は同じです。違うのは配布物の置き場所で、GitHubはファイルをリリースに直接添付し、GitLabはアセットリンクでURLを指してファイル本体を汎用パッケージなどに置きます。CIからは、GitLabはreleaseキーワード、GitHubはgh release createなどで作成する方式です。GitHub側の手順はGitHub Releasesの使い方とリリースノート自動生成で解説しています。
同じタグでリリースを作り直すことはできますか?
リリースを削除してから再実行すれば作り直せます。リリースを消してもタグは残るため、同じタグ名をそのまま使えます。先にタグを消すとリリースも消えるので、順番を逆にしないでください。glab release createなら削除せずに上書きもでき、releaseキーワードは既存があると失敗で止まります。
過去の版へ修正リリースを出すと最新版の扱いはどうなりますか?
最新の判定はreleased_atの新しい順で、セマンティックバージョン順の並び替えは2026年11月時点で未実装です。2.4系を出した後に2.3系の修正版を出すと、2.3系がpermalink/latestの行き先になります。複数の系統を並行して保守する製品では、permalink/latestではなく版番号入りのURLを案内します。
マイルストーンをリリースに紐付けると何が起きますか?
リリースのページにマイルストーンの進捗が表示され、どのIssueがその版に入ったかを追えます。glab release create --milestoneはリリース後にマイルストーンを閉じますが、ジョブトークンでは閉じられません。閉じる処理が要るならapiスコープのプロジェクトアクセストークンを使います。
Self-ManagedのGitLabでもリリース機能は使えますか?
使えます。ReleasesとReleases APIは、GitLab.com・Self-Managed・Dedicatedの全プラン(Free〜Ultimate)で提供されています。グループのマイルストーンを紐付ける機能だけはPremium以上です。18.0より前の版ではrelease-cliのイメージを指定した構成が残りがちなので、20.0へ上げる前にイメージをcli:latestへ揃えます。
関連記事
- GitLab CI/CDとは:.gitlab-ci.ymlの書き方とrules・needs・変数の設定例【2026年11月】:リリースジョブを載せるパイプライン全体の書き方を確認できます
- GitHub Releasesの使い方|タグとの違い・リリースノート自動生成・Latestの決まり方:GitHub側の同じ機能と比べたいときに読めます
- GitLab Flowとは:環境ブランチの組み方とGit Flow・GitHub Flowとの違い【2026年11月】:リリースブランチをどう切るかを決めるときの前提になります
- GitLabの使い方:プロジェクト作成からIssue・MR・CI/CDまでの手順【2026年10月】:プロジェクト作成から最初のパイプラインまでを画面操作でたどれます
- GitHubとGitLabの違い|ActionsとGitLab CIの対応表・料金・セルフホスト比較:GitHub ActionsのリリースワークフローをGitLab CIへ移すときの対応表があります