Write version.txt file before build

This commit is contained in:
Sebastien L
2022-11-28 09:12:58 -05:00
parent 8462de1c16
commit d092ae093c

View File

@@ -12,18 +12,27 @@ import io
from os import walk
from requests import Response
NEWLINE_CHAR = '\n'
def print_message(message,prefix=''):
trimmed=re.sub(r'\n', r'%0A', message,flags=re.MULTILINE)
print(f'{prefix}{trimmed}')
def print_debug(message):
print_message(message,'::debug::')
class Logger:
NEWLINE_CHAR = '\n'
@classmethod
def print_message(cls,message,prefix=''):
trimmed=re.sub(r'\n', r'%0A', message,flags=re.MULTILINE)
print(f'{prefix}{trimmed}')
@classmethod
def debug(cls,message):
cls.print_message(message,'::debug::')
def print_error(message):
print_message(message,'::error::')
@classmethod
def error(cls,message):
cls.print_message(message,'::error::')
@classmethod
def notice(cls,message):
cls.print_message(message,'::notice::')
@classmethod
def warning(cls,message):
cls.print_message(message,'::notice::')
try:
@@ -34,7 +43,6 @@ try:
import glob
import json
import logging
import re
import shutil
import stat
@@ -60,12 +68,12 @@ try:
from genericpath import isdir
except ImportError as ex:
print_error(
f'Failed importing module {ex.name}, using interpreter {sys.executable}. {NEWLINE_CHAR} Installed packages:')
Logger.error(
f'Failed importing module {ex.name}, using interpreter {sys.executable}. {Logger.NEWLINE_CHAR} Installed packages:')
installed_packages = pkg_resources.working_set
installed_packages_list = sorted(
["%s==%s" % (i.key, i.version) for i in installed_packages])
print(NEWLINE_CHAR.join(installed_packages_list))
print(Logger.NEWLINE_CHAR.join(installed_packages_list))
print(f'Environment: ')
envlist = "\n".join([f"{k}={v}" for k, v in sorted(os.environ.items())])
print(f'{envlist}')
@@ -74,13 +82,15 @@ except ImportError as ex:
tool_version = "1.0.7"
WEB_INSTALLER_DEFAULT_PATH = './web_installer/'
FORMAT = '%(asctime)s %(message)s'
logging.basicConfig(format=FORMAT)
github_env = type('', (), {})()
manifest = {
"name": "",
"version": "",
"home_assistant_domain": "slim_player",
"funding_url": "https://esphome.io/guides/supporters.html",
"new_install_prompt_erase": True,
"new_install_improv_wait_time" : 20,
"builds": [
{
"chipFamily": "ESP32",
@@ -277,21 +287,21 @@ class BinFile():
self.source_full_path = os.path.join(
source_path, file_build_path).rstrip()
self.offset = offset
self.target_name = f'{release_details.format_prefix()}-{self.name}'.rstrip()
self.target_name = f'{release_details.format_prefix()}-{release_details.bitrate}-{self.name}'.rstrip()
def get_manifest(self):
return {"path": self.target_name, "offset": self.offset}
def copy(self, target_folder) -> str:
self.target_fullpath = os.path.join(target_folder, self.target_name)
print_debug(
Logger.debug(
f'File {self.source_full_path} will be copied to {self.target_fullpath}')
try:
os.makedirs(target_folder, exist_ok=True)
shutil.copyfile(self.source_full_path,
self.target_fullpath, follow_symlinks=True)
except Exception as ex:
print_error(f"Error while copying {self.source_full_path} to {self.target_fullpath}{NEWLINE_CHAR}Content of {os.path.dirname(self.source_full_path.rstrip())}:{NEWLINE_CHAR}{NEWLINE_CHAR.join(get_file_list(os.path.dirname(self.source_full_path.rstrip())))}")
Logger.error(f"Error while copying {self.source_full_path} to {self.target_fullpath}{Logger.NEWLINE_CHAR}Content of {os.path.dirname(self.source_full_path.rstrip())}:{Logger.NEWLINE_CHAR}{Logger.NEWLINE_CHAR.join(get_file_list(os.path.dirname(self.source_full_path.rstrip())))}")
@@ -323,7 +333,7 @@ class PlatformRelease():
flash_file_path: str
def get_manifest_name(self) -> str:
return f'{self.name_prefix}-{self.release_details.format_prefix()}.json'
return f'{self.name_prefix}-{self.release_details.format_prefix()}-{self.release_details.bitrate}.json'
def __init__(self, flash_file_path, git_release, build_dir, branch, name_prefix) -> None:
self.name = git_release.tag_name
@@ -389,8 +399,7 @@ class PlatformRelease():
self.has_artifacts = False
def cleanup(self):
print(
f'removing temp directory for platform release {self.name}')
Logger.debug(f'removing temp directory for platform release {self.name}')
shutil.rmtree(self.tempfolder)
def get_attributes(self):
@@ -438,7 +447,6 @@ class Releases():
return result
def append(self, value: PlatformRelease):
# optional processing here
if self.count(value) == 0:
self._dict[value.platform()] = []
if self.should_add(value):
@@ -465,8 +473,7 @@ class Releases():
def add_package(self, package: PlatformRelease, with_artifacts: bool = True):
if self.branch != package.branch:
print(
f'Skipping release {package.name} from branch {package.branch}')
Logger.debug(f'Skipping release {package.name} from branch {package.branch}')
elif package.has_artifacts or not with_artifacts:
self.append(package)
@@ -476,7 +483,7 @@ class Releases():
if last is None:
return ''
else:
return last.message.replace(NEWLINE_CHAR, ' ')
return last.message.replace(Logger.NEWLINE_CHAR, ' ')
@classmethod
def get_last_author(cls, repo_obj: Repository = None) -> Signature:
@@ -505,7 +512,7 @@ class Releases():
print(
f'Last commit for {head.shorthand} is {format_commit(cls.last_commit)}')
except Exception as e:
print_error(
Logger.error(
f'Unable to retrieve last commit for {head.shorthand}/{target}: {e}')
cls.last_commit = None
return cls.last_commit
@@ -558,11 +565,11 @@ class Releases():
packages: Releases = cls(branch=repo.head.shorthand, maxcount=maxcount)
build_dir = os.path.dirname(flash_file_path)
for page in range(1, 999):
print_debug(f'Getting releases page {page}')
Logger.debug(f'Getting releases page {page}')
releases = get_github_data(
repo, f'releases?per_page=50&page={page}')
if len(releases) == 0:
print_debug(f'No more release found for page {page}')
Logger.debug(f'No more release found for page {page}')
break
for release_entry in [AttributeDict(platform) for platform in releases]:
packages.add_package(PlatformRelease(flash_file_path, release_entry, build_dir,
@@ -588,14 +595,14 @@ class Releases():
break
except Exception as e:
print_error(
Logger.error(
f'Unable to get commit list starting at {last.id}: {e}')
return commit_list
@classmethod
def get_commit_list_descriptions(cls) -> str:
return '<<~EOD\n### Revision Log\n'+NEWLINE_CHAR.join(cls.get_commit_list())+'\n~EOD'
return '<<~EOD\n### Revision Log\n'+Logger.NEWLINE_CHAR.join(cls.get_commit_list())+'\n~EOD'
def update(self, *args, **kwargs):
if args:
@@ -626,34 +633,27 @@ def parse_json(filename: str):
try:
with open(fname) as f:
content = f.read()
print_debug(f'Loading json\n{content}')
Logger.debug(f'Loading json\n{content}')
return json.loads(content)
except JSONDecodeError as ex:
print_error(f'Error parsing {content}')
Logger.error(f'Error parsing {content}')
except Exception as ex:
print_error(
f"Unable to parse flasher args json file. Content of {folder}:{NEWLINE_CHAR.join(get_file_list(folder))}")
Logger.error(
f"Unable to parse flasher args json file. Content of {folder}:{Logger.NEWLINE_CHAR.join(get_file_list(folder))}")
raise
def write_github_env(args):
print(f'Writing environment details to {args.env_file}...')
with open(args.env_file, "w") as env_file:
for attr in [attr for attr in dir(github_env) if not attr.startswith('_')]:
line = f'{attr}{"=" if attr != "description" else ""}{getattr(github_env,attr)}'
def write_github_env_file(values,env_file):
print(f'Writing content to {env_file}...')
with open(env_file, "w") as env_file:
for attr in [attr for attr in dir(values) if not attr.startswith('_')]:
line = f'{attr}{"=" if attr != "description" else ""}{getattr(values,attr)}'
print(line)
env_file.write(f'{line}\n')
os.environ[attr] = str(getattr(github_env, attr))
print(f'Done writing environment details to {args.env_file}!')
os.environ[attr] = str(getattr(values, attr))
print(f'Done writing to {env_file}!')
def set_workflow_output(args):
print(f'Outputting job variables ...')
for attr in [attr for attr in dir(github_env) if not attr.startswith('_')]:
print(f'::set-output name={attr}::{getattr(github_env,attr)}')
os.environ[attr] = str(getattr(github_env, attr))
print(f'Done outputting job variables!')
def format_artifact_from_manifest(manif_json: AttributeDict):
if len(manif_json) == 0:
@@ -674,7 +674,19 @@ def handle_build_flags(args):
github_env.release_flag = 1 if args.mock or args.force or 'release' in commit_message.lower() else 0
github_env.ui_build = 1 if args.mock or args.ui_build or '[ui-build]' in commit_message.lower(
) or github_env.release_flag == 1 else 0
set_workflow_output(github_env)
write_github_env_file(github_env,os.environ.get('GITHUB_OUTPUT'))
def write_version_number(file_path:str,env_details):
# app_name="${TARGET_BUILD_NAME}.${DEPTH}.dev-$(git log --pretty=format:'%h' --max-count=1).${branch_name}"
# echo "${app_name}">version.txt
try:
version:str = f'{env_details.TARGET_BUILD_NAME}.{env_details.DEPTH}.{env_details.major}.{env_details.BUILD_NUMBER}.{env_details.branch_name}'
with open(file_path, "w") as version_file:
version_file.write(version)
except Exception as ex:
Logger.error(f'Unable to set version string {version} in file {file_path}')
raise Exception('Version error')
Logger.notice(f'Firmware version set to {version}')
def handle_environment(args):
@@ -706,7 +718,8 @@ def handle_environment(args):
github_env.artifact_bin_file_name = f"{github_env.artifact_prefix}.bin"
github_env.PROJECT_VER = f'{args.node}-{ args.build }'
github_env.description = Releases.get_commit_list_descriptions()
write_github_env(args)
write_github_env_file(github_env,args.env_file)
write_version_number("version.txt",github_env)
def handle_artifacts(args):
@@ -722,7 +735,7 @@ def handle_artifacts(args):
os.makedirs(target_dir, exist_ok=True)
shutil.copyfile(source, target, follow_symlinks=True)
except Exception as ex:
print_error(f"Error while copying {source} to {target}\nContent of {target_dir}:\n{NEWLINE_CHAR.join(get_file_list(os.path.dirname(attr[0].rstrip())))}")
Logger.error(f"Error while copying {source} to {target}\nContent of {target_dir}:\n{Logger.NEWLINE_CHAR.join(get_file_list(os.path.dirname(attr[0].rstrip())))}")
raise
@@ -731,16 +744,16 @@ def delete_folder(path):
for root, dirs, files in os.walk(path, topdown=True):
for dir in dirs:
fulldirpath = os.path.join(root, dir)
print_debug(f'Drilling down in {fulldirpath}')
Logger.debug(f'Drilling down in {fulldirpath}')
delete_folder(fulldirpath)
for fname in files:
full_path = os.path.join(root, fname)
print_debug(f'Setting file read/write {full_path}')
Logger.debug(f'Setting file read/write {full_path}')
os.chmod(full_path, stat.S_IWRITE)
print_debug(f'Deleting file {full_path}')
Logger.debug(f'Deleting file {full_path}')
os.remove(full_path)
if os.path.exists(path):
print_debug(f'Changing folder read/write {path}')
Logger.debug(f'Changing folder read/write {path}')
os.chmod(path, stat.S_IWRITE)
print(f'WARNING: Deleting Folder {path}')
os.rmdir(path)
@@ -797,7 +810,7 @@ def handle_manifest(args):
man['builds'][0]['parts'] = release.process_files(args.outdir)
man['name'] = release.platform()
man['version'] = release.release_details.version
print_debug(f'Generated manifest: \n{json.dumps(man)}')
Logger.debug(f'Generated manifest: \n{json.dumps(man)}')
fullpath = os.path.join(args.outdir, release.get_manifest_name())
print(f'Writing manifest to {fullpath}')
with open(fullpath, "w") as f:
@@ -827,7 +840,7 @@ def copy_no_overwrite(source: str, target: str):
print(f'Copying {f} to target')
shutil.copy(source_file, target_file)
else:
print_debug(f'Skipping existing file {f}')
Logger.debug(f'Skipping existing file {f}')
def get_changed_items(repo: Repository) -> Dict:
@@ -870,13 +883,13 @@ def push_if_change(repo: Repository, token: str, source_path: str, manif_json):
print(
f'Pushing commit {format_commit(repo[commit])} to url {origin.url}')
remote: Remote = repo.remotes['origin']
auth_methods = ['x-access-token','x-oauth-basic']
for method in auth_methods:
if push_with_method('x-access-token', token, remote, [reference]):
print(f'::notice Web installer updated for {format_artifact_from_manifest(manif_json)}')
return
raise Exception('Unable to push web installer changes to installer repo')
# remote.credentials = credentials
auth_method = 'x-access-token'
remote.push([reference], callbacks=RemoteCallbacks(
pygit2.UserPass(auth_method, token)))
print(
f'::notice Web installer updated for {format_artifact_from_manifest(manif_json)}')
else:
print(f'WARNING: No change found. Skipping update')
@@ -921,8 +934,8 @@ def handle_show(args):
def extract_files_from_archive(url):
tempfolder = tempfile.mkdtemp()
platform:Response = requests.get(url)
print_debug(f'Downloading {url} to {tempfolder}')
print_debug(f'Transfer status code: {platform.status_code}. Expanding content')
Logger.debug(f'Downloading {url} to {tempfolder}')
Logger.debug(f'Transfer status code: {platform.status_code}. Expanding content')
z = zipfile.ZipFile(io.BytesIO(platform.content))
z.extractall(tempfolder)
return tempfolder
@@ -930,7 +943,7 @@ def extract_files_from_archive(url):
def handle_list_files(args):
print(f'Content of {args.cwd}:')
print(NEWLINE_CHAR.join(get_file_list(args.cwd)))
print(Logger.NEWLINE_CHAR.join(get_file_list(args.cwd)))
parser_environment.set_defaults(func=handle_environment, cmd='environment')
@@ -955,7 +968,7 @@ def main():
try:
func(args)
except Exception as e:
print_error(f'Critical error while running {args.command}\n{" ".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))}')
Logger.error(f'Critical error while running {args.command}\n{" ".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))}')
exit_result_code = 1
else:
# No subcommand was provided, so call help