blob: 4de3eef42618325e4110420cb171188c6f0255f3 [file] [log] [blame]
Søren Gjessee6087bf2023-01-17 10:49:29 +01001#!/usr/bin/env python3
2# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6import argparse
7import os
8import re
9try:
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020010 import resource
Søren Gjessee6087bf2023-01-17 10:49:29 +010011except ImportError:
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020012 # Not a Unix system. Do what Gandalf tells you not to.
13 pass
Søren Gjessee6087bf2023-01-17 10:49:29 +010014import shutil
15import subprocess
16import sys
17
Søren Gjesse246b11c2024-02-07 14:33:27 +010018import jdk
Søren Gjessee6087bf2023-01-17 10:49:29 +010019import utils
20
21ARCHIVE_BUCKET = 'r8-releases'
22REPO = 'https://github.com/google/smali'
23NO_DRYRUN_OUTPUT = object()
24
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020025
Søren Gjessee6087bf2023-01-17 10:49:29 +010026def checkout(temp):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020027 subprocess.check_call(['git', 'clone', REPO, temp])
28 return temp
29
Søren Gjessee6087bf2023-01-17 10:49:29 +010030
Søren Gjessee6087bf2023-01-17 10:49:29 +010031def parse_options():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020032 result = argparse.ArgumentParser(description='Release Smali')
33 result.add_argument('--version',
34 metavar=('<version>'),
35 help='The version of smali to archive.')
36 result.add_argument('--dry-run',
37 '--dry_run',
38 nargs='?',
39 help='Build only, no upload.',
40 metavar='<output directory>',
41 default=None,
42 const=NO_DRYRUN_OUTPUT)
43 result.add_argument('--checkout', help='Use existing checkout.')
44 return result.parse_args()
Søren Gjessee6087bf2023-01-17 10:49:29 +010045
46
47def set_rlimit_to_max():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020048 (soft, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
49 resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard))
Søren Gjessee6087bf2023-01-17 10:49:29 +010050
51
52def Main():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020053 options = parse_options()
54 if not utils.is_bot() and not options.dry_run:
55 raise Exception('You are not a bot, don\'t archive builds. ' +
56 'Use --dry-run to test locally')
57 if options.checkout and not options.dry_run:
58 raise Exception('Using local checkout is only allowed with --dry-run')
59 if not options.checkout and not options.version:
60 raise Exception(
61 'Option --version is required (when not using local checkout)')
Søren Gjessee6087bf2023-01-17 10:49:29 +010062
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020063 if utils.is_bot() and not utils.IsWindows():
64 set_rlimit_to_max()
Søren Gjessee6087bf2023-01-17 10:49:29 +010065
Søren Gjessed0528372024-09-13 13:54:28 +020066 utils.DownloadFromGoogleCloudStorage(utils.JAVA11_SHA_FILE)
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020067 with utils.TempDir() as temp:
68 # Resolve dry run location to support relative directories.
69 dry_run_output = None
70 if options.dry_run and options.dry_run != NO_DRYRUN_OUTPUT:
71 if not os.path.isdir(options.dry_run):
72 os.mkdir(options.dry_run)
73 dry_run_output = os.path.abspath(options.dry_run)
Søren Gjessee6087bf2023-01-17 10:49:29 +010074
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020075 checkout_dir = options.checkout if options.checkout else checkout(temp)
76 with utils.ChangedWorkingDirectory(checkout_dir):
77 if options.version:
78 output = subprocess.check_output(
79 ['git', 'tag', '-l', options.version])
80 if len(output) == 0:
81 raise Exception(
82 'Repository does not have a release tag for version %s'
83 % options.version)
84 subprocess.check_call(['git', 'checkout', options.version])
Søren Gjessee6087bf2023-01-17 10:49:29 +010085
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020086 # Find version from `build.gradle`.
87 for line in open(os.path.join('build.gradle'), 'r'):
88 result = re.match(r'^version = \'(\d+)\.(\d+)\.(\d+)\'', line)
89 if result:
90 break
91 version = '%s.%s.%s' % (result.group(1), result.group(2),
92 result.group(3))
93 if options.version and version != options.version:
94 message = 'version %s, expected version %s' % (version,
95 options.version)
96 if (options.checkout):
97 raise Exception('Checkout %s has %s' %
98 (options.checkout, message))
99 else:
100 raise Exception('Tag % has %s' % (options.version, message))
Ian Zerny6e65f712023-02-15 09:46:02 +0100101
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200102 print('Building version: %s' % version)
Søren Gjessee6087bf2023-01-17 10:49:29 +0100103
Søren Gjessed0528372024-09-13 13:54:28 +0200104 # Build release to local Maven repository compiling with JDK-11.
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200105 m2 = os.path.join(temp, 'm2')
106 os.mkdir(m2)
107 subprocess.check_call([
108 './gradlew',
Søren Gjesse740f37d2024-12-20 11:06:47 +0100109 '-Dorg.gradle.java.home=%s' % jdk.GetJdk11Home(),
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200110 '-Dmaven.repo.local=%s' % m2, 'release', 'test',
Søren Gjesse246b11c2024-02-07 14:33:27 +0100111 'publishToMavenLocal',
Søren Gjesse740f37d2024-12-20 11:06:47 +0100112 ])
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200113 base = os.path.join('com', 'android', 'tools', 'smali')
Søren Gjessee6087bf2023-01-17 10:49:29 +0100114
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200115 # Check that the local maven repository only has the single version directory in
116 # each artifact directory.
117 for name in [
118 'smali-util', 'smali-dexlib2', 'smali', 'smali-baksmali'
119 ]:
120 dirnames = next(os.walk(os.path.join(m2, base, name)),
121 (None, None, []))[1]
122 if not dirnames or len(dirnames) != 1 or dirnames[0] != version:
123 raise Exception('Found unexpected directory %s in %s' %
124 (dirnames, name))
Søren Gjessee6087bf2023-01-17 10:49:29 +0100125
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200126 # Build an archive with the relevant content of the local maven repository.
127 m2_filtered = os.path.join(temp, 'm2_filtered')
128 shutil.copytree(
129 m2,
130 m2_filtered,
131 ignore=shutil.ignore_patterns('maven-metadata-local.xml'))
132 maven_release_archive = shutil.make_archive(
133 'smali-maven-release-%s' % version, 'zip', m2_filtered, base)
Søren Gjessee6087bf2023-01-17 10:49:29 +0100134
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200135 # Collect names of the fat jars.
136 fat_jars = list(
137 map(lambda prefix: '%s-%s-fat.jar' % (prefix, version),
138 ['smali/build/libs/smali', 'baksmali/build/libs/baksmali']))
Søren Gjessee6087bf2023-01-17 10:49:29 +0100139
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200140 # Copy artifacts.
141 files = [maven_release_archive]
142 files.extend(fat_jars)
143 if options.dry_run:
144 if dry_run_output:
145 print('Dry run, not actually uploading. Copying to %s:' %
146 dry_run_output)
147 for file in files:
148 destination = os.path.join(dry_run_output,
149 os.path.basename(file))
150 shutil.copyfile(file, destination)
151 print(" %s" % destination)
152 else:
153 print('Dry run, not actually uploading. Generated files:')
154 for file in files:
155 print(" %s" % os.path.basename(file))
156 else:
157 destination_prefix = 'gs://%s/smali/%s' % (ARCHIVE_BUCKET,
158 version)
159 if utils.cloud_storage_exists(destination_prefix):
160 raise Exception(
161 'Target archive directory %s already exists' %
162 destination_prefix)
163 for file in files:
164 destination = '%s/%s' % (destination_prefix,
165 os.path.basename(file))
166 if utils.cloud_storage_exists(destination):
167 raise Exception('Target %s already exists' %
168 destination)
169 utils.upload_file_to_cloud_storage(file, destination)
170 public_url = 'https://storage.googleapis.com/%s/smali/%s' % (
171 ARCHIVE_BUCKET, version)
172 print('Artifacts available at: %s' % public_url)
Søren Gjessee6087bf2023-01-17 10:49:29 +0100173
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200174 print("Done!")
175
Søren Gjessee6087bf2023-01-17 10:49:29 +0100176
177if __name__ == '__main__':
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200178 sys.exit(Main())