Move ClaudeChecker builds and updates to Gitea
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Publish a completed main build, then advance its update channel."""
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self, *args, **kwargs):
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
version = os.environ['VERSION']
|
||||
channel = os.environ['CHANNEL']
|
||||
if channel not in ('stable', 'beta', 'windows-beta', 'windows-stable'):
|
||||
raise ValueError('Unknown release channel')
|
||||
if not re.fullmatch(r'\d+\.\d+\.\d+(-beta\.\d+)?', version):
|
||||
raise ValueError('Invalid release version')
|
||||
if ('beta' in channel) != ('-beta.' in version):
|
||||
raise ValueError('Version must match release channel')
|
||||
if os.environ.get('GITHUB_REF') != 'refs/heads/main':
|
||||
raise ValueError('Releases must build from main')
|
||||
revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip()
|
||||
windows = channel.startswith('windows-')
|
||||
tag = ('win-v' if windows else 'v') + version
|
||||
artifact = Path('ClaudeChecker-Installer.exe' if windows else 'ClaudeChecker.zip')
|
||||
notes = Path('windows/RELEASE_NOTES.md' if windows else 'RELEASE_NOTES.md').read_text()
|
||||
feed = {'stable': 'version.json', 'beta': 'version-beta.json',
|
||||
'windows-beta': 'version-windows-beta.json', 'windows-stable': 'version-windows.json'}[channel]
|
||||
server = os.environ['GITHUB_SERVER_URL'].rstrip('/')
|
||||
repo = os.environ['GITHUB_REPOSITORY']
|
||||
opener = urllib.request.build_opener(NoRedirect)
|
||||
|
||||
def api(path, method='GET', data=None, binary=False):
|
||||
body = data if binary else (json.dumps(data).encode() if data is not None else None)
|
||||
request = urllib.request.Request(f'{server}/api/v1/repos/{repo}{path}', data=body, method=method,
|
||||
headers={'Authorization': 'token ' + os.environ['GITEA_TOKEN'],
|
||||
'Content-Type': 'application/octet-stream' if binary else 'application/json'})
|
||||
with opener.open(request, timeout=600) as response:
|
||||
return json.load(response)
|
||||
|
||||
# Never replace an existing release or advertise a partially uploaded asset.
|
||||
release = api('/releases', 'POST', {'tag_name': tag, 'target_commitish': revision,
|
||||
'name': tag, 'body': notes + '\n\nBuilt from main: ' + revision,
|
||||
'draft': True, 'prerelease': 'beta' in channel})
|
||||
asset = api(f"/releases/{release['id']}/assets?name={urllib.parse.quote(artifact.name)}",
|
||||
'POST', artifact.read_bytes(), binary=True)
|
||||
if asset['size'] != artifact.stat().st_size:
|
||||
raise ValueError('Uploaded asset size mismatch')
|
||||
api(f"/releases/{release['id']}", 'PATCH', {'draft': False})
|
||||
content = json.dumps({'version': version,
|
||||
'url': f'https://git.jamesbone.net/{repo}/releases/download/{tag}/{artifact.name}',
|
||||
'notes': notes}, indent=2) + '\n'
|
||||
try:
|
||||
current = api(f'/contents/{feed}?ref=main')
|
||||
except urllib.error.HTTPError as error:
|
||||
if error.code != 404:
|
||||
raise
|
||||
current = None
|
||||
payload = {'branch': 'main', 'message': f'Update {channel} feed to {tag}',
|
||||
'content': base64.b64encode(content.encode()).decode()}
|
||||
if current:
|
||||
payload['sha'] = current['sha']
|
||||
api(f'/contents/{feed}', 'PUT' if current else 'POST', payload)
|
||||
print(f'Published {tag} and {feed} from {revision}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user