|
@@ -0,0 +1,102 @@
|
|
|
|
+#!/usr/bin/env python
|
|
|
|
+# -*- encoding: utf-8 -*-
|
|
|
|
+'''
|
|
|
|
+@Contact : liuyuqi.gov@msn.cn
|
|
|
|
+@Time : 2023/11/13 14:29:00
|
|
|
|
+@License : Copyright © 2017-2022 liuyuqi. All Rights Reserved.
|
|
|
|
+@Desc : github api方式设置 Create or update a repository secret
|
|
|
|
+'''
|
|
|
|
+
|
|
|
|
+import requests
|
|
|
|
+import nacl.secret
|
|
|
|
+from nacl.encoding import Base64Encoder
|
|
|
|
+import json
|
|
|
|
+
|
|
|
|
+class GithubPulbicKey:
|
|
|
|
+ ''' Github public key '''
|
|
|
|
+
|
|
|
|
+ def __init__(self, key_id: str, key: str):
|
|
|
|
+ self.key_id = key_id
|
|
|
|
+ self.key = key
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class GithubApi:
|
|
|
|
+ ''' Github api '''
|
|
|
|
+
|
|
|
|
+ _api_url = 'https://api.github.com'
|
|
|
|
+
|
|
|
|
+ def __init__(self, owner: str, token: str, repo: str):
|
|
|
|
+ self.owner = owner
|
|
|
|
+ self.token = token
|
|
|
|
+ self.repo = repo
|
|
|
|
+ self.public_key = None
|
|
|
|
+ self.sess = requests.Session()
|
|
|
|
+ self.sess.headers.update({
|
|
|
|
+ 'Accept': 'application/vnd.github.v3+json',
|
|
|
|
+ 'X-GitHub-Api-Version': '2022-11-28',
|
|
|
|
+ 'Authorization': f'Bearer {self.token}'
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ def get_repo_public_key(self) -> GithubPulbicKey:
|
|
|
|
+ ''' Get a repository public key
|
|
|
|
+ {
|
|
|
|
+ "key_id": "012345678912345678",
|
|
|
|
+ "key": "xx+dB7TJyvv1234"
|
|
|
|
+ }
|
|
|
|
+ '''
|
|
|
|
+ url = f'{self._api_url}/repos/{self.owner}/{self.repo}/actions/secrets/public-key'
|
|
|
|
+ response = self.sess.get(url)
|
|
|
|
+ print(f'get public key response: {response.text}')
|
|
|
|
+ if response.status_code == 200:
|
|
|
|
+ res_json = response.json()
|
|
|
|
+ self.public_key = GithubPulbicKey(
|
|
|
|
+ res_json['key_id'], res_json['key'])
|
|
|
|
+ return self.public_key
|
|
|
|
+ else:
|
|
|
|
+ print("Failed to get repository public key.")
|
|
|
|
+ print(f"Response status code: {response.status_code}")
|
|
|
|
+ print(f"Response body: {response.text}")
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ def encrypt_secret_value(self, value: str, public_key: str):
|
|
|
|
+ ''' Value for your secret, encrypted with LibSodium using the public key retrieved from
|
|
|
|
+ the Get a repository public key endpoint.
|
|
|
|
+ '''
|
|
|
|
+ key_bytes = Base64Encoder.decode(public_key)
|
|
|
|
+ box = nacl.secret.SecretBox(key_bytes)
|
|
|
|
+ encrypted = box.encrypt(value.encode(), encoder=Base64Encoder).decode()
|
|
|
|
+ print(f'encrypt value: {value} -> {encrypted} success.')
|
|
|
|
+ return encrypted
|
|
|
|
+
|
|
|
|
+ def set_update_github_secret(self, key: str, value: str):
|
|
|
|
+ url = f'{self._api_url}/repos/{self.owner}/{self.repo}/actions/secrets/{key}'
|
|
|
|
+ if self.public_key is None:
|
|
|
|
+ self.get_repo_public_key()
|
|
|
|
+
|
|
|
|
+ if self.public_key is not None:
|
|
|
|
+ secret_value = self.encrypt_secret_value(
|
|
|
|
+ value, self.public_key.key)
|
|
|
|
+ data = {
|
|
|
|
+ 'encrypted_value': secret_value,
|
|
|
|
+ 'key_id': self.public_key.key_id
|
|
|
|
+ }
|
|
|
|
+ response = self.sess.put(url, json=data)
|
|
|
|
+ if response.status_code == 204:
|
|
|
|
+ print("GitHub secret updated successfully!")
|
|
|
|
+ else:
|
|
|
|
+ print("Failed to update GitHub secret.")
|
|
|
|
+ print(f"Response status code: {response.status_code}")
|
|
|
|
+ print(f"Response body: {response.text}")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+if __name__ == '__main__':
|
|
|
|
+ with open("account.json", "r") as file:
|
|
|
|
+ data = json.load(file)
|
|
|
|
+ owner = data["owner"]
|
|
|
|
+ token = data["token"]
|
|
|
|
+ repo = data["repo"]
|
|
|
|
+ github_api = GithubApi(owner=owner, token=token, repo=repo)
|
|
|
|
+ for i in range(data["secret"]):
|
|
|
|
+ key = i["key"]
|
|
|
|
+ value = i["value"]
|
|
|
|
+ github_api.set_update_github_secret(key, value)
|