How to download GitHub Release from private repo using command line

Learn how to download github release from private repo using command line with practical examples, diagrams, and best practices. Covers shell, github, command-line development techniques with visua...

Download GitHub Releases from Private Repositories via Command Line

Hero image for How to download GitHub Release from private repo using command line

Learn how to programmatically download release assets from private GitHub repositories using curl and wget with personal access tokens.

Downloading release assets from public GitHub repositories is straightforward. However, accessing releases from private repositories requires authentication. This article will guide you through the process of using command-line tools like curl and wget to download these assets securely, leveraging GitHub Personal Access Tokens (PATs).

Understanding GitHub Releases and Authentication

GitHub Releases are a way to package and provide software to your users. They are based on Git tags and can include binaries, source code, and other files. For private repositories, accessing these files programmatically requires authentication. The recommended method for command-line access is using a Personal Access Token (PAT).

A Personal Access Token acts as an alternative password when using the GitHub API or Git over HTTPS. It's crucial to generate a PAT with the appropriate scopes to ensure it has the necessary permissions to access your private repositories and their releases. For downloading releases, the repo scope (or more specifically, repo:status, repo_deployment, public_repo if applicable) is generally required.

flowchart TD
    A[Start]
    A --> B{Generate GitHub PAT}
    B --> C{Set PAT as Environment Variable}
    C --> D{Construct API URL for Release Asset}
    D --> E{Authenticate with PAT}
    E --> F{Download Asset using curl/wget}
    F --> G[End]

Workflow for downloading private GitHub release assets

Generating a Personal Access Token (PAT)

Before you can download anything, you need a PAT. Follow these steps to create one with the correct permissions:

1. Navigate to GitHub Developer Settings

Go to your GitHub profile settings, then select 'Developer settings' from the sidebar.

2. Access Personal Access Tokens

Click on 'Personal access tokens' and then 'Tokens (classic)'.

3. Generate New Token

Click 'Generate new token' and choose 'Generate new token (classic)'.

4. Configure Token Details

Give your token a descriptive name (e.g., 'Release Downloader'). Set an expiration date (it's best practice to set a limited expiration). For scopes, select repo to grant full control of private repositories. If you need more granular control, ensure repo:status and public_repo are selected at a minimum for release access.

5. Save Your Token

Click 'Generate token'. Copy the token immediately as you won't be able to see it again. Store it securely.

Downloading Release Assets with curl

curl is a versatile command-line tool for transferring data with URLs. It's widely available on most Unix-like systems and can be used to download GitHub release assets by authenticating with your PAT.

First, you need to identify the API URL for the specific release asset you want to download. This is typically in the format: https://api.github.com/repos/{owner}/{repo}/releases/assets/{asset_id}

To find the asset_id, you can list all assets for a specific release tag: https://api.github.com/repos/{owner}/{repo}/releases/tags/{tag_name}

Or, to get the latest release: https://api.github.com/repos/{owner}/{repo}/releases/latest

When you query these URLs, look for the browser_download_url or url field within the assets array. The url field is the API endpoint for the asset, which requires authentication and a specific Accept header. The browser_download_url is often a direct download link that might work without explicit authentication for public assets, but for private ones, it's safer to use the API endpoint with authentication.

# Set your GitHub Personal Access Token
export GITHUB_TOKEN="YOUR_PERSONAL_ACCESS_TOKEN"

# Repository details
OWNER="your-github-username-or-org"
REPO="your-private-repo-name"
TAG="v1.0.0" # Or 'latest' for the latest release

# 1. Get release information to find asset_id and download URL
# For a specific tag:
RELEASE_INFO=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/releases/tags/$TAG")

# For the latest release:
# RELEASE_INFO=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
#   "https://api.github.com/repos/$OWNER/$REPO/releases/latest")

# Extract asset_id and file name (adjust 'name' and 'id' based on your asset)
ASSET_ID=$(echo "$RELEASE_INFO" | grep -oP '"id": \K\d+' | head -1)
ASSET_NAME=$(echo "$RELEASE_INFO" | grep -oP '"name": "\K[^"]+' | head -1)

# If you have multiple assets, you might need to parse more carefully
# Example: find asset with a specific name pattern
# ASSET_ID=$(echo "$RELEASE_INFO" | jq -r '.assets[] | select(.name | contains("my_app.zip")) | .id')
# ASSET_NAME=$(echo "$RELEASE_INFO" | jq -r '.assets[] | select(.name | contains("my_app.zip")) | .name')

if [ -z "$ASSET_ID" ]; then
  echo "Error: Asset ID not found for tag $TAG in $OWNER/$REPO."
  exit 1
fi

# 2. Download the asset using the API endpoint
# Note the 'Accept' header for raw binary data
curl -LJO -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/octet-stream" \
  "https://api.github.com/repos/$OWNER/$REPO/releases/assets/$ASSET_ID"

echo "Downloaded $ASSET_NAME"

Bash script to download a specific release asset using curl.

Downloading Release Assets with wget

wget is another popular command-line utility for retrieving content from web servers. It can also be used for downloading private GitHub release assets, though its authentication mechanism is slightly different from curl.

# Set your GitHub Personal Access Token
export GITHUB_TOKEN="YOUR_PERSONAL_ACCESS_TOKEN"

# Repository details
OWNER="your-github-username-or-org"
REPO="your-private-repo-name"
TAG="v1.0.0" # Or 'latest' for the latest release

# 1. Get release information to find asset_id and download URL
# For a specific tag:
RELEASE_INFO=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$OWNER/$REPO/releases/tags/$TAG")

# For the latest release:
# RELEASE_INFO=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
#   "https://api.github.com/repos/$OWNER/$REPO/releases/latest")

# Extract asset_id and file name (adjust 'name' and 'id' based on your asset)
ASSET_ID=$(echo "$RELEASE_INFO" | grep -oP '"id": \K\d+' | head -1)
ASSET_NAME=$(echo "$RELEASE_INFO" | grep -oP '"name": "\K[^"]+' | head -1)

if [ -z "$ASSET_ID" ]; then
  echo "Error: Asset ID not found for tag $TAG in $OWNER/$REPO."
  exit 1
fi

# 2. Construct the download URL for wget
# wget doesn't handle the 'Accept: application/octet-stream' header directly for redirects
# It's often easier to get the 'browser_download_url' from the API response
# and then pass the Authorization header to wget.

# Extract browser_download_url for the specific asset
DOWNLOAD_URL=$(echo "$RELEASE_INFO" | jq -r ".assets[] | select(.id == $ASSET_ID) | .browser_download_url")

if [ -z "$DOWNLOAD_URL" ]; then
  echo "Error: Download URL not found for asset ID $ASSET_ID."
  exit 1
fi

# 3. Download the asset using wget
# Note: wget requires the --header for Authorization
wget --header="Authorization: token $GITHUB_TOKEN" \
     --content-disposition \
     "$DOWNLOAD_URL"

echo "Downloaded $ASSET_NAME"

Bash script to download a specific release asset using wget.

Both curl and wget provide robust ways to download files from private GitHub repositories. Choose the tool that best fits your environment and scripting preferences. Remember to always keep your Personal Access Tokens secure.