Help us understand the problem. What is going on with this article?

プライベートなツールをGitHub Releaseにおいてbrewで配布していたのがエラーになった件の対処メモ

More than 1 year has passed since last update.

GitHubのプライベートリポジトリのReleaseにおいてHomebrewのtapをつかってインストールできるようにしていたところ、以下がエラーが出るようになった。

==> Installing XXXX from xxxx/xxxx
Error: An exception occurred within a child process:
  MethodDeprecatedError: Calling GitHubPrivateRepositoryReleaseDownloadStrategy is disabled! Use a vendored GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap (using require_relative) instead.

GitHubPrivateRepositoryReleaseDownloadStrategyは使えなくなったのでえ、自分のtapで読みこんで使って、と書かれている気がする。

対処した内容

download_strategy.rbの配置

自前のtapの lib/download_strategy.rb を配置

lib/download_strategy.rb
# GitHubPrivateRepositoryDownloadStrategy downloads contents from GitHub
# Private Repository. To use it, add
# `:using => :github_private_repo` to the URL section of
# your formula. This download strategy uses GitHub access tokens (in the
# environment variables `HOMEBREW_GITHUB_API_TOKEN`) to sign the request.  This
# strategy is suitable for corporate use just like S3DownloadStrategy, because
# it lets you use a private GitHub repository for internal distribution.  It
# works with public one, but in that case simply use CurlDownloadStrategy.
class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
  require "utils/formatter"
  require "utils/github"


  def initialize(url, name, version, **meta)
    super
    parse_url_pattern
    set_github_token
  end


  def parse_url_pattern
    unless match = url.match(%r{https://github.com/([^/]+)/([^/]+)/(\S+)})
      raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Repository."
    end


    _, @owner, @repo, @filepath = *match
  end


  def download_url
    "https://#{@github_token}@github.com/#{@owner}/#{@repo}/#{@filepath}"
  end


  private


  def _fetch(url:, resolved_url:)
    curl_download download_url, to: temporary_path
  end


  def set_github_token
    @github_token = ENV["HOMEBREW_GITHUB_API_TOKEN"]
    unless @github_token
      raise CurlDownloadStrategyError, "Environmental variable HOMEBREW_GITHUB_API_TOKEN is required."
    end


    validate_github_repository_access!
  end


  def validate_github_repository_access!
    # Test access to the repository
    GitHub.repository(@owner, @repo)
  rescue GitHub::HTTPNotFoundError
    # We only handle HTTPNotFoundError here,
    # becase AuthenticationFailedError is handled within util/github.
    message = <<~EOS
      HOMEBREW_GITHUB_API_TOKEN can not access the repository: #{@owner}/#{@repo}
      This token may not have permission to access the repository or the url of formula may be incorrect.
    EOS
    raise CurlDownloadStrategyError, message
  end
end


# GitHubPrivateRepositoryReleaseDownloadStrategy downloads tarballs from GitHub
# Release assets. To use it, add `:using => :github_private_release` to the URL section
# of your formula. This download strategy uses GitHub access tokens (in the
# environment variables HOMEBREW_GITHUB_API_TOKEN) to sign the request.
class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDownloadStrategy
  def initialize(url, name, version, **meta)
    super
  end


  def parse_url_pattern
    url_pattern = %r{https://github.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(\S+)}
    unless @url =~ url_pattern
      raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Release."
    end


    _, @owner, @repo, @tag, @filename = *@url.match(url_pattern)
  end


  def download_url
    "https://#{@github_token}@api.github.com/repos/#{@owner}/#{@repo}/releases/assets/#{asset_id}"
  end


  private


  def _fetch(url:, resolved_url:)
    # HTTP request header `Accept: application/octet-stream` is required.
    # Without this, the GitHub API will respond with metadata, not binary.
    curl_download download_url, "--header", "Accept: application/octet-stream", to: temporary_path
  end


  def asset_id
    @asset_id ||= resolve_asset_id
  end


  def resolve_asset_id
    release_metadata = fetch_release_metadata
    assets = release_metadata["assets"].select { |a| a["name"] == @filename }
    raise CurlDownloadStrategyError, "Asset file not found." if assets.empty?


    assets.first["id"]
  end


  def fetch_release_metadata
    release_url = "https://api.github.com/repos/#{@owner}/#{@repo}/releases/tags/#{@tag}"
    GitHub.open_api(release_url)
  end
end

Formulaの修正

各Formulaの先頭に以下を追加

require_relative '../lib/download_strategy'

作業メモ

以下の変更で、非推奨になって、コードの位置が移動した。
https://github.com/Homebrew/brew/pull/5112

以下の変更で、コードが消えた。
https://github.com/Homebrew/brew/pull/5598

消えたファイルの中身
https://github.com/Homebrew/brew/blob/193af1442f6b9a19fa71325160d0ee2889a1b6c9/Library/Homebrew/compat/download_strategy.rb

修正方法

  1. 使いたいストラテジーをコピーしてもってくる。
  2. odisableの呼び出しを削除する
  3. もってきたものを各Formulaで読み込む

消えたストラテジー

  • S3DownloadStrategy
  • GitHubPrivateRepositoryDownloadStrategy
  • GitHubPrivateRepositoryReleaseDownloadStrategy
  • ScpDownloadStrategy

マージするまえに、特定のブランチの作業を確認してもらう方法

brew tap [リポジトリ名]/[tap名]
cd /usr/local/Homebrew/Library/Taps/[リポジトリ名]/homebrew-[tap名]
git fetch origin [作業ブランチ名]
git checkout FETCH_HEAD
brew install [確認するformula名]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした