Class: Homebrew::Livecheck::Strategy::GithubReleases

Inherits:
Object
  • Object
show all
Extended by:
Homebrew::Livecheck::Strategic
Defined in:
livecheck/strategy/github_releases.rb

Overview

The GithubReleases strategy identifies versions of software at github.com by checking a repository's recent releases using the GitHub API.

GitHub URLs take a few different formats:

  • https://github.com/example/example/releases/download/1.2.3/example-1.2.3.tar.gz
  • https://github.com/example/example/archive/v1.2.3.tar.gz
  • https://github.com/downloads/example/example/example-1.2.3.tar.gz

GithubReleases should only be used when the upstream repository has releases for suitable versions and the strategy is necessary or appropriate (e.g. the formula/cask uses a release asset and the GithubLatest strategy isn't sufficient to identify the newest version. The strategy can only be applied by using strategy :github_releases in a livecheck block.

The default regex identifies versions like 1.2.3/v1.2.3 in each release's tag or title. This is a common tag format but a modified regex can be provided in a livecheck block to override the default if a repository uses a different format (e.g. 1.2.3d, 1.2.3-4, etc.).

Constant Summary collapse

NICE_NAME =
"GitHub - Releases"
PRIORITY =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

A priority of zero causes livecheck to skip the strategy. We do this for Homebrew::Livecheck::Strategy::GithubReleases so we can selectively apply the strategy using strategy :github_releases in a livecheck block.

0
URL_MATCH_REGEX =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

The Regexp used to determine if the strategy applies to the URL.

%r{
  ^https?://github\.com
  /(?:downloads/)?(?<username>[^/]+) # The GitHub username
  /(?<repository>[^/]+)              # The GitHub repository name
}ix
DEFAULT_REGEX =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

The default regex used to identify a version from a tag when a regex isn't provided.

/v?(\d+(?:\.\d+)+)/i

Class Method Summary collapse

Methods included from Homebrew::Livecheck::Strategic

find_versions, match?

Class Method Details

.find_versions(url:, regex: nil, content: nil, options: Options.new, &block) ⇒ Hash{Symbol => T.anything}

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Generates the GitHub API URL for the repository's recent releases and identifies versions from the JSON response.

Parameters:

  • url (String)

    the URL of the content to check

  • regex (Regexp, nil) (defaults to: nil)

    a regex for matching versions in content

  • content (String, nil) (defaults to: nil)

    content to check instead of fetching

  • options (Options) (defaults to: Options.new)

    options to modify behavior

  • block (Proc, nil)

Returns:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'livecheck/strategy/github_releases.rb', line 134

def self.find_versions(url:, regex: nil, content: nil, options: Options.new, &block)
  regex ||= DEFAULT_REGEX
  match_data = { matches: {}, regex:, url: }
  match_data[:cached] = true if content

  generated = generate_input_values(url)
  return match_data if generated.blank?

  match_data[:url] = generated[:url]

  unless match_data[:cached]
    match_data[:content] = GitHub::API.open_rest(generated[:url], parse_json: false)
    content = match_data[:content]
  end
  return match_data if content.blank?

  versions_from_content(content, regex, &block).each do |match_text|
    match_data[:matches][match_text] = Version.new(match_text)
  end

  match_data
end

.generate_input_values(url) ⇒ Hash{Symbol => T.untyped}

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Extracts information from a provided URL and uses it to generate various input values used by the strategy to check for new versions. Some of these values act as defaults and can be overridden in a livecheck block.

Parameters:

  • url (String)

    the URL used to generate values

Returns:



71
72
73
74
75
76
77
78
79
80
81
82
# File 'livecheck/strategy/github_releases.rb', line 71

def self.generate_input_values(url)
  values = {}

  match = url.delete_suffix(".git").match(URL_MATCH_REGEX)
  return values if match.blank?

  values[:url] = "#{GitHub::API_URL}/repos/#{match[:username]}/#{match[:repository]}/releases"
  values[:username] = match[:username]
  values[:repository] = match[:repository]

  values
end

.match?(url) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Whether the strategy can be applied to the provided URL.

Parameters:

  • url (String)

    the URL to match against

Returns:

  • (Boolean)


59
60
61
# File 'livecheck/strategy/github_releases.rb', line 59

def self.match?(url)
  URL_MATCH_REGEX.match?(url)
end

.versions_from_content(content, regex, &block) ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Uses a regex to match versions from release JSON or, if a block is provided, passes the JSON to the block to handle matching. With either approach, an array of unique matches is returned.

Parameters:

  • content (String)

    an array of releases or a single release

  • regex (Regexp)

    a regex for matching versions in content

  • block (Proc, nil)

Returns:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'livecheck/strategy/github_releases.rb', line 98

def self.versions_from_content(content, regex, &block)
  return [] if content.blank?

  json = Json.parse_json(content)
  return [] if json.blank?

  if block.present?
    block_return_value = yield(json, regex)
    return Strategy.handle_block_return(block_return_value)
  end

  json = [json] unless json.is_a?(Array)
  json.compact_blank.filter_map do |release|
    next if release["draft"] || release["prerelease"]

    release["tag_name"]&.[](regex, 1)
  end.uniq
end