# typed: strict # frozen_string_literal: true require "download_strategy" require "utils/github" module GitHub # Download an artifact from GitHub Actions and unpack it into the current working directory. # # @param url [String] URL to download from # @param artifact_id [String] a value that uniquely identifies the downloaded artifact sig { params(url: String, artifact_id: String).void } def self.download_artifact(url, artifact_id) token = API.credentials raise API::MissingAuthenticationError if token.blank? # We use a download strategy here to leverage the Homebrew cache # to avoid repeated downloads of (possibly large) bottles. downloader = GitHubArtifactDownloadStrategy.new(url, artifact_id, token:) downloader.fetch downloader.stage end end # Strategy for downloading an artifact from GitHub Actions. class GitHubArtifactDownloadStrategy < AbstractFileDownloadStrategy sig { params(url: String, artifact_id: String, token: String).void } def initialize(url, artifact_id, token:) super(url, "artifact", artifact_id) @cache = T.let(HOMEBREW_CACHE/"gh-actions-artifact", Pathname) @token = T.let(token, String) end sig { override.params(timeout: T.any(Float, Integer, NilClass)).void } def fetch(timeout: nil) ohai "Downloading #{url}" if cached_location.exist? puts "Already downloaded: #{cached_location}" else begin Utils::Curl.curl("--location", "--create-dirs", "--output", temporary_path.to_s, url, "--header", "Authorization: token #{@token}", secrets: [@token], timeout:) rescue ErrorDuringExecution raise CurlDownloadStrategyError, url end cached_location.dirname.mkpath temporary_path.rename(cached_location.to_s) end symlink_location.dirname.mkpath FileUtils.ln_s cached_location.relative_path_from(symlink_location.dirname), symlink_location, force: true end private sig { returns(String) } def resolved_basename "artifact.zip" end end