Skip to content

Instantly share code, notes, and snippets.

@Konstantin-Dudersky
Created September 6, 2022 12:02
Show Gist options
  • Save Konstantin-Dudersky/c10cb07339fa16c6c5456587a35fbd3f to your computer and use it in GitHub Desktop.
Save Konstantin-Dudersky/c10cb07339fa16c6c5456587a35fbd3f to your computer and use it in GitHub Desktop.
"""Class for GitHub API."""
import json
import mimetypes
import requests
from logger_setup import LoggerLevel, get_logger
from semantic_versioning import SemanticVersioning
logger = get_logger(__name__)
logger.setLevel(LoggerLevel.INFO)
BASE_URL = 'https://api.github.com'
BASE_URL_UPLOAD = 'https://uploads.github.com'
def parse_version(version: str) -> tuple[int, ...]:
"""Parse version.
Version must be: vMINOR.MAJOR.PATCH
"""
parts = version.lstrip('v').split('.')
return tuple(int(part) for part in parts)
class GithubApi:
"""Class for GitHub API."""
def __init__(
self: 'GithubApi',
owner: str,
repo: str,
token: str,
) -> None:
"""Constructor for GithubApi."""
self.owner = owner
self.repo = repo
self.token = token
self.headers = {
'Authorization': f'token {token}',
'Accept': 'application/vnd.github.v3+json',
}
# -------------------------------------------------------------------------
# Releases
def get_latest_release_tag_name(self: 'GithubApi') -> str:
"""Tag for latest release."""
url = f'{BASE_URL}/repos/{self.owner}/{self.repo}/releases/latest'
response = requests.get(
url=url,
headers=self.headers,
)
if response.status_code == 404:
return 'v0.0.0'
if response.status_code != 200:
logger.error(response.text)
raise requests.exceptions.RequestException
return response.json()['tag_name']
def create_release(
self: 'GithubApi',
tag_name: tuple[int, int, int],
) -> int:
"""Create a release.
:param tag_name: Required. The name of the tag.
:return: release id
"""
url = f'{BASE_URL}/repos/{self.owner}/{self.repo}/releases'
data = {
'tag_name': f'v{tag_name[0]}.{tag_name[1]}.{tag_name[2]}',
}
response = requests.post(
url=url,
data=json.dumps(data),
headers=self.headers,
)
if response.status_code != 201:
logger.error(response.text)
raise requests.exceptions.RequestException
return response.json()['id']
def upload_release_asset(
self: 'GithubApi',
release_id: int,
filename: str,
) -> None:
"""Upload a release asset."""
url = (
f'{BASE_URL_UPLOAD}/repos/{self.owner}/{self.repo}/'
f'releases/{release_id}/assets'
)
headers = self.headers.copy()
headers['Content-Type'] = mimetypes.guess_type(filename)[0]
params = {
'name': filename.split('/')[-1],
}
response = requests.post(
url=url,
data=open(filename, 'rb').read(),
headers=headers,
params=params,
)
if response.status_code != 201:
logger.error(response.text)
raise requests.exceptions.RequestException
return
if __name__ == '__main__':
TOKEN = '' # specify token
github = GithubApi(
owner='inosat-automation',
repo='cocacola-resourcesmgmt',
token=TOKEN,
)
version = github.get_latest_release_tag_name()
sv = SemanticVersioning(*parse_version(version))
release_id = github.create_release(sv.new_patch())
github.upload_release_asset(
release_id=release_id,
filename='attachments/resourcesmgmt-front.zip',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment