blob: 0c877e5e99ac45faa26e5afe7fa0fb793ec772b9 [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 Gjesse0eaf82d2024-02-09 10:41:06 +010066 utils.DownloadFromGoogleCloudStorage(utils.JAVA8_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 Gjesse0eaf82d2024-02-09 10:41:06 +0100104 # Build release to local Maven repository compiling with JDK-8.
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200105 m2 = os.path.join(temp, 'm2')
106 os.mkdir(m2)
Søren Gjesse246b11c2024-02-07 14:33:27 +0100107 env = os.environ.copy()
Søren Gjesse0eaf82d2024-02-09 10:41:06 +0100108 env["JAVA_HOME"] = jdk.GetJdk8Home()
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200109 subprocess.check_call([
110 './gradlew',
111 '-Dmaven.repo.local=%s' % m2, 'release', 'test',
Søren Gjesse246b11c2024-02-07 14:33:27 +0100112 'publishToMavenLocal',
113 ], env=env)
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200114 base = os.path.join('com', 'android', 'tools', 'smali')
Søren Gjessee6087bf2023-01-17 10:49:29 +0100115
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200116 # Check that the local maven repository only has the single version directory in
117 # each artifact directory.
118 for name in [
119 'smali-util', 'smali-dexlib2', 'smali', 'smali-baksmali'
120 ]:
121 dirnames = next(os.walk(os.path.join(m2, base, name)),
122 (None, None, []))[1]
123 if not dirnames or len(dirnames) != 1 or dirnames[0] != version:
124 raise Exception('Found unexpected directory %s in %s' %
125 (dirnames, name))
Søren Gjessee6087bf2023-01-17 10:49:29 +0100126
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200127 # Build an archive with the relevant content of the local maven repository.
128 m2_filtered = os.path.join(temp, 'm2_filtered')
129 shutil.copytree(
130 m2,
131 m2_filtered,
132 ignore=shutil.ignore_patterns('maven-metadata-local.xml'))
133 maven_release_archive = shutil.make_archive(
134 'smali-maven-release-%s' % version, 'zip', m2_filtered, base)
Søren Gjessee6087bf2023-01-17 10:49:29 +0100135
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200136 # Collect names of the fat jars.
137 fat_jars = list(
138 map(lambda prefix: '%s-%s-fat.jar' % (prefix, version),
139 ['smali/build/libs/smali', 'baksmali/build/libs/baksmali']))
Søren Gjessee6087bf2023-01-17 10:49:29 +0100140
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200141 # Copy artifacts.
142 files = [maven_release_archive]
143 files.extend(fat_jars)
144 if options.dry_run:
145 if dry_run_output:
146 print('Dry run, not actually uploading. Copying to %s:' %
147 dry_run_output)
148 for file in files:
149 destination = os.path.join(dry_run_output,
150 os.path.basename(file))
151 shutil.copyfile(file, destination)
152 print(" %s" % destination)
153 else:
154 print('Dry run, not actually uploading. Generated files:')
155 for file in files:
156 print(" %s" % os.path.basename(file))
157 else:
158 destination_prefix = 'gs://%s/smali/%s' % (ARCHIVE_BUCKET,
159 version)
160 if utils.cloud_storage_exists(destination_prefix):
161 raise Exception(
162 'Target archive directory %s already exists' %
163 destination_prefix)
164 for file in files:
165 destination = '%s/%s' % (destination_prefix,
166 os.path.basename(file))
167 if utils.cloud_storage_exists(destination):
168 raise Exception('Target %s already exists' %
169 destination)
170 utils.upload_file_to_cloud_storage(file, destination)
171 public_url = 'https://storage.googleapis.com/%s/smali/%s' % (
172 ARCHIVE_BUCKET, version)
173 print('Artifacts available at: %s' % public_url)
Søren Gjessee6087bf2023-01-17 10:49:29 +0100174
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200175 print("Done!")
176
Søren Gjessee6087bf2023-01-17 10:49:29 +0100177
178if __name__ == '__main__':
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200179 sys.exit(Main())