How do I download binary files of a GitHub release?

23,751

Solution 1

I've tried for days trying to find the proper answer to this, and finally I figured out how to do this via the curl command. It's a 3-step process.

First, to get a list of the assets for the latest release:

curl -H "Authorization: token YOURGITHUBTOKEN" \
    https://api.github.com/repos/NAME/REPO/releases/latest 

Then in the JSON, look up the url of the asset you want. For example it would look like:

"url": "https://api.github.com/repos/NAME/REPO/releases/assets/1275759"

Then you pass this to another curl command to retrieve the actual URL, which is actually a link to an Amazon S3 file.

curl -H "Authorization: token YOURGITHUBTOKEN" \
     -H "Accept:application/octet-stream" \
     -i https://api.github.com/repos/NAME/REPO/releases/assets/1275759

The URL will be in the "location" field of the HTTP response, and then use curl to get the file like this:

curl "https://github-cloud.s3.amazonaws.com...." -i -o FILENAME

Solution 2

Binary release assets exist outside of Git, and cannot be managed using the standard tools.

They should be available via GitHub's API, though.

  1. List the repository's release assets:

    GET /repos/:owner/:repo/releases/:id/assets
    

    This will send back a JSON document listing the release assets for the repository, e.g.

    [
      {
        "url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/1",
        "browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip",
        "id": 1,
        "name": "example.zip",
        "label": "short description",
        "state": "uploaded",
        "content_type": "application/zip",
        "size": 1024,
        "download_count": 42,
        "created_at": "2013-02-27T19:35:32Z",
        "updated_at": "2013-02-27T19:35:32Z",
        "uploader": {
          "login": "octocat",
          ...
        }
      }
    ]
    
  2. Retrieve the assts from the release you want, as defined by its id from above:

    GET /repos/:owner/:repo/releases/assets/:id
    

    If you want to download the asset's binary content, pass a media type of "application/octet-stream". The API will either redirect the client to the location, or stream it directly if possible. API clients should handle both a 200 or 302 response.

As documented, these requests are all relative to https://api.github.com.

Solution 3

This is a mini script to download an asset knowing its file name (can be easily modified to download other assets:

asseturl=$(curl -H "Authorization: token ${token}" https://api.github.com/repos/${repo}/releases/${releaseid}/assets | jq ".[] | select(.name==\"${filename}\") | .url")
curl -L -H "Authorization: token ${token}" -H "Accept:application/octet-stream" $(echo $asseturl | tr -d '"') > ${filename}
  • $token is the access token for github
  • $filename is the filename for the asset
  • $releaseid is the releaseid where the binary file is stored

Solution 4

For Ansible, you can use this tasklist (same steps as @ted):

- name: Get latest version
  uri:
    url: "https://api.github.com/repos/{{github_user}}/{{github_repo}}/releases/latest"
    return_content: yes
    headers:
      Authorization: "token {{ vault_github_deploying_token }}"
  register: github_response

- set_fact:
    binary_asset_url: "{{  github_response.json.assets|json_query(query) }}"
  vars:
    query: "[?name=='{{your_github_binary_filename}}'].url | [0]"   

- name: Get Binary asset's location
  uri:
    url: "{{ binary_asset_url }}"
    return_content: no
    follow_redirects: none
    status_code: 302
    headers:
      Authorization: "token {{ vault_github_deploying_token }}"
      Accept: "application/octet-stream"
  register: assets

- name: Download binary
  get_url:
    url: "{{ assets.location }}"
    dest: "/tmp/{{ your_github_binary_filename }}"
    mode: 0755

Solution 5

One-Step Process:

Here's a one-liner (sans auth) I used in a script to download Digital Ocean's doctl interface from Github. It just grabs the LATEST release and unTARs it:

curl -sL $(curl -s https://api.github.com/repos/digitalocean/doctl/releases/latest | grep "http.*linux-amd64.tar.gz" | awk '{print $2}' | sed 's|[\"\,]*||g') | tar xzvf -

If not using Linux, replace "http.*linux-amd64.tar.gz" in the above with "darwin", "windows", etc and the appropriate arch.

NOTE: The above should work programmatically grabbing binaries from other Github repos, but I've only tested it with doctl. HTH-

Share:
23,751
Tyler Pfaff
Author by

Tyler Pfaff

Updated on April 01, 2020

Comments

  • Tyler Pfaff
    Tyler Pfaff about 4 years

    I have a repo with binary files in it that I need.

    I can

    git checkout tags/thetagoftherelease
    

    which seems to checkout the correct tag, but does not pull down the binary files. How can I pull down the binary files that were added to the release (the green boxes on the release)?

    Added picture of binary files in a release.

    enter image description here

  • frekele
    frekele almost 8 years
    best answer, thanks.Forget curl, use the httpie.org (CLI HTTP client, user-friendly curl replacement with intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc.)
  • Erick A. Montañez
    Erick A. Montañez about 6 years
    Make sure to use quotes to surround the s3 url. Otherwise curl won't get it apropiately.
  • M. Davis
    M. Davis almost 6 years
    Excellent! For most releases, your_github_binary_filename is usually "{{ github_repo }}.tar.gz"
  • cyrf
    cyrf over 2 years
    if you dont know the releaseid you can filter /repos/{owner}/{repo}/releases by name with curl -H "Authorization: token ${token}" https://api.github.com/repos/${owner}/${repo}/releases | jq -r ".[] | select(.name == \"${releasename}\") | .assets[] | select(.name == \"${filename}\") | .url"