如何在GitHub Workflow中提取Release资产的下载URL?
解决GitHub Workflow中提取Release资产下载URL的问题
问题背景
我在GitHub Workflow中使用octokit/request-action通过标签获取Release信息,步骤如下:
- name: Get Release Info uses: octokit/request-action@v2.x id: release with: route: GET /repos/{org_repo}/releases/tags/{tag}
返回的JSON响应包含Release的资产信息(精简示例):
{ "url": "https://api.github.com/repos/octocat/Hello-World/releases/1", "id": 1, "assets": [ { "url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/1", "browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example1.zip", "id": 1 }, { "url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/2", "browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example2.zip", "id": 2 } ] }
需要提取assets数组中所有browser_download_url的值,传递给Python脚本discord_notification.py,期望调用形式:
python discord_notification.py "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example1.zip" "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example2.zip"
若Workflow中直接实现有难度,也可接受将JSON传递给Python脚本解析的方案,避免Bash传递多行字符串的复杂度。
方案一:在Workflow中直接提取URL并传递
利用GitHub托管runner默认安装的jq工具,从octokit/request-action的输出里提取所有browser_download_url,格式化为Shell安全的带引号参数:
- name: Extract Download URLs id: extract_urls run: | # 用jq遍历assets数组,提取每个browser_download_url并添加Shell安全引号 DOWNLOAD_URLS=$(echo "${{ steps.release.outputs.data }}" | jq -r '.assets[] | @sh') # 将处理后的URL列表存入步骤输出 echo "urls=$DOWNLOAD_URLS" >> "$GITHUB_OUTPUT" - name: Run Discord Notification Script run: | python discord_notification.py ${{ steps.extract_urls.outputs.urls }}
jq -r '.assets[] | @sh'会自动处理URL中的特殊字符,确保每个URL都被正确包裹在引号中,避免Shell解析出错。
方案二:将JSON传递给Python脚本解析
如果不想处理Shell层面的字符串转义问题,直接把完整的Release JSON传递给Python脚本,由脚本内部解析提取URL:
Workflow步骤
- name: Run Discord Notification Script env: RELEASE_DATA: ${{ steps.release.outputs.data }} run: | python discord_notification.py "$RELEASE_DATA"
Python脚本示例(discord_notification.py)
import json import sys def main(): # 获取传入的JSON字符串 release_json = sys.argv[1] release_data = json.loads(release_json) # 提取所有资产的下载URL download_urls = [asset['browser_download_url'] for asset in release_data['assets']] # 这里添加构建Discord通知的逻辑,比如调用Discord API发送消息 print("待通知的下载URL:", download_urls) if __name__ == "__main__": main()
通过环境变量传递JSON数据,既避免了命令行参数的长度限制,也无需处理复杂的字符串转义,Python解析JSON的方式更安全可靠。
内容的提问来源于stack exchange,提问作者void.pointer
相关产品推荐
相关产品推荐

