diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml index eb1ac0740f..d2d463d20d 100644 --- a/Library/Homebrew/.rubocop.yml +++ b/Library/Homebrew/.rubocop.yml @@ -25,6 +25,7 @@ Style/Documentation: - Homebrew Include: - abstract_command.rb + - autobump_constants.rb - cask/cask.rb - cask/dsl.rb - cask/dsl/version.rb diff --git a/Library/Homebrew/autobump_constants.rb b/Library/Homebrew/autobump_constants.rb index 6dfab8de22..baf7ecdf5a 100644 --- a/Library/Homebrew/autobump_constants.rb +++ b/Library/Homebrew/autobump_constants.rb @@ -1,11 +1,15 @@ # typed: strict # frozen_string_literal: true -# TODO: add more reasons here +NO_AUTOBUMP_REASONS_INTERNAL = T.let({ + extract_plist: "livecheck uses `:extract_plist` strategy", + latest_version: "`version` is set to `:latest`", +}.freeze, T::Hash[Symbol, String]) + +# The valid symbols for passing to `no_autobump!` in a `Formula` or `Cask`. +# @api public NO_AUTOBUMP_REASONS_LIST = T.let({ incompatible_version_format: "incompatible version format", bumped_by_upstream: "bumped by upstream", - extract_plist: "livecheck uses `:extract_plist` strategy", - latest_version: "`version` is set to `:latest`", requires_manual_review: "a manual review of this package is required for inclusion in autobump", -}.freeze, T::Hash[Symbol, String]) +}.merge(NO_AUTOBUMP_REASONS_INTERNAL).freeze, T::Hash[Symbol, String]) diff --git a/docs/Autobump.md b/docs/Autobump.md new file mode 100644 index 0000000000..0beaf0bac0 --- /dev/null +++ b/docs/Autobump.md @@ -0,0 +1,33 @@ +--- +last_review_date: "2025-06-16" +--- + +# Autobump + +[BrewTestBot](BrewTestBot.md) automatically checks for available updates of packages that are in Homebrew's "autobump list" for official repositories. These packages should not have to be bumped (i.e versions increased) manually by a contributor. Instead, every 3 hours a GitHub Action opens a new pull request to upgrade to the latest version of a formula/cask, if needed. + +## Excluding packages from autobumping + +By default, all new formulae and casks from [Homebrew/core](https://github.com/Homebrew/homebrew-core) and [Homebrew/cask](https://github.com/Homebrew/homebrew-cask) repositories are autobumped. To exclude a package from being autobumped, it must: + +1. have a `deprecate!` or `disable!` call +2. have a `livecheck do` block containing a `skip` call +3. has no `no_autobump!` call + +There are other formula or cask-specific reasons listed in the Formula Cookbook and Cask Cookbook respectively. + +To use `no_autobump!`, a reason for exclusion must be provided. We prefer use of one of the supported symbols. These can be found in the [`NO_AUTOBUMP_REASONS_LIST`](https://rubydoc.brew.sh/top-level-namespace.html#NO_AUTOBUMP_REASONS_LIST-constant). + +The reasons can be specified by their symbols: + +```ruby +no_autobump! because: :bumped_by_upstream +``` + +If none of the existing reasons fit, a custom reason can be provided as a string: + +```ruby +no_autobump! because: "some unique reason" +``` + +If there are multiple packages with a similar custom reason, it be added to `NO_AUTOBUMP_REASONS_LIST`. diff --git a/docs/Brew-Livecheck.md b/docs/Brew-Livecheck.md index 3b4b0d535f..6f69c0c0c6 100644 --- a/docs/Brew-Livecheck.md +++ b/docs/Brew-Livecheck.md @@ -438,6 +438,8 @@ livecheck do end ``` +Note that if a package uses this livecheck strategy it will be excluded from [autobumping](Autobump.md) as this strategy has negative impact on CI time. + ### `throttle` For software with extremely frequent releases that don't all need to be published as formula/cask updates, livecheck can be set to reduce how many versions it surfaces by using `throttle`. In this example, only versions whose last component is divisible by 10 will be returned. diff --git a/docs/Cask-Cookbook.md b/docs/Cask-Cookbook.md index 7777cde67d..32684f0fef 100644 --- a/docs/Cask-Cookbook.md +++ b/docs/Cask-Cookbook.md @@ -56,6 +56,8 @@ Having a common order for stanzas makes casks easier to update and parse. Below livecheck + no_autobump! + deprecate! disable! @@ -173,6 +175,7 @@ Each cask must declare one or more [artifacts](https://rubydoc.brew.sh/Cask/Arti | `container nested:` | no | Relative path to an inner container that must be extracted before moving on with the installation. This allows for support of `.dmg` inside `.tar`, `.zip` inside `.dmg`, etc. (Example: [blocs.rb](https://github.com/Homebrew/homebrew-cask/blob/aa461148bbb5119af26b82cccf5003e2b4e50d95/Casks/b/blocs.rb#L17-L19)) | | `container type:` | no | Symbol to override container-type autodetect. May be one of: `:air`, `:bz2`, `:cab`, `:dmg`, `:generic_unar`, `:gzip`, `:otf`, `:pkg`, `:rar`, `:seven_zip`, `:sit`, `:tar`, `:ttf`, `:xar`, `:zip`, `:naked`. (Example: [parse.rb](https://github.com/Homebrew/homebrew-cask/blob/aa461148bbb5119af26b82cccf5003e2b4e50d95/Casks/p/parse.rb#L10)) | | `auto_updates` | no | `true`. Asserts that the cask artifacts auto-update. Use if `Check for Updates…` or similar is present in an app menu, but not if it only opens a webpage and does not do the download and installation for you. | +| [`no_autobump!`](#stanza-no_autobump) | no | Allowed symbol or a string. Excludes cask from autobumping if set. | ## Stanza descriptions @@ -641,6 +644,24 @@ Every `livecheck` block must contain a `url`, which can be either a string or a Refer to the [`brew livecheck`](Brew-Livecheck.md) documentation for how to write a `livecheck` block. +### Stanza: `no_autobump!` + +The `no_autobump!` stanza excludes the cask for autobump list. That means the future updates will be handled by Homebrew contributors rather than by an automated process. + +To use this stanza, a reason must be provided. The preferred way is to use one of the available symbols. These symbols can be found in the [`NO_AUTOBUMP_REASONS_LIST`](https://rubydoc.brew.sh/top-level-namespace.html#NO_AUTOBUMP_REASONS_LIST-constant). + +```ruby +no_autobump! because: :incompatible_version_format +``` + +A custom reason can be provided if none of the available symbols fits: + +```ruby +no_autobump! because: "some unique reason" +``` + +Refer to [Autobump](Autobump.md) page for more information about the autobump process in Homebrew. + ### Stanza: `name` `name` accepts a UTF-8 string defining the name of the software, including capitalization and punctuation. It is used to help with searchability and disambiguation. @@ -1149,7 +1170,7 @@ The special value `version :latest` is used when: * `url` does not contain any version information and there is no way to retrieve the version using a `livecheck`, or * having a correct value for `version` is too difficult or impractical, even with our automated systems. For example, [chromium.rb](https://github.com/Homebrew/homebrew-cask/blob/aa461148bbb5119af26b82cccf5003e2b4e50d95/Casks/c/chromium.rb#L4) which releases multiple versions per day. -In both cases, using the special value [`sha256 :no_check`](#special-value-no_check) is also required. +In both cases, using the special value [`sha256 :no_check`](#special-value-no_check) is also required. Casks that use `version :latest` are excluded from [autobumping](Autobump.md). ### Stanza: `zap` diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md index a94ffde80f..00664fcbf0 100644 --- a/docs/Formula-Cookbook.md +++ b/docs/Formula-Cookbook.md @@ -746,6 +746,40 @@ end For `url`/`regex` guidelines and additional `livecheck` block examples, refer to the [`brew livecheck` documentation](Brew-Livecheck.md). For more technical information on the methods used in a `livecheck` block, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck). +### Excluding formula from autobumping + +By default, all new formulae in the Homebrew/core repository are autobumped. It means that future updates will be handled automatically by Homebrew CI jobs, and contributors do not have to do it manually. + +Sometimes, we want to exclude a formula from this list, for one reason or another. It can be done by adding the `no_autobump!` method in the formula definition, for example: + +```ruby +class Foo < Formula + # ... + url "https://example.com/foo-1.0.tar.gz" + + livecheck do + url "https://example.com/foo/download.html" + regex(/href=.*?foo[._-]v?(\d+(?:\.\d+)+)\.t/i) + end + + no_autobump! because: :bumped_by_upstream +end +``` + +To use this method, a reason must be provided. The preferred way is to use one of the available symbols. These reasons can be found in the [`NO_AUTOBUMP_REASONS_LIST`](https://rubydoc.brew.sh/top-level-namespace.html#NO_AUTOBUMP_REASONS_LIST-constant). + +```ruby +no_autobump! because: :incompatible_version_format +``` + +A custom reason can be provided if none of the available symbols fits: + +```ruby +no_autobump! because: "some unique reason" +``` + +More information about the autobump process can be found on the [Autobump](Autobump.md) page. + ### Unstable versions (`head`) Formulae can specify an alternate download for the upstream project’s development cutting-edge source (e.g. `main`/`master`/`trunk`) using [`head`](https://rubydoc.brew.sh/Formula#head-class_method), which can be activated by passing `--HEAD` when installing. Specifying it is done in the same manner as [`url`](https://rubydoc.brew.sh/Formula#url-class_method): diff --git a/docs/index.md b/docs/index.md index af1627ba70..58eaa29bd7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,6 +52,7 @@ last_review_date: "2025-02-08" - [Node for Formula Authors](Node-for-Formula-Authors.md) - [Python for Formula Authors](Python-for-Formula-Authors.md) - [`brew livecheck`](Brew-Livecheck.md) +- [Autobump](Autobump.md) - [Migrating a Formula to a Tap](Migrating-A-Formula-To-A-Tap.md) - [Renaming a Formula](Rename-A-Formula.md) - [Building Against Non-Homebrew Dependencies](Building-Against-Non-Homebrew-Dependencies.md)