変更履歴

チェンジログはコミットタイトルと Git トレーラーに基づいて生成されます。変更ログに含めるには、コミットに特定の Git トレーラーが含まれている必要があります。チェンジログはコミットタイトルから生成され、Git トレーラーの種類によって分類されます。マージリクエストへのリンクやコミット作成者の詳細など、追加データで変更履歴を充実させることができます。チェンジログのフォーマットはテンプレートでカスタマイズできます。

デフォルトの変更ログの各セクションには、このようにバージョン番号とリリース日を含むタイトルがあります:

## 1.0.0 (2021-01-05)

### Features (4 changes)

- [Feature 1](gitlab-org/gitlab@123abc) by @alice ([merge request](gitlab-org/gitlab!123))
- [Feature 2](gitlab-org/gitlab@456abc) ([merge request](gitlab-org/gitlab!456))
- [Feature 3](gitlab-org/gitlab@234abc) by @steve
- [Feature 4](gitlab-org/gitlab@456)

セクションの日付の書式はカスタマイズできますが、タイトルの残りの部分はカスタマイズできません。新しいセクションを追加するとき、GitLabはこれらのタイトルを解析して新しい情報をファイルのどこに置くかを決定します。GitLabは、日付ではなくバージョンに従ってセクションをソートします。

各セクションは、(Featuresのように)カテゴリー別にソートされた変更を含み、これらのセクションのフォーマットは変更することができます。セクション名は、コミットをインクルードしたり除外したりする Git トレーラーの値に由来します。

変更ログのコミットは、ミラー上でのオペレーションで取得することができます。GitLab 自身がこの機能を使っています。セキュリティリリースは公開プロジェクトと非公開セキュリティミラーの両方からの変更を含むことができるからです。

Git コミットへのトレーラーの追加

コミットメッセージを書く際には、手動でトレーラを追加することができます。デフォルトのトレイラーであるChangelog を使ってコミットを機能として分類するには、コミットメッセージに次のように文字列Changelog: feature を追加します:

<Commit message subject>

<Commit message description>

Changelog: feature

変更履歴の作成

変更ログはコマンドラインから API か GitLab CLI を使って生成します。変更ログの出力は Markdown でフォーマットされ、カスタマイズすることができます。

API から

curl コマンドを使って API から変更ログを生成するには、API ドキュメントのAdd changelog data to a changelog fileを参照してください。

GitLab CLI から

glab バージョン 1.30.0 で導入されました

前提条件:

変更履歴を生成するには

  1. リポジトリの内部コピーをgit fetch で更新してください。
  2. デフォルトのオプションで現在のバージョン(git describe --tags によって決定されます)の変更ログを生成するには、次のようにします:
    • コマンドglab changelog generate を実行します。
    • 出力をファイルに保存するには、コマンドglab changelog generate > <filename>.md を実行します。
  3. オプションをカスタマイズして変更ログを生成するには、glab changelog generate コマンドを実行し、希望のオプションを追加します。いくつかのオプションがあります:

    • --config-file [string]:プロジェクトの Git リポジトリにある変更ログ設定ファイルへのパス。デフォルトは.gitlab/changelog_config.yml です。
    • コミット範囲:
      • --from [string]:変更履歴の生成に使用するコミット範囲の開始位置 (SHA) です。このコミット自体は変更履歴には含まれません。
      • --to [string]:変更履歴の生成に使用するコミット範囲の終了位置 (SHA 形式)。このコミットはリストに含ま_れます_。デフォルトはデフォルトプロジェクトブランチのHEAD です。
    • --date [string]:ISO 8601 (2016-03-11T03:45:40Z) フォーマットでのリリース日時。デフォルトは現在の時刻です。
    • --trailer [string]:コミットを含める Git のトレーラー。デフォルトはChangelog
    • --version [string]:変更履歴を生成するバージョン。

GitLab CLI で利用できるパラメータの詳細については、glab changelog generate --help を実行してください。定義や使い方についてはAPI ドキュメントを参照してください。

変更ログ出力のカスタマイズ

変更ログ出力をカスタマイズするには、変更ログ設定ファイルを編集してください。この設定のデフォルトの場所は.gitlab/changelog_config.yml です。このファイルは以下の変数に対応しています:

  • date_format:新しく追加される変更ログデータのタイトルに使われるstrftime 形式の日付フォーマット。
  • template:変更履歴データを生成するときに使用するカスタムテンプレート。
  • include_groups:プロジェクトのメンバーシップに関係なく貢献者がクレジットされるべきユーザーを含むグループのフルパスのリスト。変更ログを生成するユーザーは、クレジットを与えるために各グループへのアクセス権を持っていなければなりません。
  • categories:生のカテゴリ名を変更ログで使う名前にマップするハッシュ。変更ログに表示される名前を変更するには、設定ファイルにこれらの行を追加し、あなたのニーズに合うように編集してください。この例では、カテゴリのタイトルを### Features,### Bug fixes,### Performance improvementsのようにレンダリングしています:

      ---
      categories:
        feature: Features
        bug: Bug fixes
        performance: Performance improvements
    

カスタムテンプレート

カテゴリセクションはテンプレートを使って生成されます。デフォルトのテンプレートは

{% if categories %}
{% each categories %}
### {{ title }} ({% if single_change %}1 change{% else %}{{ count }} changes{% end %})

{% each entries %}
- [{{ title }}]({{ commit.reference }})\
{% if author.credit %} by {{ author.reference }}{% end %}\
{% if merge_request %} ([merge request]({{ merge_request.reference }})){% end %}

{% end %}

{% end %}
{% else %}
No changes.
{% end %}

{% ... %} タグはステートメント用で、{{ ... }} は印刷データ用です。ステートメントは{% end %} タグで終了する必要があります。ifeach の両ステートメントには引数が1つ必要です。

例えば、valid という変数に対して、次のようにすると、この値が真のときは「yes」と表示し、そうでないときは「nope」と表示することができます:

{% if valid %}
yes
{% else %}
nope
{% end %}

else の使用は任意です。値は、空でない値または真偽値true のときに真とみなされます。空の配列やハッシュは偽とみなされます。

ループはeach を使用して行われ、ループ内部の変数はループにスコープされます。ループ内で現在の値を参照するには、変数タグ{{ it }} を使用します。他の変数はループの現在値から値を読み取ります。このテンプレートを例にとってみましょう:

{% each users %}
{{name}}
{% end %}

users がオブジェクトの配列で、それぞれにname フィールドがあるとすると、すべてのユーザーの名前が表示されます。

変数タグを使用すると、入れ子になったオブジェクトにアクセスすることができます。例えば、{{ users.0.name }} は、users 変数の最初のユーザーの名前を表示します。

行末がバックスラッシュの場合、次の改行は無視されます。これにより、Markdownの出力に不要な改行を導入することなく、複数行にわたってコードをラップすることができます。

{%%} (式タグとして知られています)を使用するタグは、もし改行があれば、それに直接続く改行を消費します。つまり、これは

---
{% if foo %}
bar
{% end %}
---

にコンパイルされます:

---
bar
---

この代わりに

---

bar

---

このように、設定にカスタムテンプレートを指定することができます:

---
template: |
  {% if categories %}
  {% each categories %}
  ### {{ title }}

  {% each entries %}
  - [{{ title }}]({{ commit.reference }})\
  {% if author.credit %} by {{ author.reference }}{% end %}

  {% end %}

  {% end %}
  {% else %}
  No changes.
  {% end %}

テンプレートを指定するときは、template: > ではなくtemplate: | を使うべきです。後者はテンプレート内で改行が保持されないからです。

テンプレートデータ

トップレベルでは、以下の変数が使用できます:

  • categoriesオブジェクトの配列です。

カテゴリでは、以下の変数が利用可能です:

  • countこのカテゴリのエントリ数。
  • entriesこのカテゴリーに属するエントリー
  • single_change: 変更がひとつだけ (true) か、複数 (false) かを示すブール値。
  • title: (リマップされた後の) カテゴリーのタイトル。

エントリでは、以下の変数が使用可能です(ここでfoo.bar は、barfoo のサブフィールドであることを意味します):

  • author.contributor作成者がプロジェクトメンバーでない場合はtrue 、そうでない場合はfalse
  • author.credit:author.contributortrue のとき、またはinclude_groups が設定されていて、作成者がいずれかのグループのメンバーであるとき、true に設定されるブール値。
  • author.reference: コミット作成者への参照 (例えば、@alice)。
  • commit.referenceコミットへの参照 (例:gitlab-org/gitlab@0a4cdd86ab31748ba6dac0f69a8653f206e5cfc7)。
  • commit.trailers: コミット本文に含まれる Git Trailer をすべて含むオブジェクト。
  • merge_request.reference: その変更を最初に導入したマージリクエストへの参照 (たとえばgitlab-org/gitlab!50063)。
  • title変更ログエントリのタイトル (これはコミットタイトルです)。

authormerge_request オブジェクトは、データが判断できない場合、存在しないかもしれません。例えば、対応するマージリクエストがないコミットが作成された場合、マージリクエストは表示されません。

バージョン抽出時のタグ形式のカスタマイズ

GitLab 13.11 で導入されました

GitLabはタグ名からセマンティックバージョンを抽出するために正規表現(re2エンジンと構文を使用)を使用します。デフォルトの正規表現は

^v?(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<pre>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<meta>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

この正規表現は公式のセマンティックバージョニング正規表現に基づいており、v で始まるタグ名のサポートも含まれています。

プロジェクトでタグに別の形式を使用している場合は、別の正規表現を指定できます。使用する正規表現は、以下のキャプチャ・グループを生成する_必要が_あります。これらのキャプチャー・グループのいずれかが欠けている場合、タグは無視されます:

  • major
  • minor
  • patch

以下のキャプチャグループはオプションです:

  • pre:設定されている場合、タグは無視されます。 preタグを無視するpreこと preで、リリース候補のタグやその他のリリース前のタグが、変更ログを生成するコミットの範囲を決定する際に考慮されないようになります。
  • meta:オプションです。ビルドのメタデータを指定します。

この情報を使って、GitLabはGitタグとそのリリースバージョンのマップを作成します。そして、各タグから抽出されたバージョンに基づいて、最新のタグが何かを決定します。

カスタム正規表現を指定するには、変更ログ設定 YAML ファイルのtag_regex 設定を使います。例えば、このパターンはversion-1.2.3 のようなタグ名にマッチしますが、version-1.2にはマッチしません。

---
tag_regex: '^version-(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)$'

正規表現が機能しているかテストするにはregex101 のようなウェブサイトを使うことができます。正規表現の構文が無効な場合、変更ログを生成するときにエラーが発生します。

コミットの取り消し処理

GitLab 13.10で導入されました

コミットをリバートコミットとして扱うには、コミットメッセージにThis reverts commit <SHA> という文字列が含まれていなければなりません。SHA はリバートするコミットの SHA です。

ある範囲の変更ログを生成するとき、GitLabはその範囲に追加されたコミットと差し戻されたコミットの両方を無視します。この例では、コミットCがコミットBを差し戻しました。コミットCには他のトレーラーはないので、コミットAだけが変更履歴に追加されます:

graph LR A[Commit A<br>Changelog: changed] --> B[Commit B<br>Changelog: changed] B --> C[Commit C<br>Reverts commit B]

しかし、もし差し戻しコミット (コミット C)_にも_変更履歴のトレーラが含まれていれば、コミット A と C の両方が変更履歴に含まれることになります:

graph LR A[Commit A<br><br>Changelog: changed] --> B[Commit B<br><br>Changelog: changed] B --> C[Commit C<br>Reverts commit B<br>Changelog: changed]

コミット B はスキップされます。