1import sys
2import re
3import json
4import base64
5import argparse
6import requests
7from urllib.parse import urlparse
8
9def process_github_release(url, token=None):
10 parsed = urlparse(url)
11 path_parts = parsed.path.strip('/').split('/')
12 if len(path_parts) < 5 or parsed.netloc != 'github.com':
13 raise ValueError("Invalid GitHub release URL format")
14 owner, repo, _, _, tag = path_parts[:5]
15 headers = {"Accept": "application/vnd.github.v3+json"}
16 if token:
17 headers["Authorization"] = f"Bearer {token}"
18 response = requests.get(
19 f"https://api.github.com/repos/{owner}/{repo}/releases/tags/{tag}",
20 headers=headers
21 )
22 if response.status_code != 200:
23 raise RuntimeError(f"Failed to fetch release info: {response.status_code} ({response.json().get('message')})")
24 release_data = response.json()
25 assets = release_data.get('assets', [])
26 result = {}
27 sha256_pattern = re.compile(r"^[a-fA-F0-9]{64}$")
28 for asset in assets:
29 if not asset['name'].endswith('.sha256'):
30 continue
31 download_url = asset['browser_download_url']
32 content_response = requests.get(download_url, headers=headers)
33 if content_response.status_code != 200:
34 raise RuntimeError(
35 f"Failed to download {asset['name']}: "
36 f"{content_response.status_code} {content_response.text}"
37 )
38 hex_hash = content_response.text.strip()
39 if not sha256_pattern.match(hex_hash):
40 raise ValueError(f"Invalid SHA256 format in {asset['name']}")
41 try:
42 byte_data = bytes.fromhex(hex_hash)
43 base64_hash = base64.b64encode(byte_data).decode('utf-8')
44 except Exception as e:
45 raise RuntimeError(f"Error processing {asset['name']}: {str(e)}")
46 filename = asset['name'][:-7]
47 result[filename] = f"sha256-{base64_hash}"
48 output_file = f"{repo}_{tag}_hashes.json"
49 with open(output_file, 'w', encoding='utf-8') as f:
50 json.dump(result, f, indent=2, ensure_ascii=False)
51 print(f"Successfully generated {output_file}")
52if __name__ == "__main__":
53 parser = argparse.ArgumentParser(description='Process GitHub release hashes')
54 parser.add_argument('url', help='GitHub release URL')
55 parser.add_argument('-t', '--token', help='GitHub API token (optional)')
56 args = parser.parse_args()
57 try:
58 process_github_release(args.url, args.token)
59 except Exception as e:
60 print(f"Error: {str(e)}")
61 sys.exit(1)