#!/usr/bin/env python3 """Configure repository Actions through the Gitea API; read tokens from local files.""" import json import os from pathlib import Path import sys import urllib.error import urllib.request BASE = 'http://192.168.2.28:3000/api/v1/repos/wanjakrah/agiledancers' def read_secret(variable): path = Path(os.environ[variable]).expanduser() if path.stat().st_mode & 0o077: raise ValueError(f'{variable} must refer to a file readable only by its owner (chmod 600)') value = path.read_text().strip() if not value: raise ValueError(f'{variable} is empty') return value def main(): admin = read_secret('GITEA_ADMIN_TOKEN_FILE') registry = read_secret('REGISTRY_TOKEN_FILE') user = os.environ['REGISTRY_USER'] platform = os.environ['TARGET_PLATFORM'] if platform not in ('linux/amd64', 'linux/arm64'): raise ValueError('Set TARGET_PLATFORM from the verified Synology architecture') def api(method, path, body): request = urllib.request.Request(BASE + path, method=method, data=json.dumps(body).encode() if body is not None else None, headers={ 'Authorization': 'token ' + admin, 'Content-Type': 'application/json'}) with urllib.request.urlopen(request, timeout=30) as response: data = response.read() return json.loads(data) if data else None api('PATCH', '', {'has_actions': True}) for name, value in [('REGISTRY_USER', user), ('REGISTRY_TOKEN', registry)]: api('PUT', '/actions/secrets/' + name, {'data': value}) try: api('GET', '/actions/variables/TARGET_PLATFORM', None) except urllib.error.HTTPError as error: if error.code != 404: raise api('POST', '/actions/variables/TARGET_PLATFORM', {'value': platform}) else: api('PUT', '/actions/variables/TARGET_PLATFORM', {'value': platform}) # Store registration credentials outside Git; never print API responses/tokens. result = api('POST', '/actions/runners/registration-token', None) token_path = Path.home() / '.config/agiledancers-runner/registration-token' token_path.parent.mkdir(mode=0o700, parents=True, exist_ok=True) fd = os.open(token_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) os.fchmod(fd, 0o600) with os.fdopen(fd, 'w') as output: output.write(result['token']) print('Actions, registry secrets and target platform configured; runner token saved outside Git.') if __name__ == '__main__': try: main() except urllib.error.HTTPError as error: print(f'Gitea configuration failed: HTTP {error.code}', file=sys.stderr) sys.exit(1) except (OSError, ValueError, KeyError, urllib.error.URLError) as error: # Do not include request bodies, headers, response bodies or token values. print(f'Gitea configuration failed ({type(error).__name__}); check local files and connection.', file=sys.stderr) sys.exit(1)