From b854d5ffe7ee94c9e39a028d81e8c063ac5f4c38 Mon Sep 17 00:00:00 2001 From: Patrick Linnane Date: Fri, 5 Jun 2026 13:30:31 -0700 Subject: [PATCH] generate-cask-ci-matrix: respect `maximum_macos` requirement Signed-off-by: Patrick Linnane --- .../dev-cmd/generate-cask-ci-matrix.rb | 27 ++++--- .../dev-cmd/generate-cask-ci-matrix_spec.rb | 81 +++++++++++++++++++ 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb b/Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb index 902206ac82..39cd04c38b 100644 --- a/Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb +++ b/Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb @@ -129,22 +129,25 @@ module Homebrew def filter_runners(cask) filtered_runners = T.let({}, T::Hash[T::Hash[Symbol, T.any(Symbol, String)], Float]) if cask.supports_macos? - filtered_macos_runners = RUNNERS.select do |runner, _| - runner[:symbol] != :linux && - cask.depends_on.macos.present? && - cask.depends_on.macos.allows?(MacOSVersion.from_symbol(runner.fetch(:symbol).to_sym)) - end + # Skip macOS if no runner satisfies the cask's min/max macOS requirements. + macos_requirements = [cask.depends_on.macos, cask.depends_on.maximum_macos] + .compact.select(&:version_specified?) - filtered_runners = if filtered_macos_runners.any? - filtered_macos_runners - else + filtered_runners = if macos_requirements.empty? MACOS_RUNNERS.dup + else + MACOS_RUNNERS.select do |runner, _| + macos_version = MacOSVersion.from_symbol(runner.fetch(:symbol).to_sym) + macos_requirements.all? { |requirement| requirement.allows?(macos_version) } + end end - end - macos_archs = architectures(cask:, os: :macos) - filtered_runners.select! do |runner, _| - macos_archs.include?(runner.fetch(:arch)) + if filtered_runners.any? + macos_archs = architectures(cask:, os: :macos) + filtered_runners.select! do |runner, _| + macos_archs.include?(runner.fetch(:arch)) + end + end end return filtered_runners unless cask.supports_linux? diff --git a/Library/Homebrew/test/dev-cmd/generate-cask-ci-matrix_spec.rb b/Library/Homebrew/test/dev-cmd/generate-cask-ci-matrix_spec.rb index 5dc3587aa1..7708630085 100644 --- a/Library/Homebrew/test/dev-cmd/generate-cask-ci-matrix_spec.rb +++ b/Library/Homebrew/test/dev-cmd/generate-cask-ci-matrix_spec.rb @@ -131,6 +131,63 @@ RSpec.describe Homebrew::DevCmd::GenerateCaskCiMatrix do app "Test.app" end end + let(:c_minimum_macos) do + Cask::Cask.new("test-minimum-macos") do + version "0.0.1,2" + + url "https://brew.sh/test-0.0.1.dmg" + name "Test" + desc "Test cask" + homepage "https://brew.sh" + + depends_on macos: :sequoia + + app "Test.app" + end + end + let(:c_maximum_macos) do + Cask::Cask.new("test-maximum-macos") do + version "0.0.1,2" + + url "https://brew.sh/test-0.0.1.dmg" + name "Test" + desc "Test cask" + homepage "https://brew.sh" + + depends_on maximum_macos: :sonoma + + app "Test.app" + end + end + let(:c_maximum_macos_below_all_runners) do + Cask::Cask.new("test-maximum-macos-below-all-runners") do + version "0.0.1,2" + + url "https://brew.sh/test-0.0.1.dmg" + name "Test" + desc "Test cask" + homepage "https://brew.sh" + + depends_on maximum_macos: :ventura + + app "Test.app" + end + end + let(:c_minimum_and_maximum_macos) do + Cask::Cask.new("test-minimum-and-maximum-macos") do + version "0.0.1,2" + + url "https://brew.sh/test-0.0.1.dmg" + name "Test" + desc "Test cask" + homepage "https://brew.sh" + + depends_on macos: :sonoma + depends_on maximum_macos: :sequoia + + app "Test.app" + end + end let(:c_linux) do Cask::Cask.new("test-linux") do version "0.0.1,2" @@ -218,6 +275,30 @@ RSpec.describe Homebrew::DevCmd::GenerateCaskCiMatrix do end end + context "when cask has a macOS version requirement" do + it "filters macOS runners by the minimum and maximum macOS requirements" do + expect(generate_matrix.filter_runners(c_minimum_macos)) + .to eq({ + { arch: :arm, name: "macos-15", symbol: :sequoia } => 0.0, + { arch: :arm, name: "macos-26", symbol: :tahoe } => 1.0, + { arch: :intel, name: "macos-15-intel", symbol: :sequoia } => 1.0, + }) + + expect(generate_matrix.filter_runners(c_maximum_macos)) + .to eq({ { arch: :arm, name: "macos-14", symbol: :sonoma } => 0.0 }) + + expect(generate_matrix.filter_runners(c_minimum_and_maximum_macos)) + .to eq({ + { arch: :arm, name: "macos-14", symbol: :sonoma } => 0.0, + { arch: :arm, name: "macos-15", symbol: :sequoia } => 0.0, + { arch: :intel, name: "macos-15-intel", symbol: :sequoia } => 1.0, + }) + + # A requirement excluding all runners must skip macOS, not test them all. + expect(generate_matrix.filter_runners(c_maximum_macos_below_all_runners)).to eq({}) + end + end + context "when cask only supports Linux" do it "returns an array including all Linux" do expect(generate_matrix.filter_runners(c_linux))