Merge pull request #351 from kiwix/no_android

No android
This commit is contained in:
Kelson 2019-12-05 14:25:47 +01:00 committed by GitHub
commit 97bcc3e991
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 23 additions and 846 deletions

View File

@ -69,7 +69,7 @@ By default, `kiwix-build` will build `kiwix-tools` .
If no target platform is specified, a default one will be infered from If no target platform is specified, a default one will be infered from
the specified target : the specified target :
- `kiwix-android` will be build using the platform `android` - `kiwix-lib-app` will be build using the platform `android`
- Other targets will be build using the platform `native_dyn` - Other targets will be build using the platform `native_dyn`
But you can select another target platform using the option But you can select another target platform using the option
@ -93,9 +93,14 @@ kiwix-build --target-platform win32_dyn
## Android ## Android
Android apk (kiwix-android) is a bit a special case. `kiwix-android` (https://github.com/kiwix/kiwix-android) depends of
`kiwix-android` itself is architecture independent (it is written in the `kiwix-lib` project.
java) but it use `kiwix-lib` who is architecture dependent. It uses a special `.aar` file that represent (and embed) the kiwix-lib for
all supported android arch. This is a kind of fat archive we have for MacOs.
The `.aar` file is build using the `kiwix-lib-app` project.
`kiwix-lib-app` itself is architecture independent (it is just a packaging of
other archives) but it use `kiwix-lib` who is architecture dependent.
When building `kiwix-lib`, you should directly use the When building `kiwix-lib`, you should directly use the
target-platform `android_<arch>`: target-platform `android_<arch>`:
@ -103,22 +108,23 @@ target-platform `android_<arch>`:
kiwix-build kiwix-lib --target-platform android_arm kiwix-build kiwix-lib --target-platform android_arm
``` ```
But, `kiwix-android` apk can also be multi arch (ie, it includes But, `kiwix-lib-app` is mainly multi arch.
`kiwix-lib` for several architectures). To do so, you must ask to build To compile `kiwix-lib-app`, you must use the `android` platform:
`kiwix-android` using the `android` platform:
```bash ```bash
kiwix-build --target-platform android kiwix-android $ kiwix-build --target-platform android kiwix-lib-app
kiwix-build kiwix-android # because `android` platform is the default for `kiwix-android` $ kiwix-build kiwix-lib-app # because `android` platform is the default for `kiwix-lib-app`
``` ```
By default, when using platform `android`, `kiwix-lib` will be build for By default, when using platform `android`, `kiwix-lib` will be build for
all architectures. This can be changed by using the option `--android-arch` : all architectures. This can be changed by using the option `--android-arch` :
```bash ```bash
kiwix-build kiwix-android # apk for all architectures $ kiwix-build kiwix-lib-app # aar with all architectures
kiwix-build kiwix-android --android-arch arm # apk for arm architecture $ kiwix-build kiwix-lib-app --android-arch arm # aar with arm architecture
kiwix-build kiwix-anrdoid --android-arch arm --android-arch arm64 # apk for arm and arm64 architectures $ kiwix-build kiwix-lib-app --android-arch arm --android-arch arm64 # aan with arm and arm64 architectures
``` ```
To build `kiwix-android` itself, you should see the documentation of `kiwix-android`.
## IOS ## IOS
When building for ios, we may want to compile a "fat library", a library When building for ios, we may want to compile a "fat library", a library

View File

@ -1,85 +0,0 @@
#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use Getopt::Long;
# get the params
my $zim_url;
my $custom_app;
my $keystore;
my $api_key;
my $version = "0";
my $cmd;
# Get console line arguments
GetOptions('zim_url=s' => \$zim_url,
'custom_app=s' => \$custom_app,
'keystore=s' => \$keystore,
'api_key=s' => \$api_key,
'version=s' => \$version
);
# Print usage() if necessary
if (!$zim_url || !$custom_app || !$keystore || !$api_key) {
print "usage: ./build_custom_app.pl --keystore=kiwix-android.keystore --api_key=google.json --zim_url=\"https://download.kiwix.org/zim/wikipedia_en_medicine_novid.zim\" --custom_app=wikimed [--version=1]\n";
exit;
}
# Clean signed ap
$cmd = "rm ./signed_apks/*apk"; `$cmd`;
# Download ZIM file
$cmd = "wget \"$zim_url\" -O content.zim"; `$cmd`;
# Get ZIM file size
$cmd = "stat -c %s content.zim";
my $zim_size = `$cmd` =~ s/\n//gr ;
$ENV{ZIM_SIZE} = $zim_size;
# Compute version code base
$cmd = "date +%y%j";
my $version_code_base = `$cmd` =~ s/\n//gr . $version;
# Compute content version code
my $content_version_code = $version_code_base;
$ENV{CONTENT_VERSION_CODE} = $content_version_code;
# Compute custom app date
$cmd = "date +%Y-%m";
my $date = `$cmd` =~ s/\n//gr;
$ENV{VERSION_NAME} = $date;
# Compile apps
$ENV{VERSION_CODE} = $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_arm --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "1" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_arm64 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "2" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_x86 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "3" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_x86_64 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
# Sign apps
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-${version_code_base}-release-signed.apk BUILD_android_arm/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-1${version_code_base}-release-signed.apk BUILD_android_arm64/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-2${version_code_base}-release-signed.apk BUILD_android_x86/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-3${version_code_base}-release-signed.apk BUILD_android_x86_64/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
# Upload
$cmd = "./build_custom_app.py --step publish --custom-app ${custom_app} --google-api-key ${api_key} --zim-path content.zim --apks-dir signed_apks --content-version-code ${content_version_code}";
system $cmd;
exit;

View File

@ -1,430 +0,0 @@
#!/usr/bin/env python3
import \
argparse, \
datetime, \
glob, \
json, \
os, \
ssl, \
sys, \
tempfile, \
time, \
urllib
from uuid import uuid4
from contextlib import contextmanager
from urllib.parse import urlparse
from utils import (
Remotefile,
download_remote
)
import requests
import httplib2
from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client import client
from oauth2client.service_account import ServiceAccountCredentials
tmpl_request_url = "https://api.travis-ci.org/repo/{organisation}%2F{repository}/{endpoint}"
tmpl_message = """Build of custom app {app} with zim file {zim}.
UUID:#{uuid}#"""
description = """Launch a custom application build.
This command will launch a custom application build on Travis-CI.
Travis-CI jobs will compile the application and upload the build apks on
google play, using tha 'alpha' track of the application.
You will need to have a valid TRAVIS_TOKEN associated to your personnal account
and the kiwix-build repository on travis.
Use the 'travis' command line tool (https://github.com/travis-ci/travis.rb)
to generate a token.
"""
def parse_args():
parser = argparse.ArgumentParser(description=description,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--custom-app')
parser.add_argument('--travis-token')
advance = parser.add_argument_group('advance', "Some advanced options.")
advance.add_argument('--extra-code', type=int, default=0)
advance.add_argument('--version-name', default=None,
help="The version of the application (seen by user). Get from json info file by default.")
advance.add_argument('--check-certificate', default=True)
advance.add_argument('--zim-url', default=None, help="Get from json info file by default.")
advance.add_argument('--no-android-upload', action='store_false', dest='android_upload')
# Hidden options
parser.add_argument('--step', default='launch', choices=['launch', 'publish'], help=argparse.SUPPRESS)
parser.add_argument('--apks-dir', help=argparse.SUPPRESS)
parser.add_argument('--zim-path', default=None, help=argparse.SUPPRESS)
parser.add_argument('--content-version-code', type=int, help=argparse.SUPPRESS)
parser.add_argument('--package-name', default=None, help=argparse.SUPPRESS)
parser.add_argument('--google-api-key', help=argparse.SUPPRESS)
options = parser.parse_args()
if (not options.package_name
or not (options.zim_url or options.zim_path)
or not options.version_name):
if not options.package_name:
print("Try to get package name from info.json file")
if not options.zim_url:
print("Try to get zim url from info.json file")
if not options.version_name:
print("Try to get version_name form info.json file")
request_url = ('https://raw.githubusercontent.com/kiwix/kiwix-android-custom/master/{}/info.json'
.format(options.custom_app))
json_request = requests.get(request_url)
if json_request.status_code != 200:
print("Error while getting json file.")
print("Reason is '{}'".format(json_request.reason))
sys.exit(-1)
json_data = json.loads(json_request.text)
if not options.package_name:
print("Found package_name '{}'".format(json_data['package']))
options.package_name = json_data['package']
if not options.zim_url:
print("Found zim_url '{}'".format(json_data['zim_url']))
options.zim_url = json_data['zim_url']
if not options.version_name:
print("Found version_name '{}'".format(json_data['version_name']))
options.version_name = json_data['version_name']
options.base_version = "{}{}".format(
datetime.date.today().strftime('%y%j'),
options.extra_code)
return options
def download_zim_file(zim_url, dest_dir=None):
if dest_dir is None:
dest_dir = os.getcwd()
out_filename = urlparse(zim_url).path
out_filename = os.path.basename(out_filename)
zim_file = Remotefile(out_filename, '', zim_url)
download_remote(zim_file, dest_dir)
return os.path.join(dest_dir, out_filename)
def get_zim_size(*, zim_url=None, zim_path=None, check_certificate=True):
print("Try to get zim size")
if not zim_path:
if not check_certificate:
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
else:
context = None
extra_args = {'context':context} if sys.version_info >= (3, 4, 3) else {}
with urllib.request.urlopen(zim_url, **extra_args) as resource:
size = resource.getheader('Content-Length', None)
if size is not None:
size = int(size)
print("Zim size is {}".format(size))
return size
else:
print("No 'Content-Length' header in http answer from the server.\n"
"We need to download the zim file to get its size.")
zim_path = download_zim_file(zim_url, tempfile.gettempdir())
size = os.path.getsize(zim_path)
print("Zim size is {}".format(size))
return size
def do_launch(options):
if options.zim_path:
zim_size = get_zim_size(zim_path=options.zim_path)
else:
zim_size = get_zim_size(zim_url=options.zim_url,
check_certificate=options.check_certificate)
travis_launch_build('kiwix', 'kiwix-build', options, zim_size)
print("Travis build has been launch.")
def do_publish(options):
zim_path = options.zim_path or download_zim_file(options.zim_url)
googleService = Google(options)
with googleService.new_request():
versionCodes = []
for apk in glob.iglob(options.apks_dir+"/*.apk"):
result = googleService.upload_apk(apk)
versionCodes.append(result['versionCode'])
googleService.upload_expansionfile(
zim_path, options.content_version_code, versionCodes)
googleService.publish_release(options, versionCodes)
def travis_launch_build(organisation, repository, options, zim_size):
request_url = tmpl_request_url.format(
organisation=organisation,
repository=repository,
endpoint='requests')
headers = {
"Travis-API-Version": "3",
"Content-Type": "application/json",
"Authorization": "token {}".format(options.travis_token),
"User-Agent": "kiwix-build"
}
uuid = uuid4()
envs = []
for platform_index, platform in enumerate(['arm', 'arm64', 'x86', 'x86_64']):
d = {
'PLATFORM': "android_{}".format(platform),
'VERSION_CODE': gen_version_code(platform_index, options.base_version)
}
envs.append(d)
global_env = [
{ 'CUSTOM_APP': options.custom_app},
{ 'ZIM_FILE_SIZE': zim_size},
{ 'PACKAGE_NAME': options.package_name},
{ 'ZIM_URL': options.zim_url},
{ 'EXTRA_CODE': options.extra_code},
{ 'CONTENT_VERSION_CODE': gen_version_code(0, options.base_version)},
{ 'VERSION_NAME': options.version_name},
# google_key
{ 'secure': ('VAgKBMx0KEIyJlSnpM4YrHKLALIbaibkhlsgiv19ITa6dODoEIqeYHz'
'wFTiL3mRHU6HwtXtdNb/JeMle9NfHJVFSV56ZgFzX7ev9zr0YG0qZQv'
'tl8vHQlFPBErARder/L2tblOTM194/TiJk/q89a0XWDanKswXExwjcW'
'Z0tnDYQXTHSAKEt+xW8hjbnhqqB/v16lX6dUjZI+sVlsw+qAM4VT/qf'
'FCyDO5eJCzWIEL2LDUWI7jKSETNih5hl5fMMvCCNRPnkgGnytw5kF/t'
'Lw8YAbLRxkGsO4FCx5mB7HF5pNHyWOCCalMTKheyg/qUV/VcXW9Unlr'
'puMu0+d3hpLZESplS/NkvDxSrx16ank7EORS8OxLOufu56TW2hDuBzz'
'w1CBAj1p6s+Z6Kc4RMYYdxRgR1TjXg/ZVUn3T69d9igdS/5lAPFx2Ww'
'8x82FWCLSaiXymxXRNsNcKx5ifuvtv307r4yh31QjlKFYwadOCaCHHZ'
'zGE1mXcOu3j6W9WIaZfYRTpxmOrcfDIHxZSdLf11hOSZEUUFpj9hQlV'
'Op0RHkDEJUMNs6vkXUhZq9yPuqgrcb6GaN+UhOT8iHlijKmlG8NJEPk'
'Hp8RnL1hsr44N57ZzLqmSUZtvC83u/5e+YUb7beUDGsMyJV/fcMiGMM'
'LVtRnuPCFyNVNQUf2CphtG0=') },
# pass
{ 'secure': ('AtbgKUukES2uJPpEWNEDHLg0WcghLlCGL171Ah3+4CckBI8y1Fn+VpH'
'U2vEXzsV8tKoxX1IyB2tFivzuyo6CQXHSuWGJYQexwkBeGCgOfzKJLj'
'MAy75ATYA6JnFrikV+UcqdEz/9Dow3J1K7Slp3jpsQhERHbNeqkr4I+'
'XCL1LLnpewfOZo9OIEu93p6b6YlqvIPXJHyQe5xnMd8jFWg3/uIYqFn'
'XPvigeZqC2lhNp48mj4JdwwF2tmiArgyXOmgxiuHJNVVI7okbhc7kmI'
'Y3MmCSFgG0XPUEBU3Kdr4o/2hy8DDP6Gff+rUZW8nPI/2UWXRLWtOxv'
'XGGRyjHHTxGWzI4JyZbli9dls5M32MMjsXVKtciSFVwsMM8qn7wFnRi'
'q248a1Sg5fDNX/WYowmsHlWjffHZ7+UqUqJxAKtZ0vpQL+4SPIALPnK'
'V6j6CoorQp+VhMF01EFlZ0c8bkNmk4YW7R7RyNLIcaHKfd1ud8QF9PD'
'AnQ7Jr1GRBxzkjHvHfFrE14WPUu+FjVvDO7UPVMNQX7RS1IVACpKSRu'
'7N8KnIK3vSnLpn5GXKsbx0JB2vtyoTaFZvC9c3qyAw1nlpn7Lp3sPs3'
'bgIBU4tWOzg5g46eHbc4ad5nyB9Soz715lbMdECvKs2HHJUG3tubLKj'
'L0S/LRGRQ+IDgC7xrjQj8aA=') },
]
env = {
'matrix': envs,
'global': global_env
}
data = {
'request': {
'message' : tmpl_message.format(app=options.custom_app, zim=options.zim_url, uuid=uuid),
'branch' : "custom_app",
'config' : {
'before_install' : [
( 'pip3 install pyOpenSSl google-api-python-client'
' httplib2 apiclient requests'),
( 'openssl aes-256-cbc -k $google_key'
' -in travis/googleplay_android_developer-5a411156212c.json.enc'
' -out travis/googleplay_android_developer-5a411156212c.json'
' -d'),
( 'openssl aes-256-cbc -k $google_key'
' -in travis/kiwix-android.keystore.enc'
' -out travis/kiwix-android.keystore -d'),
( 'openssl aes-256-cbc -K $encrypted_eba2f7543984_key'
' -iv $encrypted_eba2f7543984_iv'
' -in travis/travisci_builder_id_key.enc'
' -out travis/travisci_builder_id_key -d'),
'chmod 600 travis/travisci_builder_id_key'
],
'env' : env,
'script' : 'travis_wait 30 travis/compile_custom_app.sh',
'deploy' : {
'provider': 'script',
'skip_cleanup': True,
'script': 'travis/deploy_apk.sh',
'on': {
'branch': 'custom_app'
}
}
}
}
}
if options.android_upload:
data['request']['config']['jobs'] = {
'include': [
{
'stage' : 'make_release',
'install': 'pip3 install -r requirements_build_custom_app.txt',
'script': True,
'env': global_env,
'deploy' : {
'provider': 'script',
'skip_cleanup': True,
'script': 'travis/make_release.sh',
'on': {
'branch': 'custom_app'
}
}
}
]
}
global_env.append({
'DEPLOY_DIR' : '/home/nightlybot/apks/{}_{}'.format(
options.custom_app, options.base_version)
})
else:
global_env.append({
'DEPLOY_DIR' : '/data/tmp/custom_apps/{}_{}'.format(
options.custom_app, options.base_version)
})
r = requests.post(request_url, headers=headers, json=data)
if r.status_code != 202:
print("Error while requesting build:")
print(r.reason)
print("Have you forget to give the travis token ?")
sys.exit(-1)
else:
request_id = r.json()['request']['id']
print("Request {} has been schedule.".format(request_id))
request_left = 10
found = False
request_url = tmpl_request_url.format(
organisation=organisation,
repository=repository,
endpoint='builds')
while request_left:
time.sleep(1)
print("Try to get associated build.")
r = requests.get(request_url, headers=headers)
json_data = json.loads(r.text)
for build in json_data['builds']:
if build['event_type'] != 'api':
continue
message = build['commit']['message']
if str(uuid) in message:
found = True
break
if found:
break
print("Cannot find build. Wait 1 second and try again")
print("{} tries left".format(request_left))
request_left -= 1
if found:
print("Associated build found: {}.".format(build['number']))
print("https://travis-ci.org/kiwix/kiwix-build/builds/{}".format(build['id']))
else:
print("Request has been accepted by travis-ci but I cannot found "
"the associated build. Have a look here "
"https://travis-ci.org/kiwix/kiwix-build/builds"
"if you found it.")
if not options.android_upload:
print(("Automatic upload to android play store has been deactivated.\n"
"You will find the apks at this address once they have been compiled :"
" http://tmp.kiwix.org/custom_apps/{}_{}").format(
options.custom_app, options.base_version))
ERROR_MSG_EDIT_CHANGE = "A change was made to the application outside of this Edit, please create a new edit."
class Google:
def __init__(self, options):
scope = 'https://www.googleapis.com/auth/androidpublisher'
key = options.google_api_key
credentials = ServiceAccountCredentials.from_json_keyfile_name(
key,
scopes=[scope])
http = httplib2.Http()
http = credentials.authorize(http)
self.service = build('androidpublisher', 'v2', http=http)
self.packageName = options.package_name
self.edit_id = None
@contextmanager
def new_request(self):
edit_request = self.service.edits().insert(
packageName=self.packageName,
body={})
result = edit_request.execute()
print("create", result)
self.edit_id = result['id']
yield
commit_request = self.service.edits().commit(
editId=self.edit_id,
packageName=self.packageName)
result = commit_request.execute()
print("commit", result)
self.edit_id = None
def make_request(self, section, method, **kwargs):
request_content = self._build_request_content(kwargs)
_section = getattr(self._edits, section)()
_method = getattr(_section, method)
print(">", request_content)
request = _method(**request_content)
result = request.execute()
print("<", result)
return result
def _build_request_content(self, kwargs):
d = kwargs.copy()
d['editId'] = self.edit_id
d['packageName'] = self.packageName
return d
@property
def _edits(self):
return self.service.edits()
def upload_expansionfile(self, comp_file, contentVersionCode, versionCodes):
versionCodes = [int(v) for v in versionCodes]
self.make_request('expansionfiles', 'upload',
expansionFileType='main',
apkVersionCode=contentVersionCode,
media_body=comp_file,
media_mime_type='application/octet-stream')
for versionCode in versionCodes:
if versionCode == contentVersionCode:
continue
self.make_request('expansionfiles', 'update',
expansionFileType='main',
apkVersionCode=versionCode,
body={'referencesVersion': contentVersionCode}
)
def upload_apk(self, apk_file):
return self.make_request('apks', 'upload',
media_body=apk_file)
def publish_release(self, options, versionCodes):
return self.make_request('tracks', 'update',
track="alpha",
body={'versionCodes': versionCodes})
def gen_version_code(platform_index, base_version):
str_version = "{platform}{base_version}".format(
platform=platform_index,
base_version=base_version
)
return int(str_version)
if __name__ == "__main__":
options = parse_args()
func = globals()['do_{}'.format(options.step)]
func(options)

View File

@ -48,35 +48,15 @@ def parse_args():
help=("Specify the architecture to build for ios application/libraries.\n" help=("Specify the architecture to build for ios application/libraries.\n"
"Can be specified several times to build for several architectures.\n" "Can be specified several times to build for several architectures.\n"
"If not specified, all architectures will be build.")) "If not specified, all architectures will be build."))
subgroup = parser.add_argument_group('custom app',
description="Android custom app specific options")
subgroup.add_argument('--android-custom-app',
help="The custom android app to build")
subgroup.add_argument('--zim-file-url',
help="The url of the zim file to download")
subgroup.add_argument('--zim-file-size',
help="The size of the zim file.")
options = parser.parse_args() options = parser.parse_args()
if options.target == 'kiwix-android-custom':
err = False
if not options.android_custom_app:
print("You need to specify ANDROID_CUSTOM_APP if you "
"want to build a kiwix-android-custom target")
err = True
if not options.zim_file_url and not options.zim_file_size:
print("You need to specify ZIM_FILE_SIZE or ZIM_FILE_URL if you "
"want to build a kiwix-android-custom target")
err = True
if err:
sys.exit(1)
if not options.android_arch: if not options.android_arch:
options.android_arch = ['arm', 'arm64', 'x86', 'x86_64'] options.android_arch = ['arm', 'arm64', 'x86', 'x86_64']
if not options.ios_arch: if not options.ios_arch:
options.ios_arch = ['armv7', 'arm64', 'i386', 'x86_64'] options.ios_arch = ['armv7', 'arm64', 'i386', 'x86_64']
if not options.target_platform: if not options.target_platform:
if options.target in ('kiwix-android', 'kiwix-android-custom'): if options.target in ('kiwix-lib-app',):
options.target_platform = 'android' options.target_platform = 'android'
else: else:
options.target_platform = 'native_dyn' options.target_platform = 'native_dyn'

View File

@ -7,13 +7,10 @@ from . import (
aria2, aria2,
armhf, armhf,
flatpak, flatpak,
gradle,
gumbo, gumbo,
icu4c, icu4c,
ios_fat_lib, ios_fat_lib,
mustache, mustache,
kiwix_android,
kiwix_custom_app,
kiwix_desktop, kiwix_desktop,
kiwix_lib, kiwix_lib,
kiwix_tools, kiwix_tools,

View File

@ -525,7 +525,7 @@ class GradleBuilder(Builder):
shutil.copytree(self.source_path, self.build_path) shutil.copytree(self.source_path, self.build_path)
def _compile(self, context): def _compile(self, context):
command = "gradle {gradle_target} {gradle_option}" command = "./gradlew {gradle_target} {gradle_option}"
command = command.format( command = command.format(
gradle_target=self.gradle_target, gradle_target=self.gradle_target,
gradle_option=self.gradle_option) gradle_option=self.gradle_option)

View File

@ -1,32 +0,0 @@
from .base import (
Dependency,
ReleaseDownload,
Builder as BaseBuilder)
from kiwixbuild.utils import Remotefile, pj, copy_tree, add_execution_right
class Gradle(Dependency):
neutral = True
name = "gradle"
class Source(ReleaseDownload):
archive = Remotefile('gradle-5.2-bin.zip',
'ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f',
'https://services.gradle.org/distributions/gradle-5.2-bin.zip')
class Builder(BaseBuilder):
@property
def install_path(self):
return self.buildEnv.install_dir
def build(self):
self.command('install', self._install)
def _install(self, context):
copy_tree(
pj(self.source_path, "bin"),
pj(self.install_path, "bin"),
post_copy_function = add_execution_right)
copy_tree(
pj(self.source_path, "lib"),
pj(self.install_path, "lib"))

View File

@ -1,64 +0,0 @@
import shutil, os
from .base import (
Dependency,
GitClone,
GradleBuilder)
from kiwixbuild.utils import pj, copy_tree
from kiwixbuild._global import option, get_target_step
class KiwixAndroid(Dependency):
name = "kiwix-android"
class Source(GitClone):
git_remote = "https://github.com/kiwix/kiwix-android"
git_dir = "kiwix-android"
class Builder(GradleBuilder):
dependencies = ["kiwix-lib"]
@classmethod
def get_dependencies(cls, platformInfo, allDeps):
if not allDeps:
return super().get_dependencies(platformInfo, allDeps)
else:
deps = [('android_{}'.format(arch), 'kiwix-lib')
for arch in option('android_arch')]
return deps
def build(self):
if option('target') == 'kiwix-android-custom':
print("SKIP")
else:
super().build()
def _configure(self, context):
if not os.path.exists(self.build_path):
shutil.copytree(self.source_path, self.build_path, symlinks=True)
try:
shutil.rmtree(pj(self.build_path, 'kiwixlib', 'src', 'main'))
except FileNotFoundError:
pass
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
copy_tree(pj(kiwix_builder.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
os.makedirs(
pj(self.build_path, 'app', 'src', 'main', 'assets', 'icu'),
exist_ok=True)
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
shutil.copy2(pj(kiwix_builder.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
break

View File

@ -1,120 +0,0 @@
import shutil, os, json
from urllib.parse import urlparse
from .base import (
Dependency,
GitClone,
GradleBuilder)
from kiwixbuild.utils import Remotefile, pj, copy_tree, SkipCommand, run_command
from kiwixbuild._global import option, get_target_step
class KiwixCustomApp(Dependency):
name = "kiwix-android-custom"
class Source(GitClone):
git_remote = "https://github.com/kiwix/kiwix-android-custom"
git_dir = "kiwix-android-custom"
class Builder(GradleBuilder):
dependencies = ["kiwix-android", "kiwix-lib"]
@property
def gradle_target(self):
return "assemble{}".format(option('android_custom_app'))
@property
def gradle_option(self):
template = ("-i -P customDir={customDir}"
" -P zim_file_size={zim_size}"
" -P version_code={version_code}"
" -P version_name={version_name}"
" -P content_version_code={content_version_code}")
return template.format(
customDir=pj(self.build_path, 'custom'),
zim_size=self._get_zim_size(),
version_code=os.environ['VERSION_CODE'],
version_name=os.environ['VERSION_NAME'],
content_version_code=os.environ['CONTENT_VERSION_CODE'])
@property
def build_path(self):
return pj(self.buildEnv.build_dir, "{}_{}".format(self.target.full_name(), option('android_custom_app')))
@property
def custom_build_path(self):
return pj(self.build_path, 'custom', option('android_custom_app'))
def _get_zim_size(self):
try:
zim_size = option('zim_file_size')
except AttributeError:
with open(pj(self.source_path, option('android_custom_app'), 'info.json')) as f:
app_info = json.load(f)
zim_size = os.path.getsize(pj(self.custom_build_path, app_info['zim_file']))
return zim_size
def build(self):
self.command('configure', self._configure)
self.command('download_zim', self._download_zim)
self.command('compile', self._compile)
def _download_zim(self, context):
zim_url = option('zim_file_url')
if zim_url is None:
raise SkipCommand()
with open(pj(self.source_path, option('android_custom_app'), 'info.json')) as f:
app_info = json.load(f)
zim_url = app_info.get('zim_url', zim_url)
out_filename = urlparse(zim_url).path
out_filename = os.path.basename(out_filename)
zim_file = Remotefile(out_filename, '', zim_url)
self.buildEnv.download(zim_file)
shutil.copy(pj(self.buildEnv.archive_dir, out_filename),
pj(self.custom_build_path, app_info['zim_file']))
def _configure(self, context):
# Copy kiwix-android in build dir.
kiwix_android_source = get_target_step('kiwix-android', 'source')
if not os.path.exists(self.build_path):
shutil.copytree(kiwix_android_source.source_path, self.build_path)
# Copy kiwix-lib application in build dir
try:
shutil.rmtree(pj(self.build_path, 'kiwixlib', 'src', 'main'))
except FileNotFoundError:
pass
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
copy_tree(pj(kiwix_builder.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
os.makedirs(
pj(self.build_path, 'app', 'src', 'main', 'assets', 'icu'),
exist_ok=True)
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
shutil.copy2(pj(kiwix_builder.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
break
# Generate custom directory
try:
shutil.rmtree(pj(self.build_path, 'custom'))
except FileNotFoundError:
pass
os.makedirs(pj(self.build_path, 'custom'))
command = "./gen-custom-android-directory.py {custom_name} --output-dir {custom_dir}"
command = command.format(
custom_name=option('android_custom_app'),
custom_dir=pj(self.build_path, 'custom', option('android_custom_app'))
)
run_command(command, self.source_path, context, buildEnv=self.buildEnv)

View File

@ -123,7 +123,7 @@ class AndroidX8664(AndroidPlatformInfo):
class Android(MetaPlatformInfo): class Android(MetaPlatformInfo):
name = "android" name = "android"
toolchain_names = ['android-sdk', 'gradle'] toolchain_names = ['android-sdk']
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ['fedora', 'debian']
@property @property
@ -131,7 +131,7 @@ class Android(MetaPlatformInfo):
return ['android_{}'.format(arch) for arch in option('android_arch')] return ['android_{}'.format(arch) for arch in option('android_arch')]
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
if targetName not in ('kiwix-android', 'kiwix-android-custom', 'kiwix-lib-app'): if targetName not in ('kiwix-lib-app',):
return super().add_targets(targetName, targets) return super().add_targets(targetName, targets)
else: else:
return AndroidPlatformInfo.add_targets(self, targetName, targets) return AndroidPlatformInfo.add_targets(self, targetName, targets)
@ -143,10 +143,5 @@ class Android(MetaPlatformInfo):
def sdk_builder(self): def sdk_builder(self):
return get_target_step('android-sdk', 'neutral') return get_target_step('android-sdk', 'neutral')
@property
def gradle_builder(self):
return get_target_step('gradle', 'neutral')
def set_env(self, env): def set_env(self, env):
env['ANDROID_HOME'] = self.sdk_builder.install_path env['ANDROID_HOME'] = self.sdk_builder.install_path
env['PATH'] = ':'.join([pj(self.gradle_builder.install_path, 'bin'), env['PATH']])

View File

@ -112,7 +112,6 @@ class MetaPlatformInfo(PlatformInfo):
def add_targets(self, targetName, targets): def add_targets(self, targetName, targets):
targetDefs = [] targetDefs = []
for platformName in self.subPlatformNames: for platformName in self.subPlatformNames:
print("radd {}".format(platformName))
platform = self.get_platform(platformName, targets) platform = self.get_platform(platformName, targets)
targetDefs += platform.add_targets(targetName, targets) targetDefs += platform.add_targets(targetName, targets)
return targetDefs return targetDefs

View File

@ -54,7 +54,6 @@ base_deps_versions = {
'libmicrohttpd' : '0.9.66', 'libmicrohttpd' : '0.9.66',
'gumbo' : '0.10.1', 'gumbo' : '0.10.1',
'icu4c' : '58.2', 'icu4c' : '58.2',
'gradle' : '5.2',
'libaria2' : '1.33.1', 'libaria2' : '1.33.1',
'libmagic' : '5.35', 'libmagic' : '5.35',
'android-sdk' : 'r25.2.3', 'android-sdk' : 'r25.2.3',

View File

@ -1,3 +0,0 @@
requests==2.20.0
apiclient==1.0.3

View File

@ -91,7 +91,7 @@ def run_kiwix_build(target, platform,
command.append('--hide-progress') command.append('--hide-progress')
if platform == 'flatpak' or platform.startswith('win32_'): if platform == 'flatpak' or platform.startswith('win32_'):
command.append('--assume-packages-installed') command.append('--assume-packages-installed')
if target == 'kiwix-android' and platform.startswith('android_'): if target == 'kiwix-lib-app' and platform.startswith('android_'):
command.extend(['--target-platform', 'android', '--android-arch', platform[8:]]) command.extend(['--target-platform', 'android', '--android-arch', platform[8:]])
elif platform == 'android': elif platform == 'android':
command.extend(['--target-platform', 'android']) command.extend(['--target-platform', 'android'])

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -e
cd ${HOME}
${TRAVIS_BUILD_DIR}/kiwix-build.py \
--target-platform $PLATFORM \
--hide-progress \
--android-custom-app $CUSTOM_APP \
--zim-file-size $ZIM_FILE_SIZE \
kiwix-android-custom

View File

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
KEYSTORE_FILE=${TRAVIS_BUILD_DIR}/travis/kiwix-android.keystore
GOOGLE_API_KEY=${TRAVIS_BUILD_DIR}/travis/googleplay_android_developer-5a411156212c.json
cd ${HOME}
# Sign apk file
BASE_DIR="BUILD_${PLATFORM}"
INPUT_APK_FILE=${BASE_DIR}/kiwix-android-custom_${CUSTOM_APP}/app/build/outputs/apk/${CUSTOM_APP}/release/app-${CUSTOM_APP}-release-unsigned.apk
SIGNED_APK=${BASE_DIR}/app-${CUSTOM_APP}_${VERSION_CODE}-release-signed.apk
TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign \
--ks ${KEYSTORE_FILE} \
--ks-pass env:KEYSTORE_PASS \
--out ${SIGNED_APK} \
${INPUT_APK_FILE}
ssh -i ${SSH_KEY} ci@download.kiwix.org "mkdir -p ${DEPLOY_DIR}"
scp -i ${SSH_KEY} \
${SIGNED_APK} \
ci@download.kiwix.org:${DEPLOY_DIR}

Binary file not shown.

View File

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
KEYSTORE_FILE=${TRAVIS_BUILD_DIR}/travis/test_ks.ks
GOOGLE_API_KEY=${TRAVIS_BUILD_DIR}/travis/googleplay_android_developer-5a411156212c.json
cd ${HOME}
BASE_DIR="BUILD_${PLATFORM}"
mkdir -p ${HOME}/APKS
scp -i ${SSH_KEY} ci@download.kiwix.org:${DEPLOY_DIR}/* ${HOME}/APKS
ssh -i ${SSH_KEY} ci@download.kiwix.org "rm -rf ${DEPLOY_DIR}"
${TRAVIS_BUILD_DIR}/build_custom_app.py \
--step publish \
--custom-app ${CUSTOM_APP} \
--package-name ${PACKAGE_NAME} \
--google-api-key ${GOOGLE_API_KEY} \
--zim-url ${ZIM_URL} \
--apks-dir ${HOME}/APKS \
--content-version-code ${CONTENT_VERSION_CODE}