diff --git a/tools/github/download_all_github_artifacts.py b/tools/github/download_all_github_artifacts.py new file mode 100755 index 0000000000..dee861ea13 --- /dev/null +++ b/tools/github/download_all_github_artifacts.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +# +# Copyright 2022 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import argparse +import hashlib +import json +import os +# Run `pip3 install requests` if not installed yet +import requests +# Run `pip3 install re` if not installed yet +import re +import time + +# This script downloads artifacts from GitHub. +# Ref: https://docs.github.com/en/rest/actions/artifacts#get-an-artifact + +error = False + +### Arguments + +parser = argparse.ArgumentParser(description='Download artifacts from GitHub.') +parser.add_argument('-t', + '--token', + required=True, + help='The GitHub token with read access.') +parser.add_argument('-r', + '--runUrl', + required=True, + help='the GitHub action run url.') +parser.add_argument('-d', + '--directory', + default="", + help='the target directory, where files will be downloaded. If not provided the runId will be used to create a directory.') +parser.add_argument('-v', + '--verbose', + help="increase output verbosity.", + action="store_true") +parser.add_argument('-s', + '--simulate', + help="simulate action, do not create folder or download any file.", + action="store_true") + +args = parser.parse_args() + +if args.verbose: + print("Argument:") + print(args) + + +# Split the artifact URL to get information +# Ex: https://github.com/element-hq/element-x-android/actions/runs/9065756777 +runUrl = args.runUrl + +url_regex = r"https://github.com/(.+?)/(.+?)/actions/runs/(.+)" +result = re.search(url_regex, runUrl) + +if result is None: + print( + "❌ Invalid parameter --runUrl '%s'. Please check the format.\nIt should be something like: %s" % + (runUrl, 'https://github.com/element-hq/element-x-android/actions/runs/9065756777') + ) + exit(1) + +(gitHubRepoOwner, gitHubRepo, runId) = result.groups() + +if args.verbose: + print("gitHubRepoOwner: %s, gitHubRepo: %s, runId: %s" % (gitHubRepoOwner, gitHubRepo, runId)) + +headers = { + 'Authorization': "Bearer %s" % args.token, + 'Accept': 'application/vnd.github+json' +} + +base_url = "https://api.github.com/repos/%s/%s/actions/runs/%s" % (gitHubRepoOwner, gitHubRepo, runId) + +### Fetch build state +status = "" +data = "{}" +while status != "completed": + r = requests.get(base_url, headers=headers) + data = json.loads(r.content.decode()) + + if args.verbose: + print("Json data:") + print(data) + status = data.get("status") + + if data.get("status") == "completed": + if data.get("conclusion") != "success": + print("❌ The action %s is completed, but there is an error, the conclusion is: %s." % (runUrl, data.get("conclusion"))) + exit(1) + else: + # Wait 1 minute + print("The action %s is not completed yet, waiting 1 minute..." % runUrl) + time.sleep(60) + + +artifacts_url = data.get("artifacts_url") +if args.verbose: + print("Artifacts url: %s" % artifacts_url) + +r = requests.get(artifacts_url, headers=headers) +data = json.loads(r.content.decode()) + +if args.directory == "": + targetDir = runId +else: + targetDir = args.directory + +for artifact in data.get("artifacts"): + if args.verbose: + print("Artifact:") + print(artifact) + # Invoke the script to download the artifact + os.system("python3 ./tools/github/download_github_artifacts.py -t %s -d %s -a %s" % (args.token, targetDir, artifact.get("url"))) diff --git a/tools/github/download_github_artifacts.py b/tools/github/download_github_artifacts.py index 8caa2c45b2..fcf7466901 100755 --- a/tools/github/download_github_artifacts.py +++ b/tools/github/download_github_artifacts.py @@ -71,15 +71,27 @@ if args.verbose: # Ex: https://github.com/element-hq/element-x-android/actions/runs/7299827320/artifacts/1131077517 artifactUrl = args.artifactUrl -url_regex = r"https://github.com/(.+?)/(.+?)/actions/runs/.+?/artifacts/(.+)" -result = re.search(url_regex, artifactUrl) - -if result is None: - print( - "❌ Invalid parameter --artifactUrl '%s'. Please check the format.\nIt should be something like: %s" % - (artifactUrl, 'https://github.com/element-hq/element-x-android/actions/runs/7299827320/artifacts/1131077517') - ) - exit(1) +# if artifactUrl starts with https://github.com +if artifactUrl.startswith('https://github.com'): + url_regex = r"https://github.com/(.+?)/(.+?)/actions/runs/.+?/artifacts/(.+)" + result = re.search(url_regex, artifactUrl) + + if result is None: + print( + "❌ Invalid parameter --artifactUrl '%s'. Please check the format.\nIt should be something like: %s" % + (artifactUrl, 'https://github.com/element-hq/element-x-android/actions/runs/7299827320/artifacts/1131077517') + ) + exit(1) +else: + url_regex = r"https://api.github.com/repos/(.+?)/(.+?)/actions/artifacts/(.+)" + result = re.search(url_regex, artifactUrl) + if result is None: + print( + "❌ Invalid parameter --artifactUrl '%s'. Please check the format.\nIt should be something like: %s" % + (artifactUrl, 'https://api.github.com/repos/element-hq/element-x-android/actions/artifacts/1131077517') + ) + exit(1) + (gitHubRepoOwner, gitHubRepo, artifactId) = result.groups() diff --git a/tools/release/release.sh b/tools/release/release.sh index 6110929b9f..c74431d2e0 100755 --- a/tools/release/release.sh +++ b/tools/release/release.sh @@ -215,26 +215,25 @@ fi printf "\n================================================================================\n" printf "Wait for the GitHub action https://github.com/element-hq/element-x-android/actions/workflows/release.yml?query=branch%%3Amain to build the 'main' branch.\n" -read -p "Please enter the artifact URL for Gplay app bundle (for 'elementx-app-gplay-bundle-unsigned'): " artifactGplayUrl -read -p "Please enter the artifact URL for FDroid APKs (for 'elementx-app-fdroid-apks-unsigned'): " artifactFdroidUrl +printf "Please enter the url of the github action (!!! WARNING: NOT THE URL OF THE ARTIFACT ANYMORE !!!)\n" +read -p "For instance https://github.com/element-hq/element-x-android/actions/runs/9065756777: " runUrl targetPath="./tmp/Element/${version}" printf "\n================================================================================\n" -printf "Downloading the FDroid artifact...\n" +printf "Downloading the artifacts...\n" -fdroidTargetPath="${targetPath}/fdroid" - -python3 ./tools/github/download_github_artifacts.py \ +python3 ./tools/github/download_all_github_artifacts.py \ --token ${gitHubToken} \ - --artifactUrl ${artifactFdroidUrl} \ - --directory ${fdroidTargetPath} \ + --runUrl ${runUrl} \ + --directory ${targetPath} \ --ignoreErrors printf "\n================================================================================\n" -printf "Unzipping the artifact...\n" +printf "Unzipping the F-Droid artifact...\n" -unzip ${fdroidTargetPath}/elementx-app-fdroid-apks-unsigned.zip -d ${fdroidTargetPath} +fdroidTargetPath="${targetPath}/fdroid" +unzip ${targetPath}/elementx-app-fdroid-apks-unsigned.zip -d ${fdroidTargetPath} # Flatten folder hierarchy mv ${fdroidTargetPath}/fdroid/release/* ${fdroidTargetPath} @@ -306,21 +305,10 @@ printf "\n====================================================================== printf "The APKs in ${fdroidTargetPath} have been signed!\n" printf "\n================================================================================\n" -printf "Downloading the Gplay artifact...\n" +printf "Unzipping the Gplay artifact...\n" - # Download files gplayTargetPath="${targetPath}/gplay" - -python3 ./tools/github/download_github_artifacts.py \ - --token ${gitHubToken} \ - --artifactUrl ${artifactGplayUrl} \ - --directory ${gplayTargetPath} \ - --ignoreErrors - -printf "\n================================================================================\n" -printf "Unzipping the artifact...\n" - -unzip ${gplayTargetPath}/elementx-app-gplay-bundle-unsigned.zip -d ${gplayTargetPath} +unzip ${targetPath}/elementx-app-gplay-bundle-unsigned.zip -d ${gplayTargetPath} unsignedBundlePath="${gplayTargetPath}/app-gplay-release.aab" signedBundlePath="${gplayTargetPath}/app-gplay-release-signed.aab"