Skip to content

Commit 83a10c3

Browse files
committed
Install app from GitHub action
1 parent 8795ddb commit 83a10c3

File tree

2 files changed

+248
-0
lines changed

2 files changed

+248
-0
lines changed

tools/install/installFromGitHub.sh

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env bash
2+
3+
# Exit on any error
4+
set -e
5+
6+
if [[ "$#" -ne 1 ]]; then
7+
echo "Usage: $0 GitHub_token" >&2
8+
exit 1
9+
fi
10+
11+
gitHubToken=$1
12+
13+
# Path where the app is cloned (it's where this project has been cloned)
14+
appPath=$(dirname $(dirname $(dirname $0)))
15+
# Path where the APK will be downloaded from CI (it's a dir)
16+
baseImportPath="${appPath}/tmp/DebugApks"
17+
18+
# Select device
19+
serialNumber=$(${appPath}/tools/install/androidSelectDevice.sh)
20+
21+
# Detect device architecture
22+
arch=$(adb -s ${serialNumber} shell getprop ro.product.cpu.abi)
23+
24+
echo
25+
echo "Will install the application on device ${serialNumber} with arch ${arch}"
26+
27+
# Artifact URL
28+
echo
29+
read -p "Artifact url (ex: https://github.com/vector-im/element-android/suites/9293388174/artifacts/435942121)? " artifactUrl
30+
31+
## Example of default value for Gplay
32+
#artifactUrl=${artifactUrl:-https://github.com/vector-im/element-android/suites/9293388174/artifacts/435942121}
33+
## Example of default value for FDroid
34+
# artifactUrl=${artifactUrl:-https://github.com/vector-im/element-android/suites/9293388174/artifacts/435942119}
35+
36+
artifactId=$(echo ${artifactUrl} | rev | cut -d'/' -f1 | rev)
37+
38+
# Download files
39+
targetPath=${baseImportPath}/${artifactId}
40+
41+
filename="artifact.zip"
42+
43+
fullFilePath="${targetPath}/${filename}"
44+
45+
# Check if file already exists
46+
if test -f "$fullFilePath"; then
47+
read -p "$fullFilePath already exists. Override (yes/no) default to no ? " download
48+
download=${download:-no}
49+
else
50+
download="yes"
51+
fi
52+
53+
# Ignore error from now
54+
set +e
55+
56+
if [ ${download} == "yes" ]; then
57+
echo "Downloading ${filename} to ${targetPath}..."
58+
python3 ${appPath}/tools/release/download_github_artifacts.py \
59+
--token ${gitHubToken} \
60+
--artifactUrl ${artifactUrl} \
61+
--directory ${targetPath} \
62+
--filename ${filename} \
63+
--ignoreErrors
64+
fi
65+
66+
echo "Unzipping ${filename}..."
67+
unzip $fullFilePath -d ${targetPath}
68+
69+
## gplay or fdroid
70+
if test -d "${targetPath}/gplay"; then
71+
variant="gplay"
72+
elif test -d "${targetPath}/fdroid"; then
73+
variant="fdroid"
74+
else
75+
echo "No variant found"
76+
exit 1
77+
fi
78+
79+
fullApkPath="${targetPath}/${variant}/debug/vector-${variant}-${arch}-debug.apk"
80+
81+
echo "Installing ${fullApkPath} to device ${serialNumber}..."
82+
adb -s ${serialNumber} install -r ${fullApkPath}
83+
84+
# Check error and propose to uninstall and retry installing
85+
if [[ "$?" -ne 0 ]]; then
86+
read -p "Error, do you want to uninstall the application then retry (yes/no) default to no ? " retry
87+
retry=${retry:-no}
88+
if [ ${retry} == "yes" ]; then
89+
echo "Uninstalling..."
90+
adb -s ${serialNumber} uninstall im.vector.app.debug
91+
echo "Installing again..."
92+
adb -s ${serialNumber} install -r ${fullApkPath}
93+
fi
94+
fi
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright 2022 New Vector Ltd
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
import argparse
19+
import hashlib
20+
import json
21+
import os
22+
# Run `pip3 install requests` if not installed yet
23+
import requests
24+
25+
# This script downloads artifacts from GitHub.
26+
# Ref: https://docs.github.com/en/rest/actions/artifacts#get-an-artifact
27+
28+
error = False
29+
30+
### Arguments
31+
32+
parser = argparse.ArgumentParser(description='Download artifacts from GitHub.')
33+
parser.add_argument('-t',
34+
'--token',
35+
required=True,
36+
help='The GitHub token with read access.')
37+
parser.add_argument('-a',
38+
'--artifactUrl',
39+
required=True,
40+
help='the artifact_url from GitHub.')
41+
parser.add_argument('-f',
42+
'--filename',
43+
help='the filename, if not provided, will use the artifact name.')
44+
parser.add_argument('-i',
45+
'--ignoreErrors',
46+
help='Ignore errors that can be ignored. Build state and number of artifacts.',
47+
action="store_true")
48+
parser.add_argument('-d',
49+
'--directory',
50+
default="",
51+
help='the target directory, where files will be downloaded. If not provided the build number will be used to create a directory.')
52+
parser.add_argument('-v',
53+
'--verbose',
54+
help="increase output verbosity.",
55+
action="store_true")
56+
parser.add_argument('-s',
57+
'--simulate',
58+
help="simulate action, do not create folder or download any file.",
59+
action="store_true")
60+
61+
args = parser.parse_args()
62+
63+
if args.verbose:
64+
print("Argument:")
65+
print(args)
66+
67+
# Split the artifact URL to get information
68+
# Ex: https://github.com/vector-im/element-android/suites/9293388174/artifacts/435942121
69+
artifactUrl = args.artifactUrl
70+
if not artifactUrl.startswith('https://github.com/'):
71+
print("❌ Invalid parameter --artifactUrl %s. Must start with 'https://github.com/'" % artifactUrl)
72+
exit(1)
73+
if "/artifacts/" not in artifactUrl:
74+
print("❌ Invalid parameter --artifactUrl %s. Must contain '/artifacts/'" % artifactUrl)
75+
exit(1)
76+
artifactItems = artifactUrl.split("/")
77+
if len(artifactItems) != 9:
78+
print("❌ Invalid parameter --artifactUrl %s. Please check the format." % (artifactUrl))
79+
exit(1)
80+
81+
gitHubRepoOwner = artifactItems[3]
82+
gitHubRepo = artifactItems[4]
83+
artifactId = artifactItems[8]
84+
85+
if args.verbose:
86+
print("gitHubRepoOwner: %s, gitHubRepo: %s, artifactId: %s" % (gitHubRepoOwner, gitHubRepo, artifactId))
87+
88+
headers = {
89+
'Authorization': "Bearer %s" % args.token,
90+
'Accept': 'application/vnd.github+json'
91+
}
92+
base_url = "https://api.github.com/repos/%s/%s/actions/artifacts/%s" % (gitHubRepoOwner, gitHubRepo, artifactId)
93+
94+
### Fetch build state
95+
96+
print("Getting artifacts data of project '%s/%s' artifactId '%s'..." % (gitHubRepoOwner, gitHubRepo, artifactId))
97+
98+
if args.verbose:
99+
print("Url: %s" % base_url)
100+
101+
r = requests.get(base_url, headers=headers)
102+
data = json.loads(r.content.decode())
103+
104+
if args.verbose:
105+
print("Json data:")
106+
print(data)
107+
108+
if args.verbose:
109+
print("Create subfolder %s to download artifacts..." % artifactId)
110+
111+
if args.directory == "":
112+
targetDir = artifactId
113+
else:
114+
targetDir = args.directory
115+
116+
if not args.simulate:
117+
os.makedirs(targetDir, exist_ok=True)
118+
119+
url = data.get("archive_download_url")
120+
if args.filename is not None:
121+
filename = args.filename
122+
else:
123+
filename = data.get("name") + ".zip"
124+
125+
## Print some info about the artifact origin
126+
commitLink = "https://github.com/%s/%s/commit/%s" % (gitHubRepoOwner, gitHubRepo, data.get("workflow_run").get("head_sha"))
127+
print("Preparing to download artifact `%s`, built from branch: `%s` (commit %s)" % (data.get("name"), data.get("workflow_run").get("head_branch"), commitLink))
128+
129+
if args.verbose:
130+
print()
131+
print("Artifact url: %s" % url)
132+
133+
target = targetDir + "/" + filename
134+
sizeInBytes = data.get("size_in_bytes")
135+
print("Downloading %s to '%s' (file size is %s bytes, this may take a while)..." % (filename, targetDir, sizeInBytes))
136+
if not args.simulate:
137+
# open file to write in binary mode
138+
with open(target, "wb") as file:
139+
# get request
140+
response = requests.get(url, headers=headers)
141+
# write to file
142+
file.write(response.content)
143+
print("Verifying file size...")
144+
# get the file size
145+
size = os.path.getsize(target)
146+
if sizeInBytes != size:
147+
# error = True
148+
print("Warning, file size mismatch: expecting %s and get %s. This is just a warning for now..." % (sizeInBytes, size))
149+
150+
if error:
151+
print("❌ Error(s) occurred, please check the log")
152+
exit(1)
153+
else:
154+
print("Done!")

0 commit comments

Comments
 (0)