All checks were successful
Build, test and publish / verify (push) Successful in 1m41s
68 lines
2.9 KiB
Python
68 lines
2.9 KiB
Python
#!/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)
|