octokit.rb icon indicating copy to clipboard operation
octokit.rb copied to clipboard

Add support for Actions APIs

Open electrum opened this issue 5 years ago • 8 comments

https://developer.github.com/v3/actions/

electrum avatar Mar 25 '20 08:03 electrum

@electrum PRs welcome 😄

tarebyte avatar Mar 25 '20 12:03 tarebyte

Hello, we are going to use part of the GitHub Actions APIs in the near future and it would be easier to have the support.

That's why, I would gladly work on workflow run APIs if that is OK with you :smile:.

Also I noticed there is no endpoint for https://developer.github.com/v3/repos/#create-a-repository-dispatch-event. I will address that too.

petar-lazarov avatar May 04 '20 17:05 petar-lazarov

Feel free @petar-lazarov 🍰

tarebyte avatar May 04 '20 18:05 tarebyte

Are there plans to also support the artifacts API within actions? Or is that also a "PRs welcome" scenario?

ianfixes avatar Aug 12 '21 03:08 ianfixes

Or is that also a "PRs welcome" scenario?

Yup 😄

tarebyte avatar Aug 12 '21 12:08 tarebyte

OK, I'll think about coding that up. One thing that I've observed is that when downloading artifacts, using Octokit::Client.get will attempt to follow a redirect and end up downloading the entire response (which is file contents as a zip) into memory. That is untenable for large files, in particular docker images (which can potentially be 100s of megabytes if not gigabytes) -- the preferred approach would be to receive an IO stream instead.

What's the most appropriate way to perform the following operation within octokit?

require 'net/http'

def artifact_downloadable_url(access_token, owner, repo, run_id, artifact_name)
  client = Octokit::Client.new(access_token: access_token)

  # get URL from artifact
  artifacts = client.get("/repos/#{owner}/#{repo}/actions/runs/#{run_id}/artifacts")[:artifacts]
  artifact = artifacts.find { |a| a[:name] == artifact_name }
  artifact_url = artifact[:archive_download_url]
  
  # extract location header from HTTP 302 response
  uri = URI(artifact_url)
  redirect_response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
    request = Net::HTTP::Get.new(uri)
    request["Authorization"] = "token #{access_token}"
    http.request(request)
  end
  redirect_response.each_header.find { |h| h[0] == "location" }[1]
end

# now you can get an IO object as follows:
#   URI(artifact_downloadable_url( ... )).open

In particular, I'm curious how to extract the headers from a 302 response ... the faraday stack in the client seems set up to automatically redirect, and even then I'm not sure whether setting up a separate faraday instance with different middleware for a single request is the acceptable way to do this.

Thoughts?

ianfixes avatar Aug 12 '21 13:08 ianfixes

In particular, I'm curious how to extract the headers from a 302 response ... the faraday stack in the client seems set up to automatically redirect, and even then I'm not sure whether setting up a separate faraday instance with different middleware for a single request is the acceptable way to do this.

Thoughts?

It seems that we have the same need where we implement the method for the API request used to download a workflow run log. As shown below, it seems that the implementation of that uses a special Faraday instance called client_without_redirects:

https://github.com/octokit/octokit.rb/blob/d1628ebd3e71aeb1534b3115c8bf37e8fb42068f/lib/octokit/client/actions_workflow_runs.rb#L79-L91

Perhaps we could try to use that same strategy?

lerebear avatar Jan 12 '22 04:01 lerebear

I've tried to implement support for the artifact APIs in https://github.com/octokit/octokit.rb/pull/1480.

lerebear avatar Sep 13 '22 04:09 lerebear

Since this issue was open, we've added actions functionality to the SDK. Please re-open this issue if you believe your needs are still unmet.

nickfloyd avatar Nov 03 '22 18:11 nickfloyd