Class: GitHubRunnerMatrix

Inherits:
Object show all
Includes:
Utils::Output::Mixin
Defined in:
github_runner_matrix.rb

Constant Summary collapse

NEWEST_HOMEBREW_CORE_MACOS_RUNNER =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

When bumping newest runner, run e.g. git log -p --reverse -G "sha256 tahoe" on homebrew/core and tag the first commit with a bottle e.g. git tag 15-sequoia f42c4a659e4da887fc714f8f41cc26794a4bb320 to allow people to jump to specific commits based on their macOS version.

:golden_gate
OLDEST_HOMEBREW_CORE_MACOS_RUNNER =
:sequoia

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils::Output::Mixin

#issue_reporting_message, #odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #opoo_outside_github_actions, #opoo_without_github_actions_annotation, #pretty_cannot_install, #pretty_deprecated, #pretty_disabled, #pretty_duration, #pretty_install_status, #pretty_installed, #pretty_uninstalled, #pretty_unmarked, #pretty_upgradable, #pretty_warning

Constructor Details

#initialize(testing_formulae, deleted_formulae, all_supported:, dependent_matrix:, dependent_shards: nil) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'github_runner_matrix.rb', line 36

def initialize(testing_formulae, deleted_formulae, all_supported:, dependent_matrix:, dependent_shards: nil)
  if all_supported && (testing_formulae.present? || deleted_formulae.present? || dependent_matrix)
    raise ArgumentError, "all_supported is mutually exclusive to other arguments"
  end

  @testing_formulae = testing_formulae
  @deleted_formulae = deleted_formulae
  @all_supported = all_supported
  @dependent_matrix = dependent_matrix
  @dependent_shards = T.let(dependent_shards || 1, Integer)
  @compatible_testing_formulae = T.let({}, T::Hash[GitHubRunner, T::Array[TestRunnerFormula]])
  @formulae_with_untested_dependents = T.let({}, T::Hash[GitHubRunner, T::Array[TestRunnerFormula]])

  # gracefully handle non-GitHub Actions environments
  @github_run_id = T.let(
    if ENV.key?("GITHUB_ACTIONS")
      ENV.fetch("GITHUB_RUN_ID")
    else
      ENV.fetch("GITHUB_RUN_ID", "")
    end, String
  )
  @linux_self_hosted = T.let(ENV.fetch("HOMEBREW_LINUX_SELF_HOSTED", "false") == "true", T::Boolean)
  @runner_timeout = T.let(
    if ENV.fetch("HOMEBREW_MACOS_LONG_TIMEOUT", "false") == "true"
      GITHUB_ACTIONS_LONG_TIMEOUT
    else
      GITHUB_ACTIONS_SHORT_TIMEOUT
    end, Integer
  )

  @runners = T.let([], T::Array[GitHubRunner])
  generate_runners!

  freeze
end

Instance Attribute Details

#runnersArray<GitHubRunner> (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



25
26
27
# File 'github_runner_matrix.rb', line 25

def runners
  @runners
end

Instance Method Details

#active_runner_specs_hashArray<RunnerSpecHash>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Array<RunnerSpecHash>)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'github_runner_matrix.rb', line 73

def active_runner_specs_hash
  specs = runners.select(&:active)
                 .map(&:spec)
                 .map(&:to_h)
  return specs if !@dependent_matrix || @dependent_shards == 1

  specs.flat_map do |spec|
    (1..@dependent_shards).map do |shard|
      spec.merge(
        name:                      "#{spec.fetch(:name)} shard #{shard}/#{@dependent_shards}",
        runner:                    spec.fetch(:runner).sub("-deps", "-deps#{shard}").to_s,
        formulae_dependents_shard: "#{shard}/#{@dependent_shards}",
      )
    end
  end
end

#generate_runners!void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'github_runner_matrix.rb', line 91

def generate_runners!
  return if @runners.present?

  if !@all_supported || @linux_self_hosted
    VALID_ARCHES.each do |arch|
      @runners << create_runner(:linux, arch, linux_runner_spec(arch, self_hosted: @linux_self_hosted))
    end
  end

  # Portable Ruby logic
  if @testing_formulae.any? { |tf| tf.name.start_with?("portable-") }
    x86_64_spec = MacOSRunnerSpec.new(
      name:         "macOS 11-cross x86_64",
      runner:       "macos-15-intel",
      timeout:      GITHUB_ACTIONS_RUNNER_TIMEOUT,
      cleanup:      true,
      target_macos: "11.7.10",
    )
    x86_64_macos_version = MacOSVersion.new("11")
    @runners << create_runner(:macos, :x86_64, x86_64_spec, x86_64_macos_version)

    # odisabled: remove support for Big Sur September (or later) 2027
    arm64_spec = MacOSRunnerSpec.new(
      name:    "macOS 11-cross arm64",
      runner:  "11-arm64-cross-#{@github_run_id}",
      timeout: GITHUB_ACTIONS_LONG_TIMEOUT,
      cleanup: true,
    )
    arm64_macos_version = MacOSVersion.new("11")
    @runners << create_runner(:macos, :arm64, arm64_spec, arm64_macos_version)
    return
  end

  # Use GitHub Actions macOS Runner for testing dependents if compatible with timeout.
  use_github_runner = ENV.fetch("HOMEBREW_MACOS_BUILD_ON_GITHUB_RUNNER", "false") == "true"
  use_github_runner ||= @dependent_matrix
  use_github_runner &&= @runner_timeout <= GITHUB_ACTIONS_RUNNER_TIMEOUT

  MacOSVersion::SYMBOLS.each_value do |version|
    macos_version = MacOSVersion.new(version)
    next unless runner_enabled?(macos_version)

    github_runner_available = macos_version.between?(OLDEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER,
                                                     NEWEST_GITHUB_ACTIONS_ARM_MACOS_RUNNER)

    runner, timeout = if use_github_runner && github_runner_available
      ["macos-#{version}", GITHUB_ACTIONS_RUNNER_TIMEOUT]
    elsif macos_version >= :monterey
      ["#{version}-arm64#{ephemeral_suffix}", @runner_timeout]
    else
      ["#{version}-arm64", @runner_timeout]
    end

    # Testing recursive dependents takes longer, so give those jobs two hours.
    timeout *= 2 if @dependent_matrix && timeout < GITHUB_ACTIONS_RUNNER_TIMEOUT
    spec = MacOSRunnerSpec.new(
      name:    "macOS #{version}-arm64",
      runner:,
      timeout:,
      cleanup: !runner.end_with?(ephemeral_suffix),
    )
    @runners << create_runner(:macos, :arm64, spec, macos_version)
  end

  @runners.freeze
end