Class: Fastlane::Wpmreleasetoolkit::Versioning::ContinuousBuildCodeFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/continuous_build_code_formatter.rb

Overview

The ‘ContinuousBuildCodeFormatter` derives an Android Play Store `versionCode` for a “continuous trunk” release model, where the low-order term is a high-cardinality, monotonically increasing build number (e.g. a Buildkite build number).

The build code is computed as:

versionCode = (major * 10 + minor) * 10^build_digits + build_number

It takes ‘major`, `minor`, and `build_number` as explicit arguments rather than an `AppVersion`, because the inputs come from different sources and an `AppVersion` does not model them: the marketing `major`/`minor` come from the parsed version, while `build_number` is an independent CI counter (e.g. `BUILDKITE_BUILD_NUMBER`). Notably, `AppVersion#build_number` means something else in this domain (the RC/beta iteration counter, e.g. `-rc-1`), so taking an `AppVersion` here would invite reading the wrong field. There is also no `patch`: in a continuous-trunk model the build number strictly orders every build and subsumes patch’s ordering role (hotfixes get a new build number, not a patch digit in the code).

Because the build number is globally monotonic and the version prefix only ever increases, the resulting code is always strictly increasing — even if the build number eventually exceeds ‘10^build_digits` (which only costs human-readability, not ordering). The only hard correctness constraint is staying at or below the Play Store’s max versionCode.

Unlike ‘DerivedBuildCodeFormatter` (fixed-width string concatenation capped at 8 total digits and 3 digits per component, i.e. build <= 999), this formatter can hold a large build number. The two formatters target different release models; this one does not replace the other.

Instance Method Summary collapse

Constructor Details

#initialize(build_digits: 6) ⇒ ContinuousBuildCodeFormatter

multiplier applied to the ‘major * 10 + minor` prefix (multiplier = 10^build_digits). Must be a positive integer. Defaults to 6 (multiplier = 1_000_000).

Parameters:

  • build_digits (Integer) (defaults to: 6)

    Number of digits reserved for the build number, which sets the



39
40
41
42
# File 'lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/continuous_build_code_formatter.rb', line 39

def initialize(build_digits: 6)
  validate_build_digits!(build_digits)
  @build_digits = build_digits
end

Instance Method Details

#build_code(major:, minor:, build_number:) ⇒ Integer

Derive the build code (Android ‘versionCode`).

(e.g. a Buildkite build number). This is a CI counter, not ‘AppVersion#build_number`.

Parameters:

  • major (Integer)

    The major (marketing) version number.

  • minor (Integer)

    The minor (marketing) version number. Must be 9 or lower.

  • build_number (Integer)

    A high-cardinality, monotonically increasing build number

Returns:

  • (Integer)

    The derived ‘versionCode`.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/continuous_build_code_formatter.rb', line 53

def build_code(major:, minor:, build_number:)
  # Validate up front so bad input (e.g. strings from env vars or file reads) raises a
  # user-friendly error rather than an opaque `TypeError` from the arithmetic below.
  validate_component!('major', major)
  validate_component!('minor', minor)
  validate_component!('build_number', build_number)

  # `major * 10 + minor` is only unambiguous while minor is a single digit.
  if minor > 9
    UI.user_error!("Minor version (#{minor}) must be 9 or lower to derive an unambiguous build code with `#{self.class.name}`")
  end

  prefix = (major * 10) + minor
  code = (prefix * (10**@build_digits)) + build_number

  # Sanity check: Play Store versionCodes must be positive integers.
  if code <= 0
    UI.user_error!("Derived build code (#{code}) must be a positive integer")
  end

  if code > MAX_PLAY_STORE_VERSION_CODE
    UI.user_error!("Derived build code (#{code}) exceeds the maximum allowed Play Store versionCode (#{MAX_PLAY_STORE_VERSION_CODE})")
  end

  code
end