如何使用命令行从私人仓库下载GitHub版本

时间:2013-12-05 09:36:53

标签: command-line github

GitHub guide解释了2种授权方式,但看起来没有使用Release文件。

由于:

curl -u 'username' -L -o a.tgz https://github.com/company/repository/releases/download/TAG-NAME/A.tgz

总有类似

的东西

<!DOCTYPE html> <!-- Hello future GitHubber! ...

8 个答案:

答案 0 :(得分:32)

要从私人仓库下载发布文件,您可以使用个人访问令牌,该令牌可以在settings/tokens生成,完全控制私有存储库范围。

然后使用curl命令下载资产(使用适当的值进行更改):

curl -vLJO -H 'Accept: application/octet-stream' 'https://api.github.com/repos/:owner/:repo/releases/assets/:id?access_token=:token'

其中:

  • :owner是您的用户或组织用户名;
  • :repo是您的存储库名称;
  • :id是您的资产ID,可以在代码发布网址中找到,例如:

    https://api.github.com/repos/:owner/:repo/releases/tags/:tag 
    
  • :token是您的个人访问令牌(可以在/settings/tokens创建;

请参阅:Repositories API v3 at GitHub

这是Bash脚本,它可以下载给定文件名的资产文件:

#!/usr/bin/env bash
# Script to download asset file from tag release using GitHub API v3.
# See: http://stackoverflow.com/a/35688093/55075    
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 'Accept: application/octet-stream' "$GH_ASSET?access_token=$GITHUB_API_TOKEN"
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有时会失败(如其他答案所述):

  

只允许一种身份验证机制;只应指定X-Amz-Algorithm查询参数,签名查询字符串参数或Authorization标题。

跑步时:

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>

并且由于GitHub会从资产页面重定向您(在请求application/octet-stream时),它会自动在查询字符串中填充凭据,并且curl正在通过请求标头中的相同凭据(您已经过了因此,他们是冲突的。因此,对于变通方法,您可以使用access_token代替。

答案 1 :(得分:9)

似乎两种身份验证方法仅适用于API端点。 有一个用于下载发布资产的API端点(docu):

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

但是需要知道资产的数字ID。 我询问他们是否可以添加API端点以按名称下载发布资产(就像它们用于tarball一样)。


更新:来自Github支持的回复:

  

我们不提供您建议的任何API。我们尝试避免在发布资产的标记或文件名发生更改时会发生变化的脆弱URL。我会将您的反馈意见带给团队进一步讨论。

答案 2 :(得分:7)

我们必须经常从私有GitHub repos下载发布资产,因此我们创建了fetch,这是一个开源的跨平台工具,可以轻松下载源文件并从git标签中释放资产公共和私人GitHub回购,提交或分支。

例如,要将版本资产ActionListener从私有GitHub存储库的foo.exe版下载到0.1.3,您可以执行以下操作:

/tmp

答案 3 :(得分:5)

我在这条评论中找到了答案:https://github.com/request/request/pull/1058#issuecomment-55285276

curl将请求中的身份验证标头转发到存储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解决方案:

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,了解更多详情。添加-L以查看S3错误消息。

答案 4 :(得分:4)

以下是使用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>)设置后续wget命令使用的GitHub OAuth token
  • 第二个陈述分为两部分:
    1. wget -O - https://api.github.com/repos/<owner>/<repo>/releases/tags/<tag>?access_token=$AUTH_TOKEN部分gets GitHub release information from a tag name并将其打印在 stdout 上。
    2. 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)gets a single GitHub release asset by id并将其存储到文件中。
  • 外括号创建一个子shell,并确保之后丢弃导出的环境变量。

答案 5 :(得分:3)

更简单的解决方案是使用.netrc来存储凭据。这样,curl不会将凭据转发到Amazon S3 Bucket

machine api.github.com login yourusername password yourpassword 文件中(应使用0600文件权限创建):

curl -L -O -J -n -H "Accept:application/octet-stream" https://api.github.com/repos/:owner/:repo/releases/assets/:id

然后使用curl -n选项使用.netrc:

{{1}}

答案 6 :(得分:3)

这里是$page = simplexml_load_file('data/data.xml'); $dims = $page->xpath('/users/user[not(@name=preceding-sibling::user/@name)]/@name'); jq之一;)衬里:

curl

更改数据中用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'" 包围的部分。 要生成<>,请转到github.com/settings/tokens

如果您想使用密码登录,请使用此命令(请注意,它将两次要求输入密码):

auth_token

答案 7 :(得分:0)

使用 gh release download 轻松编写下载脚本。 gh auth login 先授权。

因此要下载示例 URL https://github.com/company/repository/releases/download/TAG-NAME/A.tgz,请使用:

gh release download --repo company/repository TAG-NAME -p 'A.tgz'