Files
MotorDriver.Research/ODrive-fw-v0.5.6/.github/actions/upload-release/private_release_api.py
T
2025-05-13 01:34:53 +03:00

75 lines
3.0 KiB
Python

import hashlib
import os
from odrive.api_client import ApiClient
from odrive.crypto import b64encode
class PrivateReleaseApi():
BASE_URL = '/releases'
@staticmethod
def get_content_key(path: str, commit_hash: str):
commit_hash_bytes = bytes.fromhex(commit_hash)
def _get_file_names(path: str, prefix: list):
with os.scandir(os.path.join(path, *prefix)) as it:
for entry in it:
if entry.is_file():
yield os.path.join(*prefix, entry.name)
else:
yield from _get_file_names(path, prefix + [entry.name])
filenames = sorted(_get_file_names(path, []))
dir_hasher = hashlib.sha256()
for filename in filenames:
with open(os.path.join(path, filename), 'rb') as fp:
content = fp.read()
# Calculate commit-invariant hash of the file content
# This means that if a new compile differs only by embedded commit hash,
# it is considered equal.
patched_content = content.replace(commit_hash_bytes, bytes(len(commit_hash_bytes)))
file_hasher = hashlib.sha256()
file_hasher.update(patched_content)
dir_hasher.update(filename.encode('utf-8'))
dir_hasher.update(file_hasher.digest())
return dir_hasher.digest()
def __init__(self, api_client: 'ApiClient'):
self._api_client = api_client
async def get_manifest(self, release_type: str, content_key: bytes):
outputs = await self._api_client.call('GET', PrivateReleaseApi.BASE_URL + '/' + release_type + '/manifest', inputs={
'content_key': b64encode(content_key),
})
return outputs
async def register_content(self, release_type: str, content_key: bytes, indicated_commit: str):
outputs = await self._api_client.call('PUT', PrivateReleaseApi.BASE_URL + '/' + release_type + '/content', inputs={
'content_key': b64encode(content_key),
'indicated_commit': indicated_commit,
})
return outputs['created']
async def register_version(self, release_type: str, version: str, content_key: bytes, **qualifiers):
outputs = await self._api_client.call('PUT', PrivateReleaseApi.BASE_URL + '/' + release_type + '/version', inputs={
'version': version,
'content_key': b64encode(content_key),
**qualifiers
})
return outputs['created']
async def append_to_channel(self, release_type: str, channel: str, version: str):
outputs = await self._api_client.call('PUT', PrivateReleaseApi.BASE_URL + '/' + release_type + '/channel', inputs={
'channel': channel,
'version': version,
})
return outputs['published']
async def refresh_routes(self, release_type: str):
await self._api_client.call('PUT', PrivateReleaseApi.BASE_URL + '/' + release_type + '/refresh-routes')