Skip to content

Conversation

@rnaveiras
Copy link
Contributor

Private GitHub repositories require downloading assets via the API endpoint (api.github.com/repos/.../releases/assets/ID) with proper authentication headers, rather than direct download URLs (github.com/.../releases/download/...) which only work for public repos.

Changed Asset deserialisation to prefer url (API endpoint) over browser_download_url because the API endpoint works for both public and private repositories when authentication is provided, while the browser download URL returns 404 for private repos.

The existing download_asset method already sets the correct headers (Accept: application/octet-stream and Authorisation) required for API endpoint downloads.

How to reproduce the issue with github and curl

export GITHUB_TOKEN="ghp_your_token_here"
export PRIVATE_REPO="foo/bar"

Get the last release form the API

curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \
     -H "Accept: application/vnd.github+json" \
     https://api.github.com/repos/${PRIVATE_REPO}/releases/latest | jq '.assets[0] | { name, url, browser_download_url }'

example output:

{
  "name": "bar_Darwin_arm64.tar.gz",
  "url": "https://api.github.com/repos/foo/bar/releases/assets/299331819",
  "browser_download_url": "https://github.com/foo/bar/releases/download/v0.1.0/bar_Darwin_arm64.tar.gz"
}

Try the browser download URL on a private repo (failed)

# this will fail with 404 for private repositories
curl -L -H "Authorization: Bearer $GITHUB_TOKEN" \
     "https://github.com/foo/bar/releases/download/v0.1.0/bar_Darwin_arm64.tar.gz`

Returns not found - You can add the -o /tmp/bar.tar.gz , you will see only writes a test file that contains (not found)

  • Try with URL
# this works
$ curl -L -H "Authorization: Bearer $GITHUB_TOKEN" \
     -H "Accept: application/octet-stream" \
     -o /tmp/bar.tar.gz \
     https://api.github.com/repos/foo/bar/releases/assets/123456

$ ls -lh /tmp/bar.tar.gz

How to reproduce the issue with ubi

$ echo ${GITHUB_TOKEN:0:12}
github_pat_1

$ ubi --version
ubi 0.8.1
$ ubi --project foo/bar --in /tmp/test
[ubi][ERROR] error requesting https://github.com/foo/ares/bar/download/v0.1.0/bar_Darwin_arm64.tar.gz: 404 Not Found
Not Found

I can attached the debug output if necessary. I had changed the name of the repo for privacy, so foo/bar is not real, but you can test that with a private repo.

@risu729
Copy link

risu729 commented Oct 14, 2025

jdx/mise#6652 was also caused by this regression.
The change was introduced in #107, but I didn't find the exact reason for this change.

FYI, this GitHub behaviour is reported in https://github.com/orgs/community/discussions/47453.

@autarch
Copy link
Member

autarch commented Oct 18, 2025

Hi, thanks for your PR!

I'm pretty finicky about my projects (see this blog post for details), so I rarely merge a PR as-is.

For larger PRs, I typically use the GitHub PR review process and provide feedback directly on the code, asking you to make some changes. For smaller PRs, where I just want to tweak some small stuff (like doc wording, comments, code formatting, etc.), I don't do a PR review.

Whether or not I do a review, there are two options for merging the PR:

  1. I check your PR out locally, fiddle with it as needed, merge it locally, and simply close the PR on GitHub. This will preserve at least one commit with your name on it, but the PR will show up as closed in your GitHub stats.
  2. If you enable me to push directly to your PR branch (which is the default when you make a PR), I can do my fiddling, then force push to your PR branch and merge the resulting PR. Again, this will preserve at least one commit with your name on it, but you also get credit for the PR merge in your GitHub stats. The only downside is that I will be force pushing directly to your PR branch. Note that this will not work if the PR branch is named master. GitHub doesn't allow me to push to the default branch of your fork.

Please let me know which approach you'd prefer. If I don't hear from you before I get around to working on this PR I'll go with option 1.

Thanks again for your contribution!

@rnaveiras
Copy link
Contributor Author

Option 2 works for me, I have "Allow edits by maintainers" selected to feel free to force push to the branch as you need, thanks!

@autarch autarch force-pushed the fix-github-private-repos-download-assets branch from b9c7db3 to 51bcd20 Compare October 19, 2025 16:08
Private GitHub repositories require downloading assets via the API endpoint
(api.github.com/repos/.../releases/assets/ID) with authentication headers, rather than direct
download URLs (github.com/.../releases/download/...), which only work for public repos.

This commit changes Asset deserialization to prefer the `url` (API endpoint) field over
`browser_download_url`.

The existing download_asset method already sets the correct headers (`Accept:
application/octet-stream` and `Authorization`) required for API endpoint downloads.
@autarch autarch force-pushed the fix-github-private-repos-download-assets branch from 51bcd20 to 8579e0c Compare October 19, 2025 16:11
@autarch autarch merged commit d891c43 into houseabsolute:master Oct 19, 2025
31 checks passed
@autarch
Copy link
Member

autarch commented Oct 19, 2025

Merged. Thanks for working on this!

@autarch
Copy link
Member

autarch commented Oct 19, 2025

This was released in v0.8.2. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants