homebrew to download packages from private github behind SSO

Viewed 234

I am trying to setup a brew formula to download packages from private github behind sso, but getting error while downloading. Following is the formula:

class MyMvn < Formula
  desc "CLI tool to do maven operations"
  homepage "https://github.my.company/myorg/my-mvn"
  version "1.2.6"

  on_macos do
    if Hardware::CPU.arm?
      url "https://github.my.company/myorg/my-mvn/releases/download/v1.2.6/my-mvn_1.2.6_Darwin_x86_64.tar.gz"
      sha256 "d23869c3248d35d51d0b7eded53c93ebb16b9c213fa1cf9b8f736e851f8985dd"

    if Hardware::CPU.intel?
      url "https://github.my.company/myorg/my-mvn/releases/download/v1.2.6/my-mvn_1.2.6_Darwin_x86_64.tar.gz"
      sha256 "d23869c3248d35d51d0b7eded53c93ebb16b9c213fa1cf9b8f736e851f8985dd"

      def install
        bin.install "my-mvn"
      end
    end
  end

  depends_on "maven"

  test do
    system "#{bin}/my-mvn help"
  end
end

And download is being redirected to login which would result into SHA mismatch:

Downloading from https://github.my.company/login?return_to=https%3A%2F%2Fgithub.my.company%2Fmyorg%2Fmy-mvn%2Freleases%2Fdownload%2Fv1.2.6%2Fmy-mvn_1.2.6_Darwin_x86_64.tar.gz
---
---
Error: my-mvn: SHA256 mismatch

Is there any straight forward way to solve this, without custom homebrew downloader? Also an example of custom downloader for this case would be great. Thanks.

1 Answers

Following custom downloader solved it.

class MyReleaseDownloadStrategy < CurlDownloadStrategy

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

  def parse_url_pattern
    url_pattern = %r{https://github.my.company/([^/]+)/([^/]+)/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}@github.my.company/api/v3/repos/#{@owner}/#{@repo}/releases/assets/#{asset_id}"
  end

  private

  def _fetch(url:, resolved_url:, timeout:)
    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://github.my.company/api/v3/repos/#{@owner}/#{@repo}/releases/tags/#{@tag}"
    GitHub::API.open_rest(release_url)
  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
  end
end
Related