GitHub指南解释了两种授权方式,但看起来这两种方式都不能用于Release文件。
因此,导致:
curl -u 'username' -L -o a.tgz https://github.com/company/repository/releases/download/TAG-NAME/A.tgz
总是有类似的东西
<!DOCTYPE html>
<!--
Hello future GitHubber! ...
GitHub指南解释了两种授权方式,但看起来这两种方式都不能用于Release文件。
因此,导致:
curl -u 'username' -L -o a.tgz https://github.com/company/repository/releases/download/TAG-NAME/A.tgz
总是有类似的东西
<!DOCTYPE html>
<!--
Hello future GitHubber! ...
要从私有仓库下载发布文件,可以使用个人访问令牌,该令牌可以在settings/tokens生成,需要授权完全控制私有存储库。
然后使用curl
命令下载资产(更改为适当的值):
curl -vLJO -H 'Authorization: token my_access_token' 'https://api.github.com/repos/:owner/:repo/releases/assets/:id'
或者,如果您正在使用OAuth应用程序,请使用:
curl -u my_client_id:my_client_secret https://api.github.com/repos/:owner/:repo/releases/assets/:id
:owner
代表您的用户或组织用户名;:repo
代表您的仓库名称;:id
是您的资产ID,可以在标签发布的URL中找到,例如:
https://api.github.com/repos/:owner/:repo/releases/tags/:tag
:token
是您的个人访问令牌(可以在/settings/tokens
创建);
注意:使用access_token
作为查询参数已被弃用。
这是一个Bash脚本,它可以根据给定的文件名下载资产文件:
#!/usr/bin/env bash
# Script to download asset file from tag release using GitHub API v3.
# See: https://dev59.com/MWIj5IYBdhLWcg3wUjkX#35688093
CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"
# Check dependencies.
set -e
type curl grep sed tr >&2
xargs=$(which gxargs || which xargs)
# Validate settings.
[ -f ~/.secrets ] && source ~/.secrets
[ "$GITHUB_API_TOKEN" ] || { echo "Error: Please define GITHUB_API_TOKEN variable." >&2; exit 1; }
[ $# -ne 4 ] && { echo "Usage: $0 [owner] [repo] [tag] [name]"; exit 1; }
[ "$TRACE" ] && set -x
read owner repo tag name <<<$@
# Define variables.
GH_API="https://api.github.com"
GH_REPO="$GH_API/repos/$owner/$repo"
GH_TAGS="$GH_REPO/releases/tags/$tag"
AUTH="Authorization: token $GITHUB_API_TOKEN"
WGET_ARGS="--content-disposition --auth-no-challenge --no-cookie"
CURL_ARGS="-LJO#"
# Validate token.
curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }
# Read asset tags.
response=$(curl -sH "$AUTH" $GH_TAGS)
# Get ID of the asset based on given name.
eval $(echo "$response" | grep -C3 "name.:.\+$name" | grep -w id | tr : = | tr -cd '[[:alnum:]]=')
#id=$(echo "$response" | jq --arg name "$name" '.assets[] | select(.name == $name).id') # If jq is installed, this can be used instead.
[ "$id" ] || { echo "Error: Failed to get asset id, response: $response" | awk 'length($0)<100' >&2; exit 1; }
GH_ASSET="$GH_REPO/releases/assets/$id"
# Download asset file.
echo "Downloading asset..." >&2
curl $CURL_ARGS -H "Authorization: token $GITHUB_API_TOKEN" -H 'Accept: application/octet-stream' "$GH_ASSET"
echo "$0 done." >&2
在运行之前,您需要使用GitHub令牌设置您的GITHUB_API_TOKEN
(请参见GH上的/settings/tokens
)。这可以放在您的~/.secrets
文件中,例如:
GITHUB_API_TOKEN=XXX
示例脚本用法:
./get_gh_asset.sh :owner :repo :tag :name
这里的 name 是你的文件名(或部分文件名)。在脚本前加上 TRACE=1
来进行调试。
如果你想知道为什么有时候使用 curl
会失败(如其他答案中所提到的):
Only one auth mechanism allowed; only the
X-Amz-Algorithm
query parameter, Signature query string parameter or theAuthorization
header should be specified.
运行以下命令时出现该错误:
curl -vLJ -H 'Authorization: token <token>' -H 'Accept: application/octet-stream' https://api.github.com/repos/:owner/:repo/releases/assets/<id>
这是因为您同时指定了多个机制,因此S3服务器不知道要使用哪一个,因此您必须只选择一个,例如:
X-Amz-Algorithm
查询参数X-Amz-Signature
)Authorization: token <token>
)application/octet-stream
时),因此curl
在请求标头中传递相同的凭据(您已指定),因此它们会发生冲突。因此,作为解决方法,您可以使用access_token
代替。jq
JSON 工具,则可以使用 ASSET_ID=$(echo "$response" | jq --arg name "$name" '.assets[] | select(.name == $name).id')
或类似的方式大大简化提取资产 ID 的过程。 - Max0.1.3
中的发行版资源 foo.exe
下载到 /tmp
,应执行以下操作:GITHUB_OAUTH_TOKEN="your token"
fetch --repo="https://github.com/foo/bar" --tag="0.1.3" --release-asset="foo.exe" /tmp
--github-oauth-token=${GITHUB_OAUTH_TOKEN}
标志。然后运行得非常出色。 - M. Rodo看起来这两种身份验证方法只适用于API端点。有一个API端点可用于下载发布资产(文档):
GET /repos/:owner/:repo/releases/assets/:id
但是,要做到这一点,人们需要知道资产的数字ID。 我向他们的支持团队询问是否可以添加一个API端点来按名称下载发布的资产(就像他们为tarballs提供的那样)。
更新:来自Github支持团队的回复:
我们不提供您建议的任何API。 我们试图避免脆弱的URL,如果发布资产的标签或文件名更改,它们将发生变化。 我会将您的反馈传达给团队进一步讨论。
https://github.com/company/repository/releases/download/TAG-NAME/A.tgz
,请使用以下命令:
gh release download --repo company/repository TAG-NAME -p 'A.tgz'
curl
和 jq
的一行命令:CURL="curl -H 'Authorization: token <auth_token>' \
https://api.github.com/repos/<owner>/<repo>/releases"; \
ASSET_ID=$(eval "$CURL/tags/<tag>" | jq .assets[0].id); \
eval "$CURL/assets/$ASSET_ID -LJOH 'Accept: application/octet-stream'"
将用<>
括起来的部分更改为您的数据。
要生成auth_token
,请前往github.com/settings/tokens
如果您想使用密码登录,请使用此选项(请注意,它会要求您输入两次密码):
CURL="curl -u <github_user> https://api.github.com/repos/<owner>/<repo>/releases"; \
ASSET_ID=$(eval "$CURL/tags/<tag>" | jq .assets[0].id); \
eval "$CURL/assets/$ASSET_ID -LJOH 'Accept: application/octet-stream'"
tags/<tag>
替换为 latest
以获取最新版本的发布。 - Miguel/latest
,即 "$CURL/latest"
。 - fooquency.assets
数组中的第一项。但事实可能并非如此。这就是为什么其他人使用jq
和select()
来搜索正确的.name
的原因。 - Cliffcurl
将身份验证标头转发到存储Github发布资产的AmazonS3存储桶中的请求中。
来自S3的错误响应:<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidArgument</Code>
<Message>
Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified
</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>token <yourtoken> </ArgumentValue><RequestId>4BEDDBA630688865</RequestId> <HostId>SXLsRKgKM6tPa/K7g7tSOWmQEqowG/4kf6cwOmnpObXrSzUt4bzOFuihmzxK6+gx</HostId>
</Error>
wget --auth-no-challenge --header='Accept:application/octet-stream' https://<token>:@api.github.com/repos/:owner/:repo/releases/assets/:id -O app.zip
尝试执行以下命令:curl -i -H "Authorization: token <token>" -H "Accept:application/octet-stream" https://<token>:@api.github.com/repos/:owner/:repo/releases/assets/:id
,以获取更多详细信息。如果想要查看S3错误消息,请添加-L
参数。
<token>
吗?如果这是一个愚蠢的问题,我很抱歉。 - Dominic Sayers以下是一个使用wget
进行HTTP请求并使用python
进行JSON解析的"一行代码":
(export AUTH_TOKEN=<oauth-token>; \
export ASSET_ID=$(wget -O - https://api.github.com/repos/<owner>/<repo>/releases/tags/<tag>?access_token=$AUTH_TOKEN | python -c 'import sys, json; print json.load(sys.stdin)["assets"][0]["id"]'); \
wget --header='Accept:application/octet-stream' -O <download-name> https://api.github.com/repos/<owner>/<repo>/releases/assets/$ASSET_ID?access_token=$AUTH_TOKEN)
<oauth-token>
、<owner>
、<repo>
、<tag>
和<download-name>
替换为适当的值。export AUTH_TOKEN=<oauth-token>
)设置了GitHub OAuth令牌,该令牌由后续的wget
命令使用。
- 第二条语句有两部分:
- wget -O - https://api.github.com/repos/<owner>/<repo>/releases/tags/<tag>?access_token=$AUTH_TOKEN
部分获取了GitHub发布信息的标签名称,并将其打印在stdout上。
- python -c 'import sys, json; print json.load(sys.stdin)["assets"][0]["id"]'
部分从stdin解析JSON并提取第一个发布资产的id
。
- 第三条语句(wget --header='Accept:application/octet-stream' -O <tarball-name>.tar.gz https://api.github.com/repos/<owner>/<repo>/releases/assets/$ASSET_ID?access_token=$AUTH_TOKEN
)通过id获取单个GitHub发布资产并将其存储到文件中。
- 外部括号创建了一个子shell,并确保导出的环境变量在之后被丢弃。machine api.github.com
login yourusername
password yourpassword
然后使用curl -n选项来使用.netrc文件:
curl -L -O -J -n -H "Accept:application/octet-stream" https://api.github.com/repos/:owner/:repo/releases/assets/:id
.netrc
文件中。潜在的黑客可以利用这一点来获取对GitHub上所有用户私有存储库的完全访问权限。 - pfrenssen像 @dwayne 一样,我使用了 gh CLI 来解决这个问题,你也需要安装。因为我在 Docker 容器中,所以我需要安装 curl
、dirmngr
,然后安装 gh
CLI 并按以下方式下载发布版。下面还展示了如何使用个人令牌对 gh CLI 进行身份验证,并解压缩发布文件(在我的情况下是一个 tarball)。
FROM debian:10.9 as base
RUN apt update \
# Install package dependencies
&& apt install -y \
build-essential \
wget \
dirmngr \
curl
# Install GH CLI - see https://github.com/cli/cli/blob/trunk/docs/install_linux.md
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
apt update && \
apt install -y gh
# auth to github with PAT and download release
ARG RELEASE_TOKEN
RUN echo $RELEASE_TOKEN | gh auth login --with-token && \
cd /opt && \
gh release download YOUR_TAG_HERE --repo https://github.com/SOME_ORG/SOME-REPO && \
tar -xjf SOME-RELEASE-FILES.tar.bz2 -C /opt && \
rm SOME-RELEASE-FILES.tar.bz2
只使用curl的一行方式来完成这个操作,其中:
# YOUR_TOKEN = your access token e.g. ghp_xxxxxxxxxxxxx
# YOUR_GITHUBCOM_URL = the portion of the URL that comes after https://github.com/ e.g. myuser/myrepo/assets/127345322/d0ad7915-a6a3-4aef-adf7-369c95e13316
# YOUR_DESTINATION = the location on your local drive to save the result to e.g. /tmp/x.png
curl "$(TOKEN=YOUR_TOKEN GITHUBCOM_URL=YOUR_GITHUBCOM_URL && curl -i -H "Authorization: token $TOKEN" https://github.com/$GITHUBCOM_URL | grep '^location: ' | sed 's/location: //' | tr -d '\r' )" > YOUR_DESTINATION
在MacOS上进行测试
解释:
curl
使用您的令牌从github.com获取元数据,其中包含一个包含要获取的实际内容的已签名URLlocation:
开头的行location:
前缀和结尾的\r
后缀,只保留URLcurl
使用该URL检索资源
gh release download ...
- https://cli.github.com - Vladimir Vukanac