瀏覽代碼

Write version.txt file before build

Sebastien L 2 年之前
父節點
當前提交
d092ae093c
共有 1 個文件被更改,包括 81 次插入68 次删除
  1. 81 68
      docker/build_tools.py

+ 81 - 68
docker/build_tools.py

@@ -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,33 +633,26 @@ 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):
@@ -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