From c6598f2835ec31079c57c73c69bd6cc163713b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Wed, 17 Apr 2024 21:04:45 +0200 Subject: [PATCH] =?UTF-8?q?=E2=98=84=EF=B8=8F=20=20deploy:=20github=20rele?= =?UTF-8?q?ases=20-=20whatsNew=20text=20as=20note?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use whatsNew text (if available) as release notes text when deploying to Github releases. This feature will always use 'en-US' locale texts, since English is the lingua franka on GitHub. Additionally this change also adds a config option to preprend a static text to those release notes. --- examples/config.yml | 11 +++++++---- fdroidserver/deploy.py | 36 ++++++++++++++++++++++-------------- fdroidserver/github.py | 3 ++- tests/github.TestCase | 4 ++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/examples/config.yml b/examples/config.yml index 9fa8fa6d..2eb50abc 100644 --- a/examples/config.yml +++ b/examples/config.yml @@ -218,12 +218,13 @@ # an example for this deployment automation: # https://github.com/f-droid/fdroidclient/releases/ # -# It is highly recommended to use a "Fine-grained personal access token", which -# is restriced to the minimum required permissions, which are: +# In the examble below tokens are read from environment variables. Putting +# tokens directly into the config file is also supported but discouraged. It is +# highly recommended to use a "Fine-grained personal access token", which is +# restriced to the minimum required permissions, which are: # * Metadata - read # * Contents - read/write -# Also make sure to limit access only to the GitHub repository you're deploying -# to. (https://github.com/settings/personal-access-tokens/new) +# (https://github.com/settings/personal-access-tokens/new) # # github_token: {env: GITHUB_TOKEN} # github_releases: @@ -231,6 +232,8 @@ # packages: # - org.fdroid.basic # - org.fdroid.fdroid +# release_notes_prepend: | +# Re-post of official F-Droid App release from https://f-droid.org # - repo: example/app # token: {env: GITHUB_TOKEN_EXAMPLE} # packages: diff --git a/fdroidserver/deploy.py b/fdroidserver/deploy.py index 0ed65c7b..85a4b109 100644 --- a/fdroidserver/deploy.py +++ b/fdroidserver/deploy.py @@ -1116,27 +1116,27 @@ def push_binary_transparency(git_repo_path, git_remote): raise FDroidException(_("Pushing to remote server failed!")) -def find_release_files(index_v2_path, repo_dir, package_names): +def find_release_infos(index_v2_path, repo_dir, package_names): """ - Find files for uploading to a release page. + Find files, texts, etc. for uploading to a release page. This function parses index-v2.json for file-paths elegible for deployment to release pages. (e.g. GitHub releases) It also groups these files by packageName and versionName. e.g. to get a list of files for all specific release of fdroid client you may call: - find_binary_release_files()['org.fdroid.fdroid']['0.19.2'] + find_binary_release_infos()['org.fdroid.fdroid']['0.19.2'] All paths in the returned data-structure are of type pathlib.Path. """ - release_files = {} + release_infos = {} with open(index_v2_path, 'r') as f: idx = json.load(f) for package_name in package_names: package = idx.get('packages', {}).get(package_name, {}) for version in package.get('versions', {}).values(): - if package_name not in release_files: - release_files[package_name] = {} + if package_name not in release_infos: + release_infos[package_name] = {} ver_name = version['manifest']['versionName'] apk_path = repo_dir / version['file']['name'][1:] files = [apk_path] @@ -1146,8 +1146,11 @@ def find_release_files(index_v2_path, repo_dir, package_names): idsig_path = pathlib.Path(str(apk_path) + '.idsig') if idsig_path.is_file(): files.append(idsig_path) - release_files[package_name][ver_name] = files - return release_files + release_infos[package_name][ver_name] = { + 'files': files, + 'whatsNew': version.get('whatsNew', {}).get("en-US"), + } + return release_infos def upload_to_github_releases(repo_section, gh_config, global_gh_token): @@ -1167,13 +1170,13 @@ def upload_to_github_releases(repo_section, gh_config, global_gh_token): for package_name in repo_conf.get('packages', []): package_names.append(package_name) - release_files = find_release_files(index_v2_path, repo_dir, package_names) + release_infos = find_release_infos(index_v2_path, repo_dir, package_names) for repo_conf in gh_config: - upload_to_github_releases_repo(repo_conf, release_files, global_gh_token) + upload_to_github_releases_repo(repo_conf, release_infos, global_gh_token) -def upload_to_github_releases_repo(repo_conf, release_files, global_gh_token): +def upload_to_github_releases_repo(repo_conf, release_infos, global_gh_token): repo = repo_conf.get('repo') if not repo: logging.warning(_("One of the 'github_releases' config items is missing the 'repo' value. skipping ...")) @@ -1191,7 +1194,7 @@ def upload_to_github_releases_repo(repo_conf, release_files, global_gh_token): # local fdroid repo all_local_versions = set() for package_name in repo_conf['packages']: - for version in release_files.get(package_name, {}).keys(): + for version in release_infos.get(package_name, {}).keys(): all_local_versions.add(version) gh = fdroidserver.github.GithubApi(token, repo) @@ -1202,9 +1205,14 @@ def upload_to_github_releases_repo(repo_conf, release_files, global_gh_token): # collect files associated with this github release files = [] for package in packages: - files.extend(release_files.get(package, {}).get(version, [])) + files.extend(release_infos.get(package, {}).get(version, {}).get('files', [])) + # always use the whatsNew text from the first app listed in + # config.qml github_releases.packages + text = release_infos.get(packages[0], {}).get(version, {}).get('whatsNew') or '' + if 'release_notes_prepend' in repo_conf: + text = repo_conf['release_notes_prepend'] + "\n\n" + text # create new release on github and upload all associated files - gh.create_release(version, files) + gh.create_release(version, files, text) def main(): diff --git a/fdroidserver/github.py b/fdroidserver/github.py index b7a8ce2a..68396235 100644 --- a/fdroidserver/github.py +++ b/fdroidserver/github.py @@ -90,7 +90,7 @@ class GithubApi: tags.append(r[10:]) return tags - def create_release(self, tag, files): + def create_release(self, tag, files, body=''): """ Create a new release on github. @@ -113,6 +113,7 @@ class GithubApi: data=json.dumps( { "tag_name": tag, + "body": body, } ).encode("utf-8"), ) diff --git a/tests/github.TestCase b/tests/github.TestCase index bc5e04a4..608d7215 100755 --- a/tests/github.TestCase +++ b/tests/github.TestCase @@ -94,7 +94,7 @@ class GithubApiTest(unittest.TestCase): api._create_release_asset = unittest.mock.Mock() with unittest.mock.patch("urllib.request.urlopen", uomock): - success = api.create_release('faketag', ['file_a', 'file_b']) + success = api.create_release('faketag', ['file_a', 'file_b'], body="bdy") self.assertTrue(success) req = uomock.call_args_list[0][0][0] @@ -105,7 +105,7 @@ class GithubApiTest(unittest.TestCase): req.full_url, 'https://api.github.com/repos/fakerepopath/releases', ) - self.assertEqual(req.data, b'{"tag_name": "faketag"}') + self.assertEqual(req.data, b'{"tag_name": "faketag", "body": "bdy"}') self.assertListEqual( api._create_release_asset.call_args_list, [