列挙型の作成

新しい列挙型を作成する場合は、データベース型SMALLINT. SMALLINT型のサイズは2SMALLINTバイトで SMALLINT、列挙型としては十分です。これはデータベースの容量を節約するのに役立ちます。

この型を使うには、カラムを作成するマイグレーションにlimit: 2 を追加します。

使用例:

def change
  add_column :ci_job_artifacts, :file_format, :integer, limit: 2
end

全てのキーと値のペアはFOSSで定義されている必要があります。

要約: モデルもFOSSの一部である場合は、全ての列挙型をFOSSで定義する必要があります。

class Model < ApplicationRecord
  enum platform: {
    aws: 0,
    gcp: 1      # EE-only
  }
end

新しいkey/valueペアをenumに追加するときenum 、それがEE固有のものであれば、以下のように整理したくなるかも enumしれません:

# Define `failure_reason` enum in `Pipeline` model:
class Pipeline < ApplicationRecord
  enum failure_reason: Enums::Pipeline.failure_reasons
end
# Define key/value pairs that used in FOSS and EE:
module Enums
  module Pipeline
    def self.failure_reasons
      { unknown_failure: 0, config_error: 1 }
    end
  end
end

Enums::Pipeline.prepend_mod_with('Enums::Pipeline')
# Define key/value pairs that used in EE only:
module EE
  module Enums
    module Pipeline
      override :failure_reasons
      def failure_reasons
        super.merge(job_activity_limit_exceeded: 2)
      end
    end
  end
end

しかし、これにはいくつかの欠点があります:

  • 誰かがEEで定義したキーと値のペアがFOSSで定義した値と衝突してしまう可能性があります。例えば、EE::Enums::Pipelinejob_activity_limit_exceeded: 1 を定義します。
  • このようなことが起きると、機能の動作が全く異なってしまいます。例えば、failure_reasonconfig_errorjob_activity_limit_exceededのどちらであるかはわかりません。
  • このような場合、データの整合性を修正するためにデータベースのマイグレーションを行わなければなりません。

また、EE モジュールの値にオフセットを設定することで、この問題を回避できるかもしれません。例えば、この例ではオフセットとして1000 を設定しています:

module EE
  module Enums
    module Pipeline
      override :failure_reasons
      def failure_reasons
        super.merge(job_activity_limit_exceeded: 1_000, size_limit_exceeded: 1_001)
      end
    end
  end
end

しかし、この方法にはいくつかの欠点があります:

  • EEからFOSSへ、またはその逆へ機能が移動する可能性があります。そのため、将来的にFOSSとEEの間でオフセットが混在する可能性があります。例えば、job_activity_limit_exceeded をFOSSに移動すると、{ unknown_failure: 0, config_error: 1, job_activity_limit_exceeded: 1_000 }.
  • enum の整数カラムはSMALLINTとして作成されている可能性が高いです。したがって、オフセットが2バイト整数の最大値を超えないように注意する必要があります。

結論として、FOSSでは全てのキーと値のペアを定義すべきです。例えば、上記のケースでは以下のようなコードを書くことができます:

class Pipeline < ApplicationRecord
  enum failure_reason: {
    unknown_failure: 0,
    config_error: 1,
    job_activity_limit_exceeded: 2
  }
end

隙間に新しい値を追加

EEとFOSSの列挙型をマージした後、2つの値のグループの間にギャップが生じることがあります:

module Enums
  module Ci
    module CommitStatus
      def self.failure_reasons
        {
          # ...
          data_integrity_failure: 12,
          forward_deployment_failure: 13,
          insufficient_bridge_permissions: 1_001,
          downstream_bridge_project_not_found: 1_002,
          # ...
        }
      end
    end
  end
end

新しい値を追加するには、まずその隙間を埋める必要があります。上記の例では、1_003 の代わりに14 を追加しています:

{
  # ...
  data_integrity_failure: 12,
  forward_deployment_failure: 13,
  a_new_value: 14,
  insufficient_bridge_permissions: 1_001,
  downstream_bridge_project_not_found: 1_002,
  # ...
}