Merge commit 'upstream-main' into master
Bug: 261600888 Test: none, build files to be updated in follow up cl Change-Id: Ib520938290c6bbdee4a9f73b6419b6c947a96ec4
This commit is contained in:
@ -1 +1 @@
|
||||
sakal@webrtc.org
|
||||
xalep@webrtc.org
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env vpython3
|
||||
|
||||
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
@ -7,7 +7,6 @@
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
"""Script to generate libwebrtc.aar for distribution.
|
||||
|
||||
The script has to be run from the root src folder.
|
||||
@ -33,7 +32,6 @@ import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
|
||||
DEFAULT_ARCHS = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']
|
||||
@ -41,8 +39,8 @@ NEEDED_SO_FILES = ['libjingle_peerconnection_so.so']
|
||||
JAR_FILE = 'lib.java/sdk/android/libwebrtc.jar'
|
||||
MANIFEST_FILE = 'sdk/android/AndroidManifest.xml'
|
||||
TARGETS = [
|
||||
'sdk/android:libwebrtc',
|
||||
'sdk/android:libjingle_peerconnection_so',
|
||||
'sdk/android:libwebrtc',
|
||||
'sdk/android:libjingle_peerconnection_so',
|
||||
]
|
||||
|
||||
sys.path.append(os.path.join(SCRIPT_DIR, '..', 'libs'))
|
||||
@ -52,32 +50,58 @@ sys.path.append(os.path.join(SRC_DIR, 'build'))
|
||||
import find_depot_tools
|
||||
|
||||
|
||||
|
||||
def _ParseArgs():
|
||||
parser = argparse.ArgumentParser(description='libwebrtc.aar generator.')
|
||||
parser.add_argument('--build-dir',
|
||||
parser.add_argument(
|
||||
'--build-dir',
|
||||
type=os.path.abspath,
|
||||
help='Build dir. By default will create and use temporary dir.')
|
||||
parser.add_argument('--output', default='libwebrtc.aar',
|
||||
help='Output file of the script.')
|
||||
parser.add_argument('--arch', default=DEFAULT_ARCHS, nargs='*',
|
||||
help='Architectures to build. Defaults to %(default)s.')
|
||||
parser.add_argument('--use-goma', action='store_true', default=False,
|
||||
help='Use goma.')
|
||||
parser.add_argument('--verbose', action='store_true', default=False,
|
||||
help='Debug logging.')
|
||||
parser.add_argument('--extra-gn-args', default=[], nargs='*',
|
||||
parser.add_argument('--output',
|
||||
default='libwebrtc.aar',
|
||||
type=os.path.abspath,
|
||||
help='Output file of the script.')
|
||||
parser.add_argument('--arch',
|
||||
default=DEFAULT_ARCHS,
|
||||
nargs='*',
|
||||
help='Architectures to build. Defaults to %(default)s.')
|
||||
parser.add_argument('--use-goma',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Use goma.')
|
||||
parser.add_argument('--use-remoteexec',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Use RBE.')
|
||||
parser.add_argument('--use-unstripped-libs',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Use unstripped .so files within libwebrtc.aar')
|
||||
parser.add_argument('--verbose',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Debug logging.')
|
||||
parser.add_argument(
|
||||
'--extra-gn-args',
|
||||
default=[],
|
||||
nargs='*',
|
||||
help="""Additional GN arguments to be used during Ninja generation.
|
||||
These are passed to gn inside `--args` switch and
|
||||
applied after any other arguments and will
|
||||
override any values defined by the script.
|
||||
Example of building debug aar file:
|
||||
build_aar.py --extra-gn-args='is_debug=true'""")
|
||||
parser.add_argument('--extra-ninja-switches', default=[], nargs='*',
|
||||
parser.add_argument(
|
||||
'--extra-ninja-switches',
|
||||
default=[],
|
||||
nargs='*',
|
||||
help="""Additional Ninja switches to be used during compilation.
|
||||
These are applied after any other Ninja switches.
|
||||
Example of enabling verbose Ninja output:
|
||||
build_aar.py --extra-ninja-switches='-v'""")
|
||||
parser.add_argument('--extra-gn-switches', default=[], nargs='*',
|
||||
parser.add_argument(
|
||||
'--extra-gn-switches',
|
||||
default=[],
|
||||
nargs='*',
|
||||
help="""Additional GN switches to be used during compilation.
|
||||
These are applied after any other GN switches.
|
||||
Example of enabling verbose GN output:
|
||||
@ -86,16 +110,20 @@ def _ParseArgs():
|
||||
|
||||
|
||||
def _RunGN(args):
|
||||
cmd = [sys.executable,
|
||||
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py')]
|
||||
cmd = [
|
||||
sys.executable,
|
||||
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py')
|
||||
]
|
||||
cmd.extend(args)
|
||||
logging.debug('Running: %r', cmd)
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def _RunNinja(output_directory, args):
|
||||
cmd = [os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'ninja'),
|
||||
'-C', output_directory]
|
||||
cmd = [
|
||||
os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'ninja'), '-C',
|
||||
output_directory
|
||||
]
|
||||
cmd.extend(args)
|
||||
logging.debug('Running: %r', cmd)
|
||||
subprocess.check_call(cmd)
|
||||
@ -105,10 +133,9 @@ def _EncodeForGN(value):
|
||||
"""Encodes value as a GN literal."""
|
||||
if isinstance(value, str):
|
||||
return '"' + value + '"'
|
||||
elif isinstance(value, bool):
|
||||
if isinstance(value, bool):
|
||||
return repr(value).lower()
|
||||
else:
|
||||
return repr(value)
|
||||
return repr(value)
|
||||
|
||||
|
||||
def _GetOutputDirectory(build_dir, arch):
|
||||
@ -120,53 +147,52 @@ def _GetTargetCpu(arch):
|
||||
"""Returns target_cpu for the GN build with the given architecture."""
|
||||
if arch in ['armeabi', 'armeabi-v7a']:
|
||||
return 'arm'
|
||||
elif arch == 'arm64-v8a':
|
||||
if arch == 'arm64-v8a':
|
||||
return 'arm64'
|
||||
elif arch == 'x86':
|
||||
if arch == 'x86':
|
||||
return 'x86'
|
||||
elif arch == 'x86_64':
|
||||
if arch == 'x86_64':
|
||||
return 'x64'
|
||||
else:
|
||||
raise Exception('Unknown arch: ' + arch)
|
||||
raise Exception('Unknown arch: ' + arch)
|
||||
|
||||
|
||||
def _GetArmVersion(arch):
|
||||
"""Returns arm_version for the GN build with the given architecture."""
|
||||
if arch == 'armeabi':
|
||||
return 6
|
||||
elif arch == 'armeabi-v7a':
|
||||
if arch == 'armeabi-v7a':
|
||||
return 7
|
||||
elif arch in ['arm64-v8a', 'x86', 'x86_64']:
|
||||
if arch in ['arm64-v8a', 'x86', 'x86_64']:
|
||||
return None
|
||||
else:
|
||||
raise Exception('Unknown arch: ' + arch)
|
||||
raise Exception('Unknown arch: ' + arch)
|
||||
|
||||
|
||||
def Build(build_dir, arch, use_goma, extra_gn_args, extra_gn_switches,
|
||||
extra_ninja_switches):
|
||||
def Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
|
||||
extra_gn_switches, extra_ninja_switches):
|
||||
"""Generates target architecture using GN and builds it using ninja."""
|
||||
logging.info('Building: %s', arch)
|
||||
output_directory = _GetOutputDirectory(build_dir, arch)
|
||||
gn_args = {
|
||||
'target_os': 'android',
|
||||
'is_debug': False,
|
||||
'is_component_build': False,
|
||||
'rtc_include_tests': False,
|
||||
'target_cpu': _GetTargetCpu(arch),
|
||||
'use_goma': use_goma
|
||||
'target_os': 'android',
|
||||
'is_debug': False,
|
||||
'is_component_build': False,
|
||||
'rtc_include_tests': False,
|
||||
'target_cpu': _GetTargetCpu(arch),
|
||||
'use_goma': use_goma,
|
||||
'use_remoteexec': use_remoteexec,
|
||||
}
|
||||
arm_version = _GetArmVersion(arch)
|
||||
if arm_version:
|
||||
gn_args['arm_version'] = arm_version
|
||||
gn_args_str = '--args=' + ' '.join([
|
||||
k + '=' + _EncodeForGN(v) for k, v in gn_args.items()] + extra_gn_args)
|
||||
gn_args_str = '--args=' + ' '.join(
|
||||
[k + '=' + _EncodeForGN(v) for k, v in gn_args.items()] + extra_gn_args)
|
||||
|
||||
gn_args_list = ['gen', output_directory, gn_args_str]
|
||||
gn_args_list.extend(extra_gn_switches)
|
||||
_RunGN(gn_args_list)
|
||||
|
||||
ninja_args = TARGETS[:]
|
||||
if use_goma:
|
||||
if use_goma or use_remoteexec:
|
||||
ninja_args.extend(['-j', '200'])
|
||||
ninja_args.extend(extra_ninja_switches)
|
||||
_RunNinja(output_directory, ninja_args)
|
||||
@ -180,14 +206,16 @@ def CollectCommon(aar_file, build_dir, arch):
|
||||
aar_file.write(os.path.join(output_directory, JAR_FILE), 'classes.jar')
|
||||
|
||||
|
||||
def Collect(aar_file, build_dir, arch):
|
||||
def Collect(aar_file, build_dir, arch, unstripped):
|
||||
"""Collects architecture specific files into the .aar-archive."""
|
||||
logging.info('Collecting: %s', arch)
|
||||
output_directory = _GetOutputDirectory(build_dir, arch)
|
||||
|
||||
abi_dir = os.path.join('jni', arch)
|
||||
for so_file in NEEDED_SO_FILES:
|
||||
aar_file.write(os.path.join(output_directory, so_file),
|
||||
source_so_file = os.path.join("lib.unstripped",
|
||||
so_file) if unstripped else so_file
|
||||
aar_file.write(os.path.join(output_directory, source_so_file),
|
||||
os.path.join(abi_dir, so_file))
|
||||
|
||||
|
||||
@ -197,23 +225,29 @@ def GenerateLicenses(output_dir, build_dir, archs):
|
||||
builder.GenerateLicenseText(output_dir)
|
||||
|
||||
|
||||
def BuildAar(archs, output_file, use_goma=False, extra_gn_args=None,
|
||||
ext_build_dir=None, extra_gn_switches=None,
|
||||
extra_ninja_switches=None):
|
||||
def BuildAar(archs,
|
||||
output_file,
|
||||
use_goma=False,
|
||||
use_remoteexec=False,
|
||||
extra_gn_args=None,
|
||||
ext_build_dir=None,
|
||||
extra_gn_switches=None,
|
||||
extra_ninja_switches=None,
|
||||
unstripped=False):
|
||||
extra_gn_args = extra_gn_args or []
|
||||
extra_gn_switches = extra_gn_switches or []
|
||||
extra_ninja_switches = extra_ninja_switches or []
|
||||
build_dir = ext_build_dir if ext_build_dir else tempfile.mkdtemp()
|
||||
|
||||
for arch in archs:
|
||||
Build(build_dir, arch, use_goma, extra_gn_args, extra_gn_switches,
|
||||
extra_ninja_switches)
|
||||
Build(build_dir, arch, use_goma, use_remoteexec, extra_gn_args,
|
||||
extra_gn_switches, extra_ninja_switches)
|
||||
|
||||
with zipfile.ZipFile(output_file, 'w') as aar_file:
|
||||
# Architecture doesn't matter here, arbitrarily using the first one.
|
||||
CollectCommon(aar_file, build_dir, archs[0])
|
||||
for arch in archs:
|
||||
Collect(aar_file, build_dir, arch)
|
||||
Collect(aar_file, build_dir, arch, unstripped)
|
||||
|
||||
license_dir = os.path.dirname(os.path.realpath(output_file))
|
||||
GenerateLicenses(license_dir, build_dir, archs)
|
||||
@ -226,8 +260,9 @@ def main():
|
||||
args = _ParseArgs()
|
||||
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
|
||||
|
||||
BuildAar(args.arch, args.output, args.use_goma, args.extra_gn_args,
|
||||
args.build_dir, args.extra_gn_switches, args.extra_ninja_switches)
|
||||
BuildAar(args.arch, args.output, args.use_goma, args.use_remoteexec,
|
||||
args.extra_gn_args, args.build_dir, args.extra_gn_switches,
|
||||
args.extra_ninja_switches, args.use_unstripped_libs)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -1,291 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
"""Script for publishing WebRTC AAR on Bintray.
|
||||
|
||||
Set BINTRAY_USER and BINTRAY_API_KEY environment variables before running
|
||||
this script for authentication.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
CHECKOUT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
|
||||
|
||||
sys.path.append(os.path.join(CHECKOUT_ROOT, 'third_party'))
|
||||
import requests
|
||||
import jinja2
|
||||
|
||||
sys.path.append(os.path.join(CHECKOUT_ROOT, 'tools_webrtc'))
|
||||
from android.build_aar import BuildAar
|
||||
|
||||
|
||||
ARCHS = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']
|
||||
MAVEN_REPOSITORY = 'https://google.bintray.com/webrtc'
|
||||
API = 'https://api.bintray.com'
|
||||
PACKAGE_PATH = 'google/webrtc/google-webrtc'
|
||||
CONTENT_API = API + '/content/' + PACKAGE_PATH
|
||||
PACKAGES_API = API + '/packages/' + PACKAGE_PATH
|
||||
GROUP_ID = 'org/webrtc'
|
||||
ARTIFACT_ID = 'google-webrtc'
|
||||
COMMIT_POSITION_REGEX = r'^Cr-Commit-Position: refs/heads/master@{#(\d+)}$'
|
||||
API_TIMEOUT_SECONDS = 10.0
|
||||
UPLOAD_TRIES = 3
|
||||
# The sleep time is increased exponentially.
|
||||
UPLOAD_RETRY_BASE_SLEEP_SECONDS = 2.0
|
||||
GRADLEW_BIN = os.path.join(CHECKOUT_ROOT,
|
||||
'examples/androidtests/third_party/gradle/gradlew')
|
||||
ADB_BIN = os.path.join(CHECKOUT_ROOT,
|
||||
'third_party/android_sdk/public/platform-tools/adb')
|
||||
AAR_PROJECT_DIR = os.path.join(CHECKOUT_ROOT, 'examples/aarproject')
|
||||
AAR_PROJECT_GRADLE = os.path.join(AAR_PROJECT_DIR, 'build.gradle')
|
||||
AAR_PROJECT_APP_GRADLE = os.path.join(AAR_PROJECT_DIR, 'app', 'build.gradle')
|
||||
AAR_PROJECT_DEPENDENCY = "implementation 'org.webrtc:google-webrtc:1.0.+'"
|
||||
AAR_PROJECT_VERSION_DEPENDENCY = "implementation 'org.webrtc:google-webrtc:%s'"
|
||||
|
||||
|
||||
def _ParseArgs():
|
||||
parser = argparse.ArgumentParser(description='Releases WebRTC on Bintray.')
|
||||
parser.add_argument('--use-goma', action='store_true', default=False,
|
||||
help='Use goma.')
|
||||
parser.add_argument('--skip-tests', action='store_true', default=False,
|
||||
help='Skips running the tests.')
|
||||
parser.add_argument('--publish', action='store_true', default=False,
|
||||
help='Automatically publishes the library if the tests pass.')
|
||||
parser.add_argument('--build-dir', default=None,
|
||||
help='Temporary directory to store the build files. If not specified, '
|
||||
'a new directory will be created.')
|
||||
parser.add_argument('--verbose', action='store_true', default=False,
|
||||
help='Debug logging.')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def _GetCommitHash():
|
||||
commit_hash = subprocess.check_output(
|
||||
['git', 'rev-parse', 'HEAD'], cwd=CHECKOUT_ROOT).strip()
|
||||
return commit_hash
|
||||
|
||||
|
||||
def _GetCommitPos():
|
||||
commit_message = subprocess.check_output(
|
||||
['git', 'rev-list', '--format=%B', '--max-count=1', 'HEAD'],
|
||||
cwd=CHECKOUT_ROOT)
|
||||
commit_pos_match = re.search(
|
||||
COMMIT_POSITION_REGEX, commit_message, re.MULTILINE)
|
||||
if not commit_pos_match:
|
||||
raise Exception('Commit position not found in the commit message: %s'
|
||||
% commit_message)
|
||||
return commit_pos_match.group(1)
|
||||
|
||||
|
||||
def _UploadFile(user, password, filename, version, target_file):
|
||||
# URL is of format:
|
||||
# <repository_api>/<version>/<group_id>/<artifact_id>/<version>/<target_file>
|
||||
# Example:
|
||||
# https://api.bintray.com/content/google/webrtc/google-webrtc/1.0.19742/org/webrtc/google-webrtc/1.0.19742/google-webrtc-1.0.19742.aar
|
||||
|
||||
target_dir = version + '/' + GROUP_ID + '/' + ARTIFACT_ID + '/' + version
|
||||
target_path = target_dir + '/' + target_file
|
||||
url = CONTENT_API + '/' + target_path
|
||||
|
||||
logging.info('Uploading %s to %s', filename, url)
|
||||
with open(filename) as fh:
|
||||
file_data = fh.read()
|
||||
|
||||
for attempt in xrange(UPLOAD_TRIES):
|
||||
try:
|
||||
response = requests.put(url, data=file_data, auth=(user, password),
|
||||
timeout=API_TIMEOUT_SECONDS)
|
||||
break
|
||||
except requests.exceptions.Timeout as e:
|
||||
logging.warning('Timeout while uploading: %s', e)
|
||||
time.sleep(UPLOAD_RETRY_BASE_SLEEP_SECONDS ** attempt)
|
||||
else:
|
||||
raise Exception('Failed to upload %s' % filename)
|
||||
|
||||
if not response.ok:
|
||||
raise Exception('Failed to upload %s. Response: %s' % (filename, response))
|
||||
logging.info('Uploaded %s: %s', filename, response)
|
||||
|
||||
|
||||
def _GeneratePom(target_file, version, commit):
|
||||
env = jinja2.Environment(
|
||||
loader=jinja2.PackageLoader('release_aar'),
|
||||
)
|
||||
template = env.get_template('pom.jinja')
|
||||
pom = template.render(version=version, commit=commit)
|
||||
with open(target_file, 'w') as fh:
|
||||
fh.write(pom)
|
||||
|
||||
|
||||
def _TestAAR(tmp_dir, username, password, version):
|
||||
"""Runs AppRTCMobile tests using the AAR. Returns true if the tests pass."""
|
||||
logging.info('Testing library.')
|
||||
env = jinja2.Environment(
|
||||
loader=jinja2.PackageLoader('release_aar'),
|
||||
)
|
||||
|
||||
gradle_backup = os.path.join(tmp_dir, 'build.gradle.backup')
|
||||
app_gradle_backup = os.path.join(tmp_dir, 'app-build.gradle.backup')
|
||||
|
||||
# Make backup copies of the project files before modifying them.
|
||||
shutil.copy2(AAR_PROJECT_GRADLE, gradle_backup)
|
||||
shutil.copy2(AAR_PROJECT_APP_GRADLE, app_gradle_backup)
|
||||
|
||||
try:
|
||||
maven_repository_template = env.get_template('maven-repository.jinja')
|
||||
maven_repository = maven_repository_template.render(
|
||||
url=MAVEN_REPOSITORY, username=username, password=password)
|
||||
|
||||
# Append Maven repository to build file to download unpublished files.
|
||||
with open(AAR_PROJECT_GRADLE, 'a') as gradle_file:
|
||||
gradle_file.write(maven_repository)
|
||||
|
||||
# Read app build file.
|
||||
with open(AAR_PROJECT_APP_GRADLE, 'r') as gradle_app_file:
|
||||
gradle_app = gradle_app_file.read()
|
||||
|
||||
if AAR_PROJECT_DEPENDENCY not in gradle_app:
|
||||
raise Exception(
|
||||
'%s not found in the build file.' % AAR_PROJECT_DEPENDENCY)
|
||||
# Set version to the version to be tested.
|
||||
target_dependency = AAR_PROJECT_VERSION_DEPENDENCY % version
|
||||
gradle_app = gradle_app.replace(AAR_PROJECT_DEPENDENCY, target_dependency)
|
||||
|
||||
# Write back.
|
||||
with open(AAR_PROJECT_APP_GRADLE, 'w') as gradle_app_file:
|
||||
gradle_app_file.write(gradle_app)
|
||||
|
||||
# Uninstall any existing version of AppRTCMobile.
|
||||
logging.info('Uninstalling previous AppRTCMobile versions. It is okay for '
|
||||
'these commands to fail if AppRTCMobile is not installed.')
|
||||
subprocess.call([ADB_BIN, 'uninstall', 'org.appspot.apprtc'])
|
||||
subprocess.call([ADB_BIN, 'uninstall', 'org.appspot.apprtc.test'])
|
||||
|
||||
# Run tests.
|
||||
try:
|
||||
# First clean the project.
|
||||
subprocess.check_call([GRADLEW_BIN, 'clean'], cwd=AAR_PROJECT_DIR)
|
||||
# Then run the tests.
|
||||
subprocess.check_call([GRADLEW_BIN, 'connectedDebugAndroidTest'],
|
||||
cwd=AAR_PROJECT_DIR)
|
||||
except subprocess.CalledProcessError:
|
||||
logging.exception('Test failure.')
|
||||
return False # Clean or tests failed
|
||||
|
||||
return True # Tests pass
|
||||
finally:
|
||||
# Restore backups.
|
||||
shutil.copy2(gradle_backup, AAR_PROJECT_GRADLE)
|
||||
shutil.copy2(app_gradle_backup, AAR_PROJECT_APP_GRADLE)
|
||||
|
||||
|
||||
def _PublishAAR(user, password, version, additional_args):
|
||||
args = {
|
||||
'publish_wait_for_secs': 0 # Publish asynchronously.
|
||||
}
|
||||
args.update(additional_args)
|
||||
|
||||
url = CONTENT_API + '/' + version + '/publish'
|
||||
response = requests.post(url, data=json.dumps(args), auth=(user, password),
|
||||
timeout=API_TIMEOUT_SECONDS)
|
||||
|
||||
if not response.ok:
|
||||
raise Exception('Failed to publish. Response: %s' % response)
|
||||
|
||||
|
||||
def _DeleteUnpublishedVersion(user, password, version):
|
||||
url = PACKAGES_API + '/versions/' + version
|
||||
response = requests.get(url, auth=(user, password),
|
||||
timeout=API_TIMEOUT_SECONDS)
|
||||
if not response.ok:
|
||||
raise Exception('Failed to get version info. Response: %s' % response)
|
||||
|
||||
version_info = json.loads(response.content)
|
||||
if version_info['published']:
|
||||
logging.info('Version has already been published, not deleting.')
|
||||
return
|
||||
|
||||
logging.info('Deleting unpublished version.')
|
||||
response = requests.delete(url, auth=(user, password),
|
||||
timeout=API_TIMEOUT_SECONDS)
|
||||
if not response.ok:
|
||||
raise Exception('Failed to delete version. Response: %s' % response)
|
||||
|
||||
|
||||
def ReleaseAar(use_goma, skip_tests, publish, build_dir):
|
||||
version = '1.0.' + _GetCommitPos()
|
||||
commit = _GetCommitHash()
|
||||
logging.info('Releasing AAR version %s with hash %s', version, commit)
|
||||
|
||||
user = os.environ.get('BINTRAY_USER', None)
|
||||
api_key = os.environ.get('BINTRAY_API_KEY', None)
|
||||
if not user or not api_key:
|
||||
raise Exception('Environment variables BINTRAY_USER and BINTRAY_API_KEY '
|
||||
'must be defined.')
|
||||
|
||||
# If build directory is not specified, create a temporary directory.
|
||||
use_tmp_dir = not build_dir
|
||||
if use_tmp_dir:
|
||||
build_dir = tempfile.mkdtemp()
|
||||
|
||||
try:
|
||||
base_name = ARTIFACT_ID + '-' + version
|
||||
aar_file = os.path.join(build_dir, base_name + '.aar')
|
||||
third_party_licenses_file = os.path.join(build_dir, 'LICENSE.md')
|
||||
pom_file = os.path.join(build_dir, base_name + '.pom')
|
||||
|
||||
logging.info('Building at %s', build_dir)
|
||||
BuildAar(ARCHS, aar_file,
|
||||
use_goma=use_goma,
|
||||
ext_build_dir=os.path.join(build_dir, 'aar-build'))
|
||||
_GeneratePom(pom_file, version, commit)
|
||||
|
||||
_UploadFile(user, api_key, aar_file, version, base_name + '.aar')
|
||||
_UploadFile(user, api_key, third_party_licenses_file, version,
|
||||
'THIRD_PARTY_LICENSES.md')
|
||||
_UploadFile(user, api_key, pom_file, version, base_name + '.pom')
|
||||
|
||||
tests_pass = skip_tests or _TestAAR(build_dir, user, api_key, version)
|
||||
if not tests_pass:
|
||||
logging.info('Discarding library.')
|
||||
_PublishAAR(user, api_key, version, {'discard': True})
|
||||
_DeleteUnpublishedVersion(user, api_key, version)
|
||||
raise Exception('Test failure. Discarded library.')
|
||||
|
||||
if publish:
|
||||
logging.info('Publishing library.')
|
||||
_PublishAAR(user, api_key, version, {})
|
||||
else:
|
||||
logging.info('Note: The library has not not been published automatically.'
|
||||
' Please do so manually if desired.')
|
||||
finally:
|
||||
if use_tmp_dir:
|
||||
shutil.rmtree(build_dir, True)
|
||||
|
||||
|
||||
def main():
|
||||
args = _ParseArgs()
|
||||
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
|
||||
ReleaseAar(args.use_goma, args.skip_tests, args.publish, args.build_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<lint>
|
||||
<!-- These lint settings is for the Android linter that gets run by
|
||||
lint_action.gypi on compile of WebRTC java code. All WebRTC java code
|
||||
should lint cleanly for the issues below. -->
|
||||
<!-- TODO(phoglund): make work with suppress.py or remove printout referring
|
||||
to suppress.py. -->
|
||||
|
||||
<issue id="UseSparseArrays" severity="ignore"/>
|
||||
|
||||
<issue id="Registered" severity="ignore"/>
|
||||
<issue id="MissingPermission" severity="ignore"/>
|
||||
<issue id="ApplySharedPref" severity="ignore"/>
|
||||
<issue id="UnusedResources" severity="ignore"/>
|
||||
<issue id="IconColors" severity="ignore"/>
|
||||
<issue id="IconDipSize" severity="ignore"/>
|
||||
<issue id="IconDuplicatesConfig" severity="ignore"/>
|
||||
<issue id="RelativeOverlap" severity="ignore"/>
|
||||
<issue id="RtlCompat" severity="ignore"/>
|
||||
<issue id="IconMissingDensityFolder" severity="ignore"/>
|
||||
<issue id="OldTargetApi" severity="ignore"/>
|
||||
|
||||
<issue id="GoogleAppIndexingWarning" severity="ignore"/>
|
||||
<issue id="MissingRegistered" severity="ignore"/>
|
||||
<issue id="LintError">
|
||||
<!-- We no longer supply class files to lint. -->
|
||||
<ignore regexp="No `.class` files were found in project"/>
|
||||
</issue>
|
||||
<!-- These are just from the dummy AndroidManifest.xml we use for linting.
|
||||
It's in the same directory as this file. -->
|
||||
<issue id="MissingApplicationIcon" severity="ignore"/>
|
||||
<issue id="AllowBackup" severity="ignore"/>
|
||||
<issue id="MissingVersion" severity="ignore"/>
|
||||
|
||||
<!-- Ignore all lint errors in Chromium code. -->
|
||||
<issue id="all">
|
||||
<ignore path="**/org/chromium/**/*.java" />
|
||||
</issue>
|
||||
|
||||
<issue id="UsesMinSdkAttributes">
|
||||
<!-- TODO(oprypin): find a way to disable this warning just for Chromium's
|
||||
code, not globally. Due to https://cs.chromium.org/lint_manifest_path
|
||||
it is impossible to discern paths of AndroidManifest.xml files.-->
|
||||
<ignore path="AndroidManifest.xml" />
|
||||
</issue>
|
||||
|
||||
<issue id="NewApi">
|
||||
<!-- This is rewritten by desugar after lint runs. -->
|
||||
<ignore regexp="Call requires API level 19.*`java.util.Objects#requireNonNull`"/>
|
||||
<!-- AutoCloseable has been available since API 15, just hidden. -->
|
||||
<ignore regexp="Class requires API level 19.*java.lang.AutoCloseable"/>
|
||||
<ignore regexp="Call requires API level 19.*java.lang.AutoCloseable#close"/>
|
||||
<!-- We support try-with-resources via desugar. -->
|
||||
<ignore regexp="Try-with-resources requires API level 19"/>
|
||||
<ignore regexp="Call requires API level 19.*`java.lang.Throwable#addSuppressed`"/>
|
||||
<!-- We support new language features via desugar. -->
|
||||
<ignore regexp="Default method requires API level 24"/>
|
||||
<ignore regexp="Static interface method requires API level 24"/>
|
||||
</issue>
|
||||
|
||||
</lint>
|
||||
143
tools_webrtc/android/test_aar.py
Executable file
143
tools_webrtc/android/test_aar.py
Executable file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env vpython3
|
||||
|
||||
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
"""Script for building and testing WebRTC AAR."""
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
CHECKOUT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
|
||||
|
||||
sys.path.append(os.path.join(CHECKOUT_ROOT, 'tools_webrtc'))
|
||||
from android.build_aar import BuildAar
|
||||
|
||||
ARCHS = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']
|
||||
ARTIFACT_ID = 'google-webrtc'
|
||||
COMMIT_POSITION_REGEX = r'^Cr-Commit-Position: refs/heads/master@{#(\d+)}$'
|
||||
GRADLEW_BIN = os.path.join(CHECKOUT_ROOT,
|
||||
'examples/androidtests/third_party/gradle/gradlew')
|
||||
ADB_BIN = os.path.join(CHECKOUT_ROOT,
|
||||
'third_party/android_sdk/public/platform-tools/adb')
|
||||
AAR_PROJECT_DIR = os.path.join(CHECKOUT_ROOT, 'examples/aarproject')
|
||||
|
||||
|
||||
def _ParseArgs():
|
||||
parser = argparse.ArgumentParser(description='Releases WebRTC on Bintray.')
|
||||
parser.add_argument('--use-goma',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Use goma.')
|
||||
parser.add_argument('--skip-tests',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Skips running the tests.')
|
||||
parser.add_argument(
|
||||
'--build-dir',
|
||||
default=None,
|
||||
help='Temporary directory to store the build files. If not specified, '
|
||||
'a new directory will be created.')
|
||||
parser.add_argument('--verbose',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Debug logging.')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def _GetCommitHash():
|
||||
commit_hash = subprocess.check_output(
|
||||
['git', 'rev-parse', 'HEAD'], cwd=CHECKOUT_ROOT).decode('UTF-8').strip()
|
||||
return commit_hash
|
||||
|
||||
|
||||
def _GetCommitPos():
|
||||
commit_message = subprocess.check_output(
|
||||
['git', 'rev-list', '--format=%B', '--max-count=1', 'HEAD'],
|
||||
cwd=CHECKOUT_ROOT).decode('UTF-8')
|
||||
commit_pos_match = re.search(COMMIT_POSITION_REGEX, commit_message,
|
||||
re.MULTILINE)
|
||||
if not commit_pos_match:
|
||||
raise Exception('Commit position not found in the commit message: %s' %
|
||||
commit_message)
|
||||
return commit_pos_match.group(1)
|
||||
|
||||
|
||||
def _TestAAR(build_dir):
|
||||
"""Runs AppRTCMobile tests using the AAR. Returns true if the tests pass."""
|
||||
logging.info('Testing library.')
|
||||
|
||||
# Uninstall any existing version of AppRTCMobile.
|
||||
logging.info('Uninstalling previous AppRTCMobile versions. It is okay for '
|
||||
'these commands to fail if AppRTCMobile is not installed.')
|
||||
subprocess.call([ADB_BIN, 'uninstall', 'org.appspot.apprtc'])
|
||||
subprocess.call([ADB_BIN, 'uninstall', 'org.appspot.apprtc.test'])
|
||||
|
||||
# Run tests.
|
||||
try:
|
||||
# First clean the project.
|
||||
subprocess.check_call([GRADLEW_BIN, 'clean'], cwd=AAR_PROJECT_DIR)
|
||||
# Then run the tests.
|
||||
subprocess.check_call([
|
||||
GRADLEW_BIN, 'connectedDebugAndroidTest',
|
||||
'-PaarDir=' + os.path.abspath(build_dir)
|
||||
],
|
||||
cwd=AAR_PROJECT_DIR)
|
||||
except subprocess.CalledProcessError:
|
||||
logging.exception('Test failure.')
|
||||
return False # Clean or tests failed
|
||||
|
||||
return True # Tests pass
|
||||
|
||||
|
||||
def BuildAndTestAar(use_goma, skip_tests, build_dir):
|
||||
version = '1.0.' + _GetCommitPos()
|
||||
commit = _GetCommitHash()
|
||||
logging.info('Building and Testing AAR version %s with hash %s', version,
|
||||
commit)
|
||||
|
||||
# If build directory is not specified, create a temporary directory.
|
||||
use_tmp_dir = not build_dir
|
||||
if use_tmp_dir:
|
||||
build_dir = tempfile.mkdtemp()
|
||||
|
||||
try:
|
||||
base_name = ARTIFACT_ID + '-' + version
|
||||
aar_file = os.path.join(build_dir, base_name + '.aar')
|
||||
|
||||
logging.info('Building at %s', build_dir)
|
||||
BuildAar(ARCHS,
|
||||
aar_file,
|
||||
use_goma=use_goma,
|
||||
ext_build_dir=os.path.join(build_dir, 'aar-build'))
|
||||
|
||||
tests_pass = skip_tests or _TestAAR(build_dir)
|
||||
if not tests_pass:
|
||||
raise Exception('Test failure.')
|
||||
|
||||
logging.info('Test success.')
|
||||
|
||||
finally:
|
||||
if use_tmp_dir:
|
||||
shutil.rmtree(build_dir, True)
|
||||
|
||||
|
||||
def main():
|
||||
args = _ParseArgs()
|
||||
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
|
||||
BuildAndTestAar(args.use_goma, args.skip_tests, args.build_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user