通过GitHub REST API创建的环境Secrets在Workflow中返回为空
问题排查与修复方案
核心问题
你遇到的问题根源是Python代码中错误地将GitHub Actions的模板语法硬编码为字符串,导致API请求使用了无效的占位符参数,进而创建的Secrets无法被正确解密,最终在Workflow中返回空值。手动更新时GitHub会用正确的密钥重新加密,所以能正常读取。
具体错误点分析
API请求URL和请求体中的占位符未替换
你的代码里直接把${{ steps.repos.outputs.repos_id }}和${{ steps.keys.outputs.key_id }}作为字符串写入请求,但这些是GitHub Actions的模板变量语法,Python脚本不会自动解析它们。这会导致:- 请求体中的
key_id是无效占位符,GitHub无法匹配到对应的公钥,导致加密的Secret无法被解密。 - 若代码在Actions环境中运行但未正确注入变量,URL中的仓库ID占位符也会导致请求逻辑异常。
- 请求体中的
加密流程的密钥不匹配
即使Secrets在GitHub后台显示,若加密时使用的key_id与仓库环境的有效公钥ID不匹配,GitHub无法正确解密Secret值,Workflow读取时自然返回空。
修复步骤
1. 传递正确的变量到Python脚本
如果代码在GitHub Actions中运行,需要将仓库ID和密钥ID作为环境变量传递给Python:
# 在GitHub Actions步骤中添加环境变量注入 - name: Execute secret creation script env: REPO_ID: ${{ steps.repos.outputs.repos_id }} KEY_ID: ${{ steps.keys.outputs.key_id }} run: python your_secret_script.py
2. 修改Python代码使用真实变量
在Python脚本中读取环境变量,并替换硬编码的占位符:
import os import requests # 读取环境变量中的真实值 repo_id = os.getenv("REPO_ID") key_id = os.getenv("KEY_ID") # 修正加密循环中的请求 for i in range(len(dev_secrets_list)): url = f"https://api.github.com/repositories/{repo_id}/environments/{environnments['dev']}/secrets/{dev_secrets_names[i]}" body = {"encrypted_value": dev_encrypted_secrets_list[i], "key_id": key_id} response = requests.put(url, json=body, auth=(user, access_token)) # 可选:验证请求响应,排查异常 if response.status_code not in (201, 204): print(f"Failed to create secret {dev_secrets_names[i]}: {response.text}")
3. 验证加密流程正确性
确保加密使用的公钥是从对应仓库环境的API获取的:
- 通过
GET /repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key获取环境的公钥和key_id - 加密时必须使用该公钥,且请求体中的
key_id与返回的key_id完全一致
额外排查点
- 检查API请求的响应状态码:成功创建Secret时应返回
201 Created或204 No Content,若返回其他状态码,打印response.text查看错误详情 - 确认访问令牌(
access_token)拥有足够权限:需要repo(私有仓库)或public_repo(公共仓库)权限,且有权限管理目标环境的Secrets
内容的提问来源于stack exchange,提问作者samy KHEZNADJI
相关产品推荐
相关产品推荐

