From 1a16ef8a51ae4ceb06f7ae4355ebeb225223ca17 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 6 Jan 2021 08:25:44 +0100 Subject: [PATCH] Select macOS runners randomly. --- .github/workflows/ci.yml | 7 +++-- cmd/lib/changed_files.rb | 12 ++++----- cmd/lib/ci_matrix.rb | 52 ++++++++++++++++++++++++++++---------- cmd/lib/generate-matrix.rb | 25 +++++++++++++----- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 965b1f26cf..a38165fc63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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. diff --git a/cmd/lib/changed_files.rb b/cmd/lib/changed_files.rb index e30157a98a..8b04c02c96 100644 --- a/cmd/lib/changed_files.rb +++ b/cmd/lib/changed_files.rb @@ -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, diff --git a/cmd/lib/ci_matrix.rb b/cmd/lib/ci_matrix.rb index 8645e881e3..14e0bb6153 100644 --- a/cmd/lib/ci_matrix.rb +++ b/cmd/lib/ci_matrix.rb @@ -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 diff --git a/cmd/lib/generate-matrix.rb b/cmd/lib/generate-matrix.rb index da17876aa3..5f5109cd9e 100755 --- a/cmd/lib/generate-matrix.rb +++ b/cmd/lib/generate-matrix.rb @@ -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)}"