set_github_secret.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. '''
  4. @Contact : liuyuqi.gov@msn.cn
  5. @Time : 2023/11/13 14:29:00
  6. @License : Copyright © 2017-2022 liuyuqi. All Rights Reserved.
  7. @Desc : github api方式设置 Create or update a repository secret
  8. '''
  9. import requests
  10. import nacl.secret
  11. from nacl.encoding import Base64Encoder
  12. import json
  13. class GithubPulbicKey:
  14. ''' Github public key '''
  15. def __init__(self, key_id: str, key: str):
  16. self.key_id = key_id
  17. self.key = key
  18. class GithubApi:
  19. ''' Github api '''
  20. _api_url = 'https://api.github.com'
  21. def __init__(self, owner: str, token: str, repo: str):
  22. self.owner = owner
  23. self.token = token
  24. self.repo = repo
  25. self.public_key = None
  26. self.sess = requests.Session()
  27. self.sess.headers.update({
  28. 'Accept': 'application/vnd.github.v3+json',
  29. 'X-GitHub-Api-Version': '2022-11-28',
  30. 'Authorization': f'Bearer {self.token}'
  31. })
  32. def get_repo_public_key(self) -> GithubPulbicKey:
  33. ''' Get a repository public key
  34. {
  35. "key_id": "012345678912345678",
  36. "key": "xx+dB7TJyvv1234"
  37. }
  38. '''
  39. url = f'{self._api_url}/repos/{self.owner}/{self.repo}/actions/secrets/public-key'
  40. response = self.sess.get(url)
  41. print(f'get public key response: {response.text}')
  42. if response.status_code == 200:
  43. res_json = response.json()
  44. self.public_key = GithubPulbicKey(
  45. res_json['key_id'], res_json['key'])
  46. return self.public_key
  47. else:
  48. print("Failed to get repository public key.")
  49. print(f"Response status code: {response.status_code}")
  50. print(f"Response body: {response.text}")
  51. return None
  52. def encrypt_secret_value(self, value: str, public_key: str):
  53. ''' Value for your secret, encrypted with LibSodium using the public key retrieved from
  54. the Get a repository public key endpoint.
  55. '''
  56. key_bytes = Base64Encoder.decode(public_key)
  57. box = nacl.secret.SecretBox(key_bytes)
  58. encrypted = box.encrypt(value.encode(), encoder=Base64Encoder).decode()
  59. print(f'encrypt value: {value} -> {encrypted} success.')
  60. return encrypted
  61. def set_update_github_secret(self, key: str, value: str):
  62. url = f'{self._api_url}/repos/{self.owner}/{self.repo}/actions/secrets/{key}'
  63. if self.public_key is None:
  64. self.get_repo_public_key()
  65. if self.public_key is not None:
  66. secret_value = self.encrypt_secret_value(
  67. value, self.public_key.key)
  68. data = {
  69. 'encrypted_value': secret_value,
  70. 'key_id': self.public_key.key_id
  71. }
  72. response = self.sess.put(url, json=data)
  73. if response.status_code == 204:
  74. print("GitHub secret updated successfully!")
  75. else:
  76. print("Failed to update GitHub secret.")
  77. print(f"Response status code: {response.status_code}")
  78. print(f"Response body: {response.text}")
  79. if __name__ == '__main__':
  80. with open("account.json", "r") as file:
  81. data = json.load(file)
  82. owner = data["owner"]
  83. token = data["token"]
  84. repo = data["repo"]
  85. github_api = GithubApi(owner=owner, token=token, repo=repo)
  86. for i in range(data["secret"]):
  87. key = i["key"]
  88. value = i["value"]
  89. github_api.set_update_github_secret(key, value)