mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-09-13 14:32:28 +03:00
☄️ deploy: github releases - whatsNew text as note
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.
This commit is contained in:
parent
a079f9d85f
commit
c6598f2835
4 changed files with 33 additions and 21 deletions
|
@ -218,12 +218,13 @@
|
||||||
# an example for this deployment automation:
|
# an example for this deployment automation:
|
||||||
# https://github.com/f-droid/fdroidclient/releases/
|
# https://github.com/f-droid/fdroidclient/releases/
|
||||||
#
|
#
|
||||||
# It is highly recommended to use a "Fine-grained personal access token", which
|
# In the examble below tokens are read from environment variables. Putting
|
||||||
# is restriced to the minimum required permissions, which are:
|
# 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
|
# * Metadata - read
|
||||||
# * Contents - read/write
|
# * Contents - read/write
|
||||||
# Also make sure to limit access only to the GitHub repository you're deploying
|
# (https://github.com/settings/personal-access-tokens/new)
|
||||||
# to. (https://github.com/settings/personal-access-tokens/new)
|
|
||||||
#
|
#
|
||||||
# github_token: {env: GITHUB_TOKEN}
|
# github_token: {env: GITHUB_TOKEN}
|
||||||
# github_releases:
|
# github_releases:
|
||||||
|
@ -231,6 +232,8 @@
|
||||||
# packages:
|
# packages:
|
||||||
# - org.fdroid.basic
|
# - org.fdroid.basic
|
||||||
# - org.fdroid.fdroid
|
# - org.fdroid.fdroid
|
||||||
|
# release_notes_prepend: |
|
||||||
|
# Re-post of official F-Droid App release from https://f-droid.org
|
||||||
# - repo: example/app
|
# - repo: example/app
|
||||||
# token: {env: GITHUB_TOKEN_EXAMPLE}
|
# token: {env: GITHUB_TOKEN_EXAMPLE}
|
||||||
# packages:
|
# packages:
|
||||||
|
|
|
@ -1116,27 +1116,27 @@ def push_binary_transparency(git_repo_path, git_remote):
|
||||||
raise FDroidException(_("Pushing to remote server failed!"))
|
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
|
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
|
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
|
packageName and versionName. e.g. to get a list of files for all specific
|
||||||
release of fdroid client you may call:
|
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.
|
All paths in the returned data-structure are of type pathlib.Path.
|
||||||
"""
|
"""
|
||||||
release_files = {}
|
release_infos = {}
|
||||||
with open(index_v2_path, 'r') as f:
|
with open(index_v2_path, 'r') as f:
|
||||||
idx = json.load(f)
|
idx = json.load(f)
|
||||||
for package_name in package_names:
|
for package_name in package_names:
|
||||||
package = idx.get('packages', {}).get(package_name, {})
|
package = idx.get('packages', {}).get(package_name, {})
|
||||||
for version in package.get('versions', {}).values():
|
for version in package.get('versions', {}).values():
|
||||||
if package_name not in release_files:
|
if package_name not in release_infos:
|
||||||
release_files[package_name] = {}
|
release_infos[package_name] = {}
|
||||||
ver_name = version['manifest']['versionName']
|
ver_name = version['manifest']['versionName']
|
||||||
apk_path = repo_dir / version['file']['name'][1:]
|
apk_path = repo_dir / version['file']['name'][1:]
|
||||||
files = [apk_path]
|
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')
|
idsig_path = pathlib.Path(str(apk_path) + '.idsig')
|
||||||
if idsig_path.is_file():
|
if idsig_path.is_file():
|
||||||
files.append(idsig_path)
|
files.append(idsig_path)
|
||||||
release_files[package_name][ver_name] = files
|
release_infos[package_name][ver_name] = {
|
||||||
return release_files
|
'files': files,
|
||||||
|
'whatsNew': version.get('whatsNew', {}).get("en-US"),
|
||||||
|
}
|
||||||
|
return release_infos
|
||||||
|
|
||||||
|
|
||||||
def upload_to_github_releases(repo_section, gh_config, global_gh_token):
|
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', []):
|
for package_name in repo_conf.get('packages', []):
|
||||||
package_names.append(package_name)
|
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:
|
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')
|
repo = repo_conf.get('repo')
|
||||||
if not repo:
|
if not repo:
|
||||||
logging.warning(_("One of the 'github_releases' config items is missing the 'repo' value. skipping ..."))
|
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
|
# local fdroid repo
|
||||||
all_local_versions = set()
|
all_local_versions = set()
|
||||||
for package_name in repo_conf['packages']:
|
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)
|
all_local_versions.add(version)
|
||||||
|
|
||||||
gh = fdroidserver.github.GithubApi(token, repo)
|
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
|
# collect files associated with this github release
|
||||||
files = []
|
files = []
|
||||||
for package in packages:
|
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
|
# create new release on github and upload all associated files
|
||||||
gh.create_release(version, files)
|
gh.create_release(version, files, text)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
@ -90,7 +90,7 @@ class GithubApi:
|
||||||
tags.append(r[10:])
|
tags.append(r[10:])
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
def create_release(self, tag, files):
|
def create_release(self, tag, files, body=''):
|
||||||
"""
|
"""
|
||||||
Create a new release on github.
|
Create a new release on github.
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ class GithubApi:
|
||||||
data=json.dumps(
|
data=json.dumps(
|
||||||
{
|
{
|
||||||
"tag_name": tag,
|
"tag_name": tag,
|
||||||
|
"body": body,
|
||||||
}
|
}
|
||||||
).encode("utf-8"),
|
).encode("utf-8"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -94,7 +94,7 @@ class GithubApiTest(unittest.TestCase):
|
||||||
api._create_release_asset = unittest.mock.Mock()
|
api._create_release_asset = unittest.mock.Mock()
|
||||||
|
|
||||||
with unittest.mock.patch("urllib.request.urlopen", uomock):
|
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)
|
self.assertTrue(success)
|
||||||
|
|
||||||
req = uomock.call_args_list[0][0][0]
|
req = uomock.call_args_list[0][0][0]
|
||||||
|
@ -105,7 +105,7 @@ class GithubApiTest(unittest.TestCase):
|
||||||
req.full_url,
|
req.full_url,
|
||||||
'https://api.github.com/repos/fakerepopath/releases',
|
'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(
|
self.assertListEqual(
|
||||||
api._create_release_asset.call_args_list,
|
api._create_release_asset.call_args_list,
|
||||||
[
|
[
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue