---
title: "GitLab Releaseの作り方：CIのreleaseキーワードとglabで自動作成する手順【2026年11月】"
url: "https://www.issoh.co.jp/tech/details/19665/"
published: 2026-11-12
updated: 2026-11-12
categories: ["開発"]
publisher: "株式会社一創"
---

# GitLab Releaseの作り方：CIのreleaseキーワードとglabで自動作成する手順【2026年11月】

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ドキュメント](https://docs.gitlab.com/user/project/releases/)は、リリースを「プロジェクトの節目でコード・バイナリ・ドキュメント・リリースノートをまとめたスナップショット」と定義しています。作成すると、GitLabはタグの付いたソースコードをアーカイブし、監査用のリリース証跡（release evidence）を生成します。

ソースコードは`zip`・`tar.gz`・`tar.bz2`・`tar`の4形式で自動添付され、読み取り専用です。人が足すのは、Markdownのリリースノート、マイルストーン、ビルド成果物や手順書へのリンク（アセットリンク）です。

タグ名は[Release fieldsのページ](https://docs.gitlab.com/user/project/releases/release%5Ffields/)でセマンティックバージョニングが推奨されています。`16.10.1`なら16がメジャー、10がマイナー、1がパッチです。後述のChangelog APIもこの形式のタグから版を読み取るので、最初から揃えておくと自動化が楽になります。

### タグを消すとリリースも消え、リリースを消してもタグは残る非対称

リリースとタグの削除は対称ではありません。リリースに紐付いたGitタグを削除すると、リリースも一緒に削除されます。一方で、[Releases API](https://docs.gitlab.com/api/releases/)のページには「リリースを削除しても関連するタグは削除されない」と明記されています。

誤ったタグを消して打ち直すと、付けていたリリースノートとアセットリンクも消えます。タグを消す前に、ノートの本文を控えておきます。

リリースの`released_at`を未来の日時にすると「Upcoming Release」、過去の日時にすると「Historical release」のバッジが付きます。過去日付のリリースには証跡が作られない点は、監査用に証跡を残したい案件で見落としやすい仕様です。

### 作成・編集はDeveloper以上、保護タグには作成権限も必要という権限条件

リリースの作成・編集・削除ができるのはDeveloper・Maintainer・Ownerで、Reporterは閲覧とダウンロードだけです。Guestも閲覧できますが、ソースコードと証跡は表示されません。

見落としやすいのは保護タグです。保護タグに紐付くリリースを作るには、ロールに加えて、その保護タグを作成する権限も要ります。権限が無いと`403 Forbidden`で失敗するため、`v*`を保護タグにしているプロジェクトでは、CIジョブを動かすユーザーが許可リストに入っているかを先に確かめます。

## 画面からGitLab Releaseを作る手順とアセットリンク・固定URLの設定

### Deploy＞Releasesから既存タグを選びノートを書く画面操作の5手順

CIを組む前に、一度画面で作っておくと各項目の意味がつかめます。手順は次のとおりです。

1. プロジェクトの左メニューで**Deploy＞Releases**を開き、**New release**を選ぶ
2. **Tag name**で既存のタグを選ぶか、新しいタグ名を入力して作成元のブランチやコミットを指定する
3. **Release title**を入力する（空欄ならタグ名がタイトルになる）
4. 必要ならマイルストーンを選び、リリースノートをMarkdownで書く
5. 配布ファイルや手順書の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](https://docs.gitlab.com/user/project/releases/release%5Fcicd%5Fexamples/)の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の選び方と登録手順](https://www.issoh.co.jp/tech/details/19633/)で整理しています。

[CI/CD YAML構文リファレンス](https://docs.gitlab.com/ci/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のリリースブランチの切り方](https://www.issoh.co.jp/tech/details/19637/)で扱っています。`rules`と`workflow:rules`の評価順は[GitLab CI/CDの.gitlab-ci.ymlの書き方](https://www.issoh.co.jp/tech/details/19661/)が詳しいです。

## release-cliからglabへの移行時に必要なコマンドと認証設定の注意点

### release-cliは18.0で非推奨・20.0で削除予定という時点の整理

[GitLab Release CLI toolのページ](https://docs.gitlab.com/user/project/releases/release%5Fcli/)は、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のページ](https://docs.gitlab.com/ci/jobs/ci%5Fjob%5Ftoken/)によれば、ジョブトークンはReleases APIのすべてのエンドポイントに使えるため、個人のアクセストークンをCI変数に置く必要はありません。

[glab release create](https://docs.gitlab.com/cli/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機能](https://docs.gitlab.com/user/project/changelogs/)は、コミットに`Changelog: added`のようなGitトレーラーを付けておくと、それを集めてMarkdownのノートを作ります。カテゴリは`added`・`fixed`・`changed`・`deprecated`・`removed`・`security`・`performance`・`other`の8種類です。

[Repositories API](https://docs.gitlab.com/api/repositories/)の`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のマージリクエストのマージ方式の設定](https://www.issoh.co.jp/tech/details/19663/)とあわせて決めます。

### ビルド成果物を汎用パッケージへ上げてassets:linksから配る構成

リリースにジョブのアーティファクトのURLを直接添付する方法は、アーティファクトの期限切れや削除で404になるため推奨されていません。代わりに、[汎用パッケージリポジトリ](https://docs.gitlab.com/user/packages/generic%5Fpackages/)へ上げたファイルをアセットリンクに載せます。

```
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導入支援](https://www.issoh.co.jp/service/system/devops/)で設計から支援しています。

利用者側の立場でGitLab本体のセキュリティリリースを読み、いつ上げるかを決める手順は[GitLab脆弱性の対応手順と修正版の判断基準](https://www.issoh.co.jp/tech/details/18332/)にあります。

### 社内向け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の使い方とリリースノート自動生成](https://www.issoh.co.jp/tech/details/6534/)で解説しています。

### 同じタグでリリースを作り直すことはできますか？

リリースを削除してから再実行すれば作り直せます。リリースを消してもタグは残るため、同じタグ名をそのまま使えます。先にタグを消すとリリースも消えるので、順番を逆にしないでください。`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月】](https://www.issoh.co.jp/tech/details/19661/)：リリースジョブを載せるパイプライン全体の書き方を確認できます
- [GitHub Releasesの使い方｜タグとの違い・リリースノート自動生成・Latestの決まり方](https://www.issoh.co.jp/tech/details/6534/)：GitHub側の同じ機能と比べたいときに読めます
- [GitLab Flowとは：環境ブランチの組み方とGit Flow・GitHub Flowとの違い【2026年11月】](https://www.issoh.co.jp/tech/details/19637/)：リリースブランチをどう切るかを決めるときの前提になります
- [GitLabの使い方：プロジェクト作成からIssue・MR・CI/CDまでの手順【2026年10月】](https://www.issoh.co.jp/tech/details/18874/)：プロジェクト作成から最初のパイプラインまでを画面操作でたどれます
- [GitHubとGitLabの違い｜ActionsとGitLab CIの対応表・料金・セルフホスト比較](https://www.issoh.co.jp/tech/details/4219/)：GitHub ActionsのリリースワークフローをGitLab CIへ移すときの対応表があります

---

出典: [GitLab Releaseの作り方：CIのreleaseキーワードとglabで自動作成する手順【2026年11月】](<https://www.issoh.co.jp/tech/details/19665/>)（株式会社一創）
