From 044713f3a2c7a838788e2a6f88eef792fe00b91d Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Fri, 3 Dec 2021 22:59:31 +0000 Subject: [PATCH] workflows/dispatch-rebottle: dynamic runner selection (#89984) --- .github/workflows/dispatch-rebottle.yml | 62 ++++++++++++------- cmd/determine-rebottle-runners.rb | 81 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 23 deletions(-) create mode 100755 cmd/determine-rebottle-runners.rb diff --git a/.github/workflows/dispatch-rebottle.yml b/.github/workflows/dispatch-rebottle.yml index f46b6ddc671..b16e8da0562 100644 --- a/.github/workflows/dispatch-rebottle.yml +++ b/.github/workflows/dispatch-rebottle.yml @@ -1,4 +1,4 @@ -name: Dispatch rebottle (for all macOS versions) +name: Dispatch rebottle (for all currently bottled OS versions) on: workflow_dispatch: @@ -17,7 +17,7 @@ on: description: "Whether to upload built bottles or not (default: false)" required: false fail-fast: - description: "Whether to fail immediately on a single macOS version failure (default: true)" + description: "Whether to fail immediately on a single OS version failure (default: true)" default: "true" required: false @@ -29,27 +29,51 @@ env: HOMEBREW_RELOCATE_RPATHS: 1 jobs: + setup: + runs-on: ubuntu-latest + container: + image: ghcr.io/homebrew/ubuntu16.04:master + outputs: + runners: ${{steps.determine-runners.outputs.runners}} + steps: + - name: Set up Homebrew + id: set-up-homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Determine runners + id: determine-runners + run: brew determine-rebottle-runners "${{github.event.inputs.formula}}" "${{github.event.inputs.timeout}}" + bottle: + needs: setup strategy: matrix: - version: ["12-arm64", "12", "11-arm64", "11", "10.15"] + include: ${{fromJson(needs.setup.outputs.runners)}} fail-fast: ${{fromJson(github.event.inputs.fail-fast)}} - runs-on: ${{ matrix.version }} + runs-on: ${{matrix.runner}} + container: ${{matrix.container}} timeout-minutes: ${{fromJson(github.event.inputs.timeout)}} + defaults: + run: + working-directory: ${{matrix.workdir || github.workspace}} env: - PATH: "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" - GITHUB_ACTIONS_HOMEBREW_MACOS_SELF_HOSTED: 1 GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 1 steps: - name: ${{github.event.inputs.formula}} id: print_details run: | echo sender=${{github.event.sender.login}} echo formula=${{github.event.inputs.formula}} + echo timeout=${{github.event.inputs.timeout}} echo issue=${{github.event.inputs.issue}} echo upload=${{github.event.inputs.upload}} + - name: Set environment variables + if: runner.os == 'macOS' + run: | + echo 'PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin' >> $GITHUB_ENV + echo 'GITHUB_ACTIONS_HOMEBREW_MACOS_SELF_HOSTED=1' >> $GITHUB_ENV + - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master @@ -84,13 +108,14 @@ jobs: uses: actions/upload-artifact@main with: name: logs - path: bottles/logs + path: ${{matrix.workdir || github.workspace}}/bottles/logs - name: Delete logs and home if: always() run: | rm -rvf bottles/logs rm -rvf bottles/home + rm -rvf bottles/failed - name: Count bottles id: bottles @@ -106,14 +131,13 @@ jobs: uses: actions/upload-artifact@main with: name: bottles - path: bottles + path: ${{matrix.workdir || github.workspace}}/bottles - - run: brew test-bot --only-cleanup-after + - name: Post cleanup if: always() - - - name: Post Cleanup - if: always() - run: rm -rvf bottles + run: | + brew test-bot --only-cleanup-after + rm -rvf bottles - name: Post comment on failure if: ${{!success() && github.event.inputs.issue > 0}} @@ -124,6 +148,7 @@ jobs: body: ":x: @${{github.actor}} bottle request for ${{github.event.inputs.formula}} [failed](${{github.event.repository.html_url}}/actions/runs/${{github.run_id}})." bot_body: ":x: Bottle request for ${{github.event.inputs.formula}} [failed](${{github.event.repository.html_url}}/actions/runs/${{github.run_id}})." bot: BrewTestBot + upload: runs-on: ubuntu-latest needs: bottle @@ -131,15 +156,6 @@ jobs: env: HOMEBREW_SIMULATE_MACOS_ON_LINUX: 1 steps: - - name: ${{github.event.inputs.formula}} - id: print_details - run: | - echo sender=${{github.event.sender.login}} - echo formula=${{github.event.inputs.formula}} - echo version=${{github.event.inputs.macos}} - echo issue=${{github.event.inputs.issue}} - echo upload=${{github.event.inputs.upload}} - - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@master diff --git a/cmd/determine-rebottle-runners.rb b/cmd/determine-rebottle-runners.rb new file mode 100755 index 00000000000..23acac7454c --- /dev/null +++ b/cmd/determine-rebottle-runners.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require "cli/parser" +require "formula" + +module Homebrew + module_function + + def determine_rebottle_runners_args + Homebrew::CLI::Parser.new do + usage_banner <<~EOS + `determine-rebottle-runners` + + Determines the runners to use to rebottle a formula. + EOS + + named_args number: 2 + + hide_from_man_page! + end + end + + def determine_rebottle_runners + args = determine_rebottle_runners_args.parse + + formula = Formula[args.named.first] + timeout = args.named.second.to_i + + linux_runner = if timeout > 360 + "linux-self-hosted-1" + else + "ubuntu-latest" + end + linux_runner_spec = { + runner: linux_runner, + container: { + image: "ghcr.io/homebrew/ubuntu16.04:master", + options: "--user=linuxbrew", + }, + workdir: "/github/home", + } + + tags = formula.bottle_specification.collector.tags + runners = if tags.count == 1 && tags.first.system == :all + # Build on all supported macOS versions and Linux. + MacOS::Version::SYMBOLS.values.flat_map do |version| + macos_version = MacOS::Version.new(version) + if macos_version.outdated_release? || macos_version.prerelease? + nil + else + macos_runners = [{ runner: macos_version.to_s }] + macos_runners << { runner: "#{macos_version}-arm64" } if macos_version >= :big_sur + macos_runners + end + end << linux_runner_spec + else + tags.map do |tag| + macos_version = tag.to_macos_version + + if macos_version.outdated_release? + nil # Don't rebottle for older macOS versions (no CI to build them). + else + runner = macos_version.to_s + runner += "-#{tag.arch}" unless tag.arch == :x86_64 + { runner: runner } + end + rescue MacOSVersionError + if tag.system == :linux && tag.arch == :x86_64 + linux_runner_spec + elsif tag.system == :all + # An all bottle with OS-specific bottles also present - ignore it. + nil + else + raise "Unknown tag: #{tag}" + end + end + end.compact + + puts "::set-output name=runners::#{runners.to_json}" + end +end