Link to Support Tiers in diagnostic/error messages

Now that we have this nice URL let's reference it to allow our other
messages to be a bit shorter/kinder.
This commit is contained in:
Mike McQuaid 2025-03-31 09:53:19 +01:00
parent 3f7c0854a3
commit d899f00c4b
No known key found for this signature in database
13 changed files with 125 additions and 56 deletions

View File

@ -18,6 +18,7 @@ defaults:
shell: bash -xeuo pipefail {0} shell: bash -xeuo pipefail {0}
env: env:
# odeprecated: remove 18.04 image in Homebrew >=4.5
VERSIONS: '["18.04", "20.04", "22.04", "24.04"]' VERSIONS: '["18.04", "20.04", "22.04", "24.04"]'
jobs: jobs:
@ -145,9 +146,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
# odeprecated: remove 18.04 image in Homebrew >=4.5
version: ["18.04", "20.04", "22.04", "24.04"] version: ["18.04", "20.04", "22.04", "24.04"]
arch: ["x86_64", "arm64"] arch: ["x86_64", "arm64"]
exclude: exclude:
# odeprecated: move this to 20.04 in Homebrew >=4.5 and remove 18.04 image
- version: "18.04" - version: "18.04"
arch: "arm64" arch: "arm64"
- arch: ${{ github.event_name == 'release' && 'arm64' }} - arch: ${{ github.event_name == 'release' && 'arm64' }}
@ -172,9 +175,9 @@ jobs:
VERSION: ${{ matrix.version }} VERSION: ${{ matrix.version }}
PUSH: ${{ needs.generate-tags.outputs.push }} PUSH: ${{ needs.generate-tags.outputs.push }}
run: | run: |
# odeprecated: move this to 20.04 in Homebrew >=4.5 and remove 18.04 image
if [[ "${VERSION}" == "18.04" ]]; then if [[ "${VERSION}" == "18.04" ]]; then
# odeprecated: remove this in Homebrew >=4.5 echo "The homebrew/ubuntu18.04 image is deprecated and will soon be retired. Use homebrew/ubuntu22.04 or homebrew/ubuntu24.04 or homebrew/brew." > .docker-deprecate
echo "The homebrew/ubuntu18.04 image is deprecated and will soon be retired. Use homebrew/ubuntu22.04 or homebrew/ubuntu24.04 or homebrew/ubuntu20.04 or homebrew/brew." > .docker-deprecate
fi fi
filter="$(printf '.["%s"]' "${VERSION}")" filter="$(printf '.["%s"]' "${VERSION}")"
@ -197,10 +200,22 @@ jobs:
build-args: version=${{ matrix.version }} build-args: version=${{ matrix.version }}
labels: ${{ needs.generate-tags.outputs.labels }} labels: ${{ needs.generate-tags.outputs.labels }}
- name: Run brew test-bot --only-setup - name: Set environment variables
run: docker run --env HOMEBREW_ARM64_TESTING --rm brew brew test-bot --only-setup run: |
if [[ "${ARCH}" == "arm64" ]]; then
echo "HOMEBREW_ARM64_TESTING=1" >> "$GITHUB_ENV"
fi
# odeprecated: remove 18.04 in Homebrew >=4.5
if [[ "${VERSION}" == "18.04" || "${VERSION}" == "20.04" ]]; then
echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
fi
env: env:
HOMEBREW_ARM64_TESTING: 1 VERSION: ${{ matrix.version }}
ARCH: ${{ matrix.arch }}
- name: Run brew test-bot --only-setup
run: docker run --env HOMEBREW_ARM64_TESTING --env HOMEBREW_GLIBC_TESTING --rm brew brew test-bot --only-setup
- name: Log in to GitHub Packages (BrewTestBot) - name: Log in to GitHub Packages (BrewTestBot)
if: fromJSON(steps.attributes.outputs.push) if: fromJSON(steps.attributes.outputs.push)
@ -286,6 +301,7 @@ jobs:
done <<<"$(jq --raw-output "${filter}" <<<"${TAGS}")" done <<<"$(jq --raw-output "${filter}" <<<"${TAGS}")"
image_args=("ghcr.io/homebrew/ubuntu${VERSION}@sha256:$(<"${RUNNER_TEMP}/digests/${VERSION}-x86_64")") image_args=("ghcr.io/homebrew/ubuntu${VERSION}@sha256:$(<"${RUNNER_TEMP}/digests/${VERSION}-x86_64")")
# odeprecated: move this to 20.04 in Homebrew >=4.5 and remove 18.04 image
if [[ "${VERSION}" != 18.04 ]]; then if [[ "${VERSION}" != 18.04 ]]; then
image_args+=("ghcr.io/homebrew/ubuntu${VERSION}@sha256:$(<"${RUNNER_TEMP}/digests/${VERSION}-arm64")") image_args+=("ghcr.io/homebrew/ubuntu${VERSION}@sha256:$(<"${RUNNER_TEMP}/digests/${VERSION}-arm64")")
fi fi

View File

@ -388,6 +388,10 @@ jobs:
- run: brew test-bot --only-cleanup-before - run: brew test-bot --only-cleanup-before
- name: Setup environment variables
if: matrix.container == 'ghcr.io/homebrew/ubuntu20.04:latest'
run: echo "HOMEBREW_GLIBC_TESTING=1" >> "$GITHUB_ENV"
- run: brew test-bot --only-setup - run: brew test-bot --only-setup
- run: brew install gnu-tar - run: brew install gnu-tar

View File

@ -66,7 +66,7 @@ module Homebrew
return false if Homebrew::EnvConfig.no_verify_attestations? return false if Homebrew::EnvConfig.no_verify_attestations?
return true if Homebrew::EnvConfig.verify_attestations? return true if Homebrew::EnvConfig.verify_attestations?
return false if ENV.fetch("CI", false) return false if ENV.fetch("CI", false)
return false if OS.unsupported_configuration? return false if OS.not_tier_one_configuration?
# Always check credentials last to avoid unnecessary credential extraction. # Always check credentials last to avoid unnecessary credential extraction.
(Homebrew::EnvConfig.developer? || Homebrew::EnvConfig.devcmdrun?) && GitHub::API.credentials.present? (Homebrew::EnvConfig.developer? || Homebrew::EnvConfig.devcmdrun?) && GitHub::API.credentials.present?

View File

@ -169,8 +169,13 @@ rescue BuildError => e
Utils::Analytics.report_build_error(e) Utils::Analytics.report_build_error(e)
e.dump(verbose: args&.verbose? || false) e.dump(verbose: args&.verbose? || false)
if OS.unsupported_configuration? if OS.not_tier_one_configuration?
$stderr.puts "#{Tty.bold}Do not report this issue: you are running in an unsupported configuration.#{Tty.reset}" $stderr.puts <<~EOS
This build failure was expected, as this is not a Tier 1 configuration:
#{Formatter.url("https://docs.brew.sh/Support-Tiers")}
#{Formatter.bold("Do not report any issues to Homebrew/* repositories!")}
Read the above document instead before opening any issues or PRs.
EOS
elsif e.formula.head? || e.formula.deprecated? || e.formula.disabled? elsif e.formula.head? || e.formula.deprecated? || e.formula.disabled?
reason = if e.formula.head? reason = if e.formula.head?
"was built from an unstable upstream --HEAD" "was built from an unstable upstream --HEAD"
@ -182,14 +187,7 @@ rescue BuildError => e
$stderr.puts <<~EOS $stderr.puts <<~EOS
#{e.formula.name}'s formula #{reason}. #{e.formula.name}'s formula #{reason}.
This build failure is expected behaviour. This build failure is expected behaviour.
Do not create issues about this on Homebrew's GitHub repositories.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help in Homebrew's discussions but are unlikely to receive a response.
Try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.
EOS EOS
end end
exit 1 exit 1
@ -211,15 +209,20 @@ rescue Exception => e # rubocop:disable Lint/RescueException
require "utils/backtrace" require "utils/backtrace"
$stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") || !method_deprecated_error $stderr.puts Utils::Backtrace.clean(e) if args&.debug? || ARGV.include?("--debug") || !method_deprecated_error
if OS.unsupported_configuration? if OS.not_tier_one_configuration?
$stderr.puts "#{Tty.bold}Do not report this issue: you are running in an unsupported configuration.#{Tty.reset}" $stderr.puts <<~EOS
This error was expected, as this is not a Tier 1 configuration:
#{Formatter.url("https://docs.brew.sh/Support-Tiers")}
#{Formatter.bold("Do not report any issues to Homebrew/* repositories!")}
Read the above document instead before opening any issues or PRs.
EOS
elsif Homebrew::EnvConfig.no_auto_update? && elsif Homebrew::EnvConfig.no_auto_update? &&
(fetch_head = HOMEBREW_REPOSITORY/".git/FETCH_HEAD") && (fetch_head = HOMEBREW_REPOSITORY/".git/FETCH_HEAD") &&
(!fetch_head.exist? || (fetch_head.mtime.to_date < Date.today)) (!fetch_head.exist? || (fetch_head.mtime.to_date < Date.today))
$stderr.puts "#{Tty.bold}You have disabled automatic updates and have not updated today.#{Tty.reset}" $stderr.puts "#{Tty.bold}You have disabled automatic updates and have not updated today.#{Tty.reset}"
$stderr.puts "#{Tty.bold}Do not report this issue until you've run `brew update` and tried again.#{Tty.reset}" $stderr.puts "#{Tty.bold}Do not report this issue until you've run `brew update` and tried again.#{Tty.reset}"
elsif (issues_url = (method_deprecated_error && e.issues_url) || Utils::Backtrace.tap_error_url(e)) elsif (issues_url = (method_deprecated_error && e.issues_url) || Utils::Backtrace.tap_error_url(e))
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core):" $stderr.puts "If reporting this issue please do so at (not Homebrew/* repositories):"
$stderr.puts " #{Formatter.url(issues_url)}" $stderr.puts " #{Formatter.url(issues_url)}"
elsif internal_cmd elsif internal_cmd
$stderr.puts "#{Tty.bold}Please report this issue:#{Tty.reset}" $stderr.puts "#{Tty.bold}Please report this issue:#{Tty.reset}"

View File

@ -111,17 +111,21 @@ module Homebrew
supported_configuration_checks + build_from_source_checks supported_configuration_checks + build_from_source_checks
end end
def please_create_pull_requests(what = "unsupported configuration") sig { params(tier: T.any(Integer, String, Symbol)).returns(T.nilable(String)) }
def support_tier_message(tier:)
return if tier.to_s == "1"
tier_title, tier_slug = if tier.to_s == "unsupported"
["Unsupported", "unsupported"]
else
["Tier #{tier}", "tier-#{tier.to_s.downcase}"]
end
<<~EOS <<~EOS
It is expected behaviour that some formulae will fail to build in this #{what}. This is a #{tier_title} configuration:
It is expected behaviour that Homebrew will be buggy and slow. #{Formatter.url("https://docs.brew.sh/Support-Tiers##{tier_slug}")}
Do not create any issues about this on Homebrew's GitHub repositories. #{Formatter.bold("Do not report any issues to Homebrew/* repositories!")}
Do not create any issues even if you think this message is unrelated. Read the above document instead before opening any issues or PRs.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help in Homebrew's discussions but are unlikely to receive a response.
Try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.
EOS EOS
end end
@ -834,9 +838,10 @@ module Homebrew
<<~EOS <<~EOS
Your Homebrew's prefix is not #{Homebrew::DEFAULT_PREFIX}. Your Homebrew's prefix is not #{Homebrew::DEFAULT_PREFIX}.
Many of Homebrew's bottles (binary packages) can only be used with the default prefix. Most of Homebrew's bottles (binary packages) can only be used with the default prefix.
Consider uninstalling Homebrew and reinstalling into the default prefix. Consider uninstalling Homebrew and reinstalling into the default prefix.
#{please_create_pull_requests}
#{support_tier_message(tier: 3)}
EOS EOS
end end

View File

@ -521,23 +521,31 @@ class BuildError < RuntimeError
end end
end end
if formula.tap && !OS.unsupported_configuration? if formula.tap
if formula.tap.official? if OS.not_tier_one_configuration?
<<~EOS
This is not a Tier 1 configuration:
#{Formatter.url("https://docs.brew.sh/Support-Tiers")}
#{Formatter.bold("Do not report any issues to Homebrew/* repositories!")}
Read the above document instead before opening any issues or PRs.
EOS
elsif formula.tap.official?
puts Formatter.error(Formatter.url(OS::ISSUES_URL), label: "READ THIS") puts Formatter.error(Formatter.url(OS::ISSUES_URL), label: "READ THIS")
elsif (issues_url = formula.tap.issues_url) elsif (issues_url = formula.tap.issues_url)
puts <<~EOS puts <<~EOS
If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core): If reporting this issue please do so at (not Homebrew/* repositories):
#{Formatter.url(issues_url)} #{Formatter.url(issues_url)}
EOS EOS
else else
puts <<~EOS puts <<~EOS
If reporting this issue please do so to (not Homebrew/brew or Homebrew/homebrew-core): If reporting this issue please do so to (not Homebrew/* repositories):
#{formula.tap} #{formula.tap}
EOS EOS
end end
else else
puts <<~EOS <<~EOS
Do not report this issue to Homebrew/brew or Homebrew/homebrew-core! We cannot detect the correct tap to report this issue to.
Do not report this issue to Homebrew/* repositories!
EOS EOS
end end

View File

@ -171,7 +171,7 @@ module Kernel
tap = Tap.fetch(match[:user], match[:repository]) tap = Tap.fetch(match[:user], match[:repository])
tap_message = "\nPlease report this issue to the #{tap.full_name} tap" tap_message = "\nPlease report this issue to the #{tap.full_name} tap"
tap_message += " (not Homebrew/brew or Homebrew/homebrew-core)" unless tap.official? tap_message += " (not Homebrew/* repositories)" unless tap.official?
tap_message += ", or even better, submit a PR to fix it" if replacement tap_message += ", or even better, submit a PR to fix it" if replacement
tap_message << ":\n #{line.sub(/^(.*:\d+):.*$/, '\1')}\n\n" tap_message << ":\n #{line.sub(/^(.*:\d+):.*$/, '\1')}\n\n"
break break

View File

@ -80,7 +80,8 @@ module OS
<<~EOS <<~EOS
Your CPU architecture (#{Hardware::CPU.arch}) is not supported. We only support Your CPU architecture (#{Hardware::CPU.arch}) is not supported. We only support
x86_64 CPU architectures. You will be unable to use binary packages (bottles). x86_64 CPU architectures. You will be unable to use binary packages (bottles).
#{please_create_pull_requests}
#{support_tier_message(tier: 2)}
EOS EOS
end end
@ -90,10 +91,30 @@ module OS
<<~EOS <<~EOS
Your system glibc #{OS::Linux::Glibc.system_version} is too old. Your system glibc #{OS::Linux::Glibc.system_version} is too old.
We only support glibc #{OS::Linux::Glibc.minimum_version} or later. We only support glibc #{OS::Linux::Glibc.minimum_version} or later.
#{please_create_pull_requests}
We recommend updating to a newer version via your distribution's We recommend updating to a newer version via your distribution's
package manager, upgrading your distribution to the latest version, package manager, upgrading your distribution to the latest version,
or changing distributions. or changing distributions.
#{support_tier_message(tier: :unsupported)}
EOS
end
def check_glibc_version
return unless OS::Linux::Glibc.below_ci_version?
# We want to bypass this check in some tests.
return if ENV["HOMEBREW_GLIBC_TESTING"]
<<~EOS
Your system glibc #{OS::Linux::Glibc.system_version} is too old.
We will need to automatically install a newer version.
We recommend updating to a newer version via your distribution's
package manager, upgrading your distribution to the latest version,
or changing distributions.
#{support_tier_message(tier: 2)}
EOS EOS
end end
@ -104,10 +125,12 @@ module OS
Your Linux kernel #{OS.kernel_version} is too old. Your Linux kernel #{OS.kernel_version} is too old.
We only support kernel #{OS::Linux::Kernel.minimum_version} or later. We only support kernel #{OS::Linux::Kernel.minimum_version} or later.
You will be unable to use binary packages (bottles). You will be unable to use binary packages (bottles).
#{please_create_pull_requests}
We recommend updating to a newer version via your distribution's We recommend updating to a newer version via your distribution's
package manager, upgrading your distribution to the latest version, package manager, upgrading your distribution to the latest version,
or changing distributions. or changing distributions.
#{support_tier_message(tier: 3)}
EOS EOS
end end

View File

@ -110,10 +110,12 @@ module OS
return if Homebrew::EnvConfig.developer? return if Homebrew::EnvConfig.developer?
return if ENV["HOMEBREW_INTEGRATION_TEST"] return if ENV["HOMEBREW_INTEGRATION_TEST"]
tier = 2
who = +"We" who = +"We"
what = if OS::Mac.version.prerelease? what = if OS::Mac.version.prerelease?
"pre-release version" "pre-release version"
elsif OS::Mac.version.outdated_release? elsif OS::Mac.version.outdated_release?
tier = 3
who << " (and Apple)" who << " (and Apple)"
"old version" "old version"
end end
@ -124,7 +126,8 @@ module OS
<<~EOS <<~EOS
You are using macOS #{MacOS.version}. You are using macOS #{MacOS.version}.
#{who} do not provide support for this #{what}. #{who} do not provide support for this #{what}.
#{please_create_pull_requests(what)}
#{support_tier_message(tier:)}
EOS EOS
end end
@ -145,7 +148,8 @@ module OS
<<~EOS <<~EOS
You have booted macOS using OpenCore Legacy Patcher. You have booted macOS using OpenCore Legacy Patcher.
We do not provide support for this configuration. We do not provide support for this configuration.
#{please_create_pull_requests}
#{support_tier_message(tier: 2)}
EOS EOS
end end
@ -169,6 +173,8 @@ module OS
Your Xcode (#{MacOS::Xcode.version}) is outdated. Your Xcode (#{MacOS::Xcode.version}) is outdated.
Please update to Xcode #{MacOS::Xcode.latest_version} (or delete it). Please update to Xcode #{MacOS::Xcode.latest_version} (or delete it).
#{MacOS::Xcode.update_instructions} #{MacOS::Xcode.update_instructions}
#{support_tier_message(tier: 2)}
EOS EOS
if OS::Mac.version.prerelease? if OS::Mac.version.prerelease?
@ -198,6 +204,8 @@ module OS
<<~EOS <<~EOS
A newer Command Line Tools release is available. A newer Command Line Tools release is available.
#{MacOS::CLT.update_instructions} #{MacOS::CLT.update_instructions}
#{support_tier_message(tier: 2)}
EOS EOS
end end
@ -409,6 +417,8 @@ module OS
You should set the "HOMEBREW_TEMP" environment variable to a suitable You should set the "HOMEBREW_TEMP" environment variable to a suitable
directory on the same volume as your Cellar. directory on the same volume as your Cellar.
#{support_tier_message(tier: 2)}
EOS EOS
end end

View File

@ -378,15 +378,10 @@ class FormulaInstaller
If you're feeling brave, you can try to install from source with: If you're feeling brave, you can try to install from source with:
brew install --build-from-source #{formula} brew install --build-from-source #{formula}
It is expected behaviour that most formulae will fail to build from source. This is a Tier 3 configuration:
It is expected behaviour that Homebrew will be buggy and slow when building from source. #{Formatter.url("https://docs.brew.sh/Support-Tiers#tier-3")}
Do not create any issues about failures building from source on Homebrew's GitHub repositories. #{Formatter.bold("Do not report any issues to Homebrew/* repositories!")}
Do not create any issues building from source even if you think this message is unrelated. Read the above document instead before opening any issues or PRs.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help building from source in Homebrew's discussions but are unlikely to receive a response.
If building from source fails, try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.
EOS EOS
raise CannotInstallFormulaError, message raise CannotInstallFormulaError, message
end end
@ -608,7 +603,7 @@ on_request: installed_on_request?, options:)
raise if Homebrew::EnvConfig.developer? raise if Homebrew::EnvConfig.developer?
$stderr.puts "Please report this issue to the #{formula.tap&.full_name} tap".squeeze(" ") $stderr.puts "Please report this issue to the #{formula.tap&.full_name} tap".squeeze(" ")
$stderr.puts " (not Homebrew/brew or Homebrew/homebrew-core)!" unless formula.core_formula? $stderr.puts " (not Homebrew/* repositories)!" unless formula.core_formula?
false false
else else
f.linked_keg.exist? && f.opt_prefix.exist? f.linked_keg.exist? && f.opt_prefix.exist?

View File

@ -26,7 +26,8 @@ module Homebrew
@checks ||= Diagnostic::Checks.new @checks ||= Diagnostic::Checks.new
opoo <<~EOS opoo <<~EOS
You passed `--cc=#{cc}`. You passed `--cc=#{cc}`.
#{@checks.please_create_pull_requests}
#{@checks.support_tier_message(tier: 3)}
EOS EOS
end end

View File

@ -56,7 +56,7 @@ module OS
if OS.mac? if OS.mac?
require "os/mac" require "os/mac"
require "hardware" require "hardware"
# Don't tell people to report issues on unsupported configurations. # Don't tell people to report issues on non-Tier 1 configurations.
if !OS::Mac.version.prerelease? && if !OS::Mac.version.prerelease? &&
!OS::Mac.version.outdated_release? && !OS::Mac.version.outdated_release? &&
ARGV.none? { |v| v.start_with?("--cc=") } && ARGV.none? { |v| v.start_with?("--cc=") } &&
@ -76,7 +76,7 @@ module OS
end end
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def self.unsupported_configuration? def self.not_tier_one_configuration?
!defined?(OS::ISSUES_URL) !defined?(OS::ISSUES_URL)
end end
end end

View File

@ -25,10 +25,14 @@ module Formatter
"#{Tty.green}#{string}#{Tty.default}" "#{Tty.green}#{string}#{Tty.default}"
end end
def self.option(string) def self.bold(string)
"#{Tty.bold}#{string}#{Tty.reset}" "#{Tty.bold}#{string}#{Tty.reset}"
end end
def self.option(string)
bold(string)
end
# Format a string as success, with an optional label. # Format a string as success, with an optional label.
# #
# @api internal # @api internal