如何通过GitHub API/CLI上传制品?不用upload-artifact action,用Python脚本
自定义Python脚本实现GitHub制品上传与下载
为什么REST文档中没有直接的「上传制品」方法?
GitHub的制品上传并非通过单一REST接口完成,而是分元数据创建和文件上传两个阶段:
- 先调用接口创建制品的元记录(名称、过期时间等),GitHub会返回一个预签名的上传URL;
- 再通过这个预签名URL将文件上传到GitHub的存储系统。
官方REST文档里的Actions Artifacts接口仅负责制品元数据的管理(创建、查询、删除等),实际文件上传是通过返回的预签名URL完成,所以你不会在文档里看到单独的「上传制品」接口。
使用REST API上传制品
步骤1:创建制品元数据,获取上传URL
调用POST /repos/{owner}/{repo}/actions/artifacts接口,生成制品记录并拿到上传地址:
import requests # 配置参数 GITHUB_TOKEN = "你的个人访问令牌(需具备repo权限)" OWNER = "用户名/组织名" REPO_NAME = "目标仓库名" ARTIFACT_NAME = "my-build-artifact" EXPIRE_DAYS = 7 # 最大支持90天 headers = { "Authorization": f"token {GITHUB_TOKEN}", "Accept": "application/vnd.github+json" } payload = { "name": ARTIFACT_NAME, "expires_in": EXPIRE_DAYS } # 发送请求创建制品元数据 response = requests.post( f"https://api.github.com/repos/{OWNER}/{REPO_NAME}/actions/artifacts", headers=headers, json=payload ) response.raise_for_status() # 捕获请求错误 upload_url = response.json()["upload_url"]
步骤2:上传文件到预签名URL
拿到upload_url后,通过PUT请求上传文件,注意匹配文件的Content-Type:
import os FILE_PATH = "./build/output.zip" with open(FILE_PATH, "rb") as file: upload_response = requests.put( upload_url, data=file, headers={"Content-Type": "application/zip"} # 非压缩文件需调整类型 ) upload_response.raise_for_status() print(f"制品上传成功,状态码: {upload_response.status_code}")
使用GitHub CLI上传制品
GitHub CLI的gh artifact upload命令封装了两步流程,无需手动处理接口调用,更简便:
gh artifact upload "my-build-artifact" --repo OWNER/REPO_NAME --expires-in 7d ./build/output.zip
如果要在Python脚本中调用,可使用subprocess模块:
import subprocess subprocess.run([ "gh", "artifact", "upload", ARTIFACT_NAME, "--repo", f"{OWNER}/{REPO_NAME}", "--expires-in", f"{EXPIRE_DAYS}d", FILE_PATH ], check=True)
注意:需提前通过gh auth login完成CLI的身份验证。
制品下载实现
用REST API下载
调用GET /repos/{OWNER}/{REPO_NAME}/actions/artifacts/{ARTIFACT_ID}/zip接口获取制品压缩包:
ARTIFACT_ID = "1234567" # 可通过GET /repos/{OWNER}/{REPO_NAME}/actions/artifacts查询所有制品ID download_response = requests.get( f"https://api.github.com/repos/{OWNER}/{REPO_NAME}/actions/artifacts/{ARTIFACT_ID}/zip", headers=headers ) download_response.raise_for_status() with open("./downloaded-artifact.zip", "wb") as file: file.write(download_response.content)
用GitHub CLI下载
gh artifact download "my-build-artifact" --repo OWNER/REPO_NAME --output ./downloads/
Python脚本调用示例:
subprocess.run([ "gh", "artifact", "download", ARTIFACT_NAME, "--repo", f"{OWNER}/{REPO_NAME}", "--output", "./downloads/" ], check=True)
内容的提问来源于stack exchange,提问作者red888
相关产品推荐
相关产品推荐

