Select macOS runners randomly.

This commit is contained in:
Markus Reiter
2021-01-06 11:12:22 +01:00
parent f8804200f2
commit 1a16ef8a51
4 changed files with 67 additions and 29 deletions
+3 -4
View File
@@ -33,7 +33,7 @@ jobs:
test:
name: ${{ matrix.name }}
needs: generate-matrix
runs-on: macos-11.0
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
@@ -77,11 +77,10 @@ jobs:
echo '::warning::Removing `conda` symlink is no longer necessary.'
fi
if brew tap-info adoptopenjdk/openjdk; then
brew untap adoptopenjdk/openjdk
else
if ! brew untap adoptopenjdk/openjdk; then
echo '::warning::Untapping adoptopenjdk/openjdk is no longer necessary.'
fi
if: runner.os == 'macOS'
# Workaround until the `cache` action uses the changes from
# https://github.com/actions/toolkit/pull/580.
+6 -6
View File
@@ -1,23 +1,23 @@
# frozen_string_literal: true
module ChangedFiles
def self.collect(tap)
commit_range_start = system_command!("git", args: ["rev-parse", "origin/master"]).stdout.chomp
commit_range_end = system_command!("git", args: ["rev-parse", "HEAD"]).stdout.chomp
def changed_files
commit_range_start = system_command!("git", args: ["rev-parse", "origin"], chdir: path).stdout.chomp
commit_range_end = system_command!("git", args: ["rev-parse", "HEAD"], chdir: path).stdout.chomp
commit_range = "#{commit_range_start}...#{commit_range_end}"
modified_files = system_command!(
"git", args: ["diff", "--name-only", "--diff-filter=AMR", commit_range]
"git", args: ["diff", "--name-only", "--diff-filter=AMR", commit_range], chdir: path
).stdout.split("\n").map { |path| Pathname(path) }
added_files = system_command!(
"git", args: ["diff", "--name-only", "--diff-filter=A", commit_range]
"git", args: ["diff", "--name-only", "--diff-filter=A", commit_range], chdir: path
).stdout.split("\n").map { |path| Pathname(path) }
modified_ruby_files = modified_files.select { |path| path.extname == ".rb" }
modified_command_files = modified_files.select { |path| path.ascend.to_a.last.to_s == "cmd" }
modified_github_actions_files = modified_files.select { |path| path.to_s.start_with?(".github/actions/") }
modified_cask_files = modified_files.select { |path| tap.cask_file?(path) }
modified_cask_files = modified_files.select { |path| cask_file?(path) }
{
modified_files: modified_files,
+39 -13
View File
@@ -7,10 +7,33 @@ require_relative "changed_files"
module CiMatrix
MAX_JOBS = 256
RUNNERS = {
"macos-10.15" => 0.9,
"macos-11.0" => 0.1,
}.freeze
def self.random_runner
@random_runner ||= RUNNERS.max_by { |(_, weight)| rand ** (1.0 / weight) }.first
end
def self.runners(path)
cask_content = path.read
if cask_content.match?(/\bMacOS\s*\.version\b/m)
# If the cask depends on `MacOS.version`, test it on every possible macOS version.
RUNNERS.keys
else
# Otherwise, select a runner based on weighted random sample.
[random_runner]
end
end
def self.generate(tap, labels: [])
odie "This command must be run from inside a tap directory." unless tap
changed_files = ChangedFiles.collect(tap)
tap.extend(ChangedFiles)
changed_files = tap.changed_files
ruby_files_in_wrong_directory =
changed_files[:modified_ruby_files] - (
@@ -32,8 +55,8 @@ module CiMatrix
jobs = modified_cask_files.count
odie "Maximum job matrix size exceeded: #{jobs}/#{MAX_JOBS}" if jobs > MAX_JOBS
changed_files[:modified_cask_files].map do |path|
cask = Cask::CaskLoader.load(path)
changed_files[:modified_cask_files].flat_map do |path|
cask_token = path.basename(".rb")
appcast_arg = if labels.include?("ci-skip-appcast")
"--no-appcast"
@@ -45,16 +68,19 @@ module CiMatrix
audit_args << "--new-cask" if changed_files[:added_files].include?(path)
{
name: "test (#{cask.token})",
tap: tap.name,
cask: {
token: cask.token,
path: "./#{path}",
},
audit_args: audit_args,
skip_install: labels.include?("ci-skip-install"),
}
runners(path).map do |runner|
{
name: "test #{cask_token} (#{runner})",
tap: tap.name,
cask: {
token: cask_token,
path: "./#{path}",
},
audit_args: audit_args,
skip_install: labels.include?("ci-skip-install"),
runner: runner,
}
end
end
end
end
+19 -6
View File
@@ -7,14 +7,20 @@ require_relative "ci_matrix"
pr_url, = ARGV
pr = GitHub.open_api(pr_url)
labels = pr.fetch("labels").map { |l| l.fetch("name") }
labels = if pr_url
pr = GitHub.open_api(pr_url)
pr.fetch("labels").map { |l| l.fetch("name") }
else
[]
end
tap = Tap.from_path(Dir.pwd)
runner = CiMatrix.random_runner
syntax_job = {
name: "syntax",
tap: tap.name,
name: "syntax",
tap: tap.name,
runner: runner,
}
matrix = [syntax_job]
@@ -22,11 +28,18 @@ matrix = [syntax_job]
unless labels.include?("ci-syntax-only")
cask_jobs = CiMatrix.generate(tap, labels: labels)
# If casks were changed, skip `audit` for all others.
syntax_job[:skip_audit] = true if cask_jobs.any?
if cask_jobs.any?
# If casks were changed, skip `audit` for whole tap.
syntax_job[:skip_audit] = true
# The syntax job only runs `style` at this point, which should work on Linux.
syntax_job[:runner] = "ubuntu-latest"
end
matrix += cask_jobs
end
syntax_job[:name] += " (#{syntax_job[:runner]})"
puts JSON.pretty_generate(matrix)
puts "::set-output name=matrix::#{JSON.generate(matrix)}"