From 61842d626d6032ffcdbd2c697fb574f78c74a7b9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 18 Jun 2025 22:46:50 +0200 Subject: [PATCH] nightly: print error if env var is missing This should help with debugging a lot. Before this, it showed an obtuse stacktrace when an env var was not set: ``` Traceback (most recent call last): File "/usr/bin/fdroid", line 33, in sys.exit(load_entry_point('fdroidserver==2.4.0', 'console_scripts', 'fdroid')()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/fdroidserver/__main__.py", line 222, in main raise e File "/usr/lib/python3/dist-packages/fdroidserver/__main__.py", line 203, in main mod.main() File "/usr/lib/python3/dist-packages/fdroidserver/nightly.py", line 352, in main writer.set_value('user', 'name', git_user_name) File "/usr/lib/python3/dist-packages/git/config.py", line 122, in assure_data_present return func(self, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/git/config.py", line 134, in flush_changes rval = non_const_func(self, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/git/config.py", line 855, in set_value self.set(section, option, self._value_to_string(value)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/git/config.py", line 838, in _value_to_string return force_text(value) ^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/gitdb/utils/encoding.py", line 18, in force_text return str(data, encoding) ^^^^^^^^^^^^^^^^^^^ TypeError: decoding to str: need a bytes-like object, NoneType found ``` --- fdroidserver/nightly.py | 42 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/fdroidserver/nightly.py b/fdroidserver/nightly.py index 88386029..0c2fbb9c 100644 --- a/fdroidserver/nightly.py +++ b/fdroidserver/nightly.py @@ -241,6 +241,16 @@ def clone_git_repo(clone_url, git_mirror_path): raise VCSException(f'git clone {clone_url} failed:', str(e)) from e +def _getenv(name): + """Return the value of an environment variable, printing an error if None.""" + value = os.getenv(name) + if not value: + logging.error( + _('Environment variable "{name}" has an empty value!').format(name=name) + ) + return value + + def main(): """Deploy to F-Droid repository or generate SSH private key from keystore. @@ -303,7 +313,7 @@ def main(): umask = os.umask(0o077) if 'CI' in os.environ: - v = os.getenv('DEBUG_KEYSTORE') + v = _getenv('DEBUG_KEYSTORE') debug_keystore = None if v: debug_keystore = base64.b64decode(v) @@ -324,19 +334,19 @@ def main(): # the 'master' branch is hardcoded in fdroidserver/deploy.py if 'CI_PROJECT_PATH' in os.environ and 'CI_PROJECT_URL' in os.environ: # we are in GitLab CI - repo_git_base = os.getenv('CI_PROJECT_PATH') + NIGHTLY - base_url = f"{os.getenv('CI_PROJECT_URL')}{NIGHTLY}" + repo_git_base = f"{_getenv('CI_PROJECT_PATH')}{NIGHTLY}" + base_url = f"{_getenv('CI_PROJECT_URL')}{NIGHTLY}" clone_url = f'{base_url}.git' # avoid redirects while cloning repo_base = get_repo_base_url( base_url, repo_git_base, force_type='gitlab.com' ) servergitmirror = f'git@{urlparse(base_url).netloc}:{repo_git_base}.git' deploy_key_url = f'{base_url}/-/settings/repository#js-deploy-keys-settings' - git_user_name = os.getenv('GITLAB_USER_NAME') - git_user_email = os.getenv('GITLAB_USER_EMAIL') + git_user_name = _getenv('GITLAB_USER_NAME') + git_user_email = _getenv('GITLAB_USER_EMAIL') elif 'TRAVIS_REPO_SLUG' in os.environ: # we are in Travis CI - repo_git_base = os.getenv('TRAVIS_REPO_SLUG') + NIGHTLY + repo_git_base = _getenv('TRAVIS_REPO_SLUG') + NIGHTLY clone_url = 'https://github.com/' + repo_git_base repo_base = get_repo_base_url( clone_url, repo_git_base, force_type='github.com' @@ -347,7 +357,7 @@ def main(): + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' ) git_user_name = repo_git_base - git_user_email = os.getenv('USER') + '@' + platform.node() + git_user_email = _getenv('USER') + '@' + platform.node() elif ( 'CIRCLE_REPOSITORY_URL' in os.environ and 'CIRCLE_PROJECT_USERNAME' in os.environ @@ -355,12 +365,12 @@ def main(): ): # we are in Circle CI repo_git_base = ( - os.getenv('CIRCLE_PROJECT_USERNAME') + _getenv('CIRCLE_PROJECT_USERNAME') + '/' - + os.getenv('CIRCLE_PROJECT_REPONAME') + + _getenv('CIRCLE_PROJECT_REPONAME') + NIGHTLY ) - clone_url = os.getenv('CIRCLE_REPOSITORY_URL') + NIGHTLY + clone_url = _getenv('CIRCLE_REPOSITORY_URL') + NIGHTLY repo_base = get_repo_base_url( clone_url, repo_git_base, force_type='github.com' ) @@ -369,12 +379,12 @@ def main(): f'https://github.com/{repo_git_base}/settings/keys' + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' ) - git_user_name = os.getenv('CIRCLE_USERNAME') + git_user_name = _getenv('CIRCLE_USERNAME') git_user_email = git_user_name + '@' + platform.node() elif 'GITHUB_ACTIONS' in os.environ: # we are in Github actions - repo_git_base = os.getenv('GITHUB_REPOSITORY') + NIGHTLY - clone_url = os.getenv('GITHUB_SERVER_URL') + '/' + repo_git_base + repo_git_base = _getenv('GITHUB_REPOSITORY') + NIGHTLY + clone_url = _getenv('GITHUB_SERVER_URL') + '/' + repo_git_base repo_base = get_repo_base_url( clone_url, repo_git_base, force_type='github.com' ) @@ -383,7 +393,7 @@ def main(): f'https://github.com/{repo_git_base}/settings/keys' + '\nhttps://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys' ) - git_user_name = os.getenv('GITHUB_ACTOR') + git_user_name = _getenv('GITHUB_ACTOR') git_user_email = git_user_name + '@' + platform.node() else: print(_('ERROR: unsupported CI type, patches welcome!')) @@ -441,7 +451,7 @@ Last updated: {date}'''.format( ssh_private_key_file = _ssh_key_from_debug_keystore() # this is needed for GitPython to find the SSH key - ssh_dir = os.path.join(os.getenv('HOME'), '.ssh') + ssh_dir = os.path.join(_getenv('HOME'), '.ssh') os.makedirs(ssh_dir, exist_ok=True) ssh_config = os.path.join(ssh_dir, 'config') logging.debug(_('adding IdentityFile to {path}').format(path=ssh_config)) @@ -586,7 +596,7 @@ Last updated: {date}'''.format( + '\n -dname "CN=Android Debug,O=Android,C=US"' ) sys.exit(1) - ssh_dir = os.path.join(os.getenv('HOME'), '.ssh') + ssh_dir = os.path.join(_getenv('HOME'), '.ssh') privkey = _ssh_key_from_debug_keystore(options.keystore) if os.path.exists(ssh_dir): ssh_private_key_file = os.path.join(ssh_dir, os.path.basename(privkey))