#!/usr/bin/env python3 from typing import Any, Dict, List, Optional, Tuple import os import sys import json import urllib.request import http.client from urllib.error import HTTPError def read_changelog(tag: str) -> Optional[str]: with open('.changes', 'r') as f: return f.read() def fetch_job_ids(project_id: int, pipeline_id: int, api_token: str) -> Dict[str, str]: url: str = f'https://gitlab.com/api/v4/projects/{project_id}/pipelines/{pipeline_id}/jobs' headers: Dict[str, str] = { 'Private-Token': api_token, 'User-Agent': 'curl/7.70.0' } req = urllib.request.Request(url, headers=headers) try: resp: http.client.HTTPResponse = urllib.request.urlopen(req) except HTTPError as e: print(e.read().decode()) sys.exit(1) resp_data: bytes = resp.read() joblist: List[Dict[str, Any]] = json.loads(resp_data.decode()) jobidmap: Dict[str, str] = {} for job in joblist: name: str = job['name'] job_id: str = job['id'] jobidmap[name] = job_id return jobidmap def fetch_binary_url(base_url: str, job_ids: Dict[str, str]) -> Optional[Tuple[str, str]]: mybase: str = f'{base_url}/jobs/{job_ids["compile"]}/artifacts/raw' binary_url: str = f'{mybase}/{wheel_filename}' return binary_url def main(): api_token: Optional[str] = os.getenv('GITLAB_API_TOKEN') release_tag: Optional[str] = os.getenv('CI_COMMIT_TAG') project_name: Optional[str] = os.getenv('CI_PROJECT_PATH') project_id: Optional[str] = os.getenv('CI_PROJECT_ID') pipeline_id: Optional[str] = os.getenv('CI_PIPELINE_ID') if api_token is None: print('GITLAB_API_TOKEN is not set.', file=sys.stderr) sys.exit(1) if release_tag is None: print('CI_COMMIT_TAG is not set.', file=sys.stderr) sys.exit(1) if project_name is None: print('CI_PROJECT_PATH is not set.', file=sys.stderr) sys.exit(1) if project_id is None: print('CI_PROJECT_ID is not set.', file=sys.stderr) sys.exit(1) if pipeline_id is None: print('CI_PIPELINE_ID is not set.', file=sys.stderr) sys.exit(1) changelog: Optional[str] = read_changelog(release_tag) if changelog is None: print('Changelog could not be parsed.', file=sys.stderr) sys.exit(1) job_ids: Dict[str, str] = fetch_job_ids(project_id, pipeline_id, api_token) base_url: str = f'https://gitlab.com/{project_name}/-' binary_url = fetch_wheel_url(base_url, job_ids) augmented_changelog = f'''{changelog.strip()} ### Download - [prometheus-dnssec-exporter]({binary_url}) ''' post_body: str = json.dumps({ 'tag_name': release_tag, 'description': augmented_changelog, 'assets': { 'links': [ { 'name': 'promtheus-dnssec-exporter', 'url': binary_url, 'link_type': 'package' } ] } }) gitlab_release_api_url: str = \ f'https://gitlab.com/api/v4/projects/{project_id}/releases' headers: Dict[str, str] = { 'Private-Token': api_token, 'Content-Type': 'application/json; charset=utf-8', 'User-Agent': 'curl/7.70.0' } request = urllib.request.Request( gitlab_release_api_url, post_body.encode('utf-8'), headers=headers, method='POST' ) try: response: http.client.HTTPResponse = urllib.request.urlopen(request) except HTTPError as e: print(e.read().decode()) sys.exit(1) response_bytes: bytes = response.read() response_str: str = response_bytes.decode() response_data: Dict[str, Any] = json.loads(response_str) if response_data['tag_name'] != release_tag: print('Something went wrong...', file=sys.stderr) print(response_str, file=sys.stderr) sys.exit(1) print(response_data['description']) if __name__ == '__main__': main()