From 3bb91601fbde74c3926147b319c55e02e110a564 Mon Sep 17 00:00:00 2001 From: Nanda H Krishna Date: Mon, 15 Jul 2024 11:39:22 -0400 Subject: [PATCH] Ensure early installation of `gh` for attestations --- Library/Homebrew/attestation.rb | 27 ++++++++++++++++++++++++--- Library/Homebrew/cmd/install.rb | 8 ++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/attestation.rb b/Library/Homebrew/attestation.rb index 0ab000e583..acf1c5c20a 100644 --- a/Library/Homebrew/attestation.rb +++ b/Library/Homebrew/attestation.rb @@ -57,6 +57,16 @@ module Homebrew Homebrew::EnvConfig.developer? || Homebrew::EnvConfig.devcmdrun? end + # Ensures the availability of a suitable `gh` executable for attestation verification. + # + # @api private + sig { returns(Pathname) } + def self.ensure_gh_installed! + return @gh_executable if @gh_executable.present? + + gh_executable + end + # Returns a path to a suitable `gh` executable for attestation verification. # # @api private @@ -65,9 +75,20 @@ module Homebrew # NOTE: We set HOMEBREW_NO_VERIFY_ATTESTATIONS when installing `gh` itself, # to prevent a cycle during bootstrapping. This can eventually be resolved # by vendoring a pure-Ruby Sigstore verifier client. - @gh_executable ||= T.let(with_env(HOMEBREW_NO_VERIFY_ATTESTATIONS: "1") do - ensure_executable!("gh") - end, T.nilable(Pathname)) + return @gh_executable if @gh_executable.present? + + with_env(HOMEBREW_NO_VERIFY_ATTESTATIONS: "1") do + @gh_executable = ensure_executable!("gh") + + gh_version = Version.new(system_command!(@gh_executable, args: ["--version"], print_stderr: false) + .stdout.match(/\d+(?:\.\d+)+/i).to_s) + if gh_version < GH_ATTESTATION_MIN_VERSION + @gh_executable = ensure_formula_installed!("gh", latest: true, + reason: "verifying attestations").opt_bin/"gh" + end + end + + @gh_executable end # Verifies the given bottle against a cryptographic attestation of build provenance. diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 763a933606..372326c74f 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -263,6 +263,14 @@ module Homebrew end end + if Homebrew::Attestation.enabled? + if formulae.include?(Formula["gh"]) + formulae.unshift(formulae.delete(Formula["gh"])) + else + Homebrew::Attestation.ensure_gh_installed! + end + end + # if the user's flags will prevent bottle only-installations when no # developer tools are available, we need to stop them early on build_flags = []