Merge pull request #2904 from element-hq/feature/bma/fdroidReleaseScript
Fdroid release script
This commit is contained in:
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Create release App Bundle
|
||||
name: Create release App Bundle and APKs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
2
.idea/dictionaries/shared.xml
generated
2
.idea/dictionaries/shared.xml
generated
@@ -3,7 +3,9 @@
|
||||
<words>
|
||||
<w>backstack</w>
|
||||
<w>blurhash</w>
|
||||
<w>fdroid</w>
|
||||
<w>ftue</w>
|
||||
<w>gplay</w>
|
||||
<w>homeserver</w>
|
||||
<w>konsist</w>
|
||||
<w>kover</w>
|
||||
|
||||
129
tools/github/download_all_github_artifacts.py
Executable file
129
tools/github/download_all_github_artifacts.py
Executable file
@@ -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")))
|
||||
@@ -50,7 +50,7 @@ parser.add_argument('-i',
|
||||
parser.add_argument('-d',
|
||||
'--directory',
|
||||
default="",
|
||||
help='the target directory, where files will be downloaded. If not provided the build number will be used to create a directory.')
|
||||
help='the target directory, where files will be downloaded. If not provided the artifactId will be used to create a directory.')
|
||||
parser.add_argument('-v',
|
||||
'--verbose',
|
||||
help="increase output verbosity.",
|
||||
@@ -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 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)
|
||||
|
||||
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)
|
||||
|
||||
(gitHubRepoOwner, gitHubRepo, artifactId) = result.groups()
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ version=${version:-${versionCandidate}}
|
||||
versionMajor=`echo ${version} | cut -d "." -f1`
|
||||
versionMinor=`echo ${version} | cut -d "." -f2`
|
||||
versionPatch=`echo ${version} | cut -d "." -f3`
|
||||
nextPatchVersion=$((versionPatch + 2))
|
||||
nextPatchVersion=$((versionPatch + 1))
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Starting the release ${version}\n"
|
||||
@@ -141,10 +141,6 @@ rm ${versionsFileBak}
|
||||
# This commit may have no effect because generally we do not change the version during the release.
|
||||
git commit -a -m "Setting version for the release ${version}"
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Building the bundle locally first...\n"
|
||||
./gradlew clean app:bundleGplayRelease
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Running towncrier...\n"
|
||||
yes | towncrier build --version "v${version}"
|
||||
@@ -152,9 +148,6 @@ yes | towncrier build --version "v${version}"
|
||||
printf "\n================================================================================\n"
|
||||
read -p "Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things. Do not commit your change. Press enter to continue. "
|
||||
|
||||
# Get the changes to use it to create the GitHub release
|
||||
changelogUrlEncoded=`git diff CHANGES.md | grep ^+ | tail -n +2 | cut -c2- | jq -sRr @uri | sed s/\(/%28/g | sed s/\)/%29/g`
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Committing...\n"
|
||||
git commit -a -m "Changelog for version ${version}"
|
||||
@@ -218,27 +211,98 @@ 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 "After GHA is finished, please enter the artifact URL (for 'elementx-app-gplay-bundle-unsigned'): " artifactUrl
|
||||
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
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Downloading the artifact...\n"
|
||||
|
||||
# Download files
|
||||
targetPath="./tmp/Element/${version}"
|
||||
|
||||
python3 ./tools/github/download_github_artifacts.py \
|
||||
printf "\n================================================================================\n"
|
||||
printf "Downloading the artifacts...\n"
|
||||
|
||||
python3 ./tools/github/download_all_github_artifacts.py \
|
||||
--token ${gitHubToken} \
|
||||
--artifactUrl ${artifactUrl} \
|
||||
--directory ${targetPath} \
|
||||
--ignoreErrors
|
||||
--runUrl ${runUrl} \
|
||||
--directory ${targetPath}
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Unzipping the artifact...\n"
|
||||
printf "Unzipping the F-Droid artifact...\n"
|
||||
|
||||
unzip ${targetPath}/elementx-app-gplay-bundle-unsigned.zip -d ${targetPath}
|
||||
fdroidTargetPath="${targetPath}/fdroid"
|
||||
unzip ${targetPath}/elementx-app-fdroid-apks-unsigned.zip -d ${fdroidTargetPath}
|
||||
|
||||
unsignedBundlePath="${targetPath}/app-gplay-release.aab"
|
||||
signedBundlePath="${targetPath}/app-gplay-release-signed.aab"
|
||||
printf "\n================================================================================\n"
|
||||
printf "Signing the FDroid APKs...\n"
|
||||
|
||||
cp ${fdroidTargetPath}/app-fdroid-arm64-v8a-release.apk \
|
||||
${fdroidTargetPath}/app-fdroid-arm64-v8a-release-signed.apk
|
||||
${buildToolsPath}/apksigner sign \
|
||||
-v \
|
||||
--ks ${keyStorePath} \
|
||||
--ks-pass pass:${keyStorePassword} \
|
||||
--ks-key-alias elementx \
|
||||
--key-pass pass:${keyPassword} \
|
||||
--min-sdk-version ${minSdkVersion} \
|
||||
${fdroidTargetPath}/app-fdroid-arm64-v8a-release-signed.apk
|
||||
|
||||
cp ${fdroidTargetPath}/app-fdroid-armeabi-v7a-release.apk \
|
||||
${fdroidTargetPath}/app-fdroid-armeabi-v7a-release-signed.apk
|
||||
${buildToolsPath}/apksigner sign \
|
||||
-v \
|
||||
--ks ${keyStorePath} \
|
||||
--ks-pass pass:${keyStorePassword} \
|
||||
--ks-key-alias elementx \
|
||||
--key-pass pass:${keyPassword} \
|
||||
--min-sdk-version ${minSdkVersion} \
|
||||
${fdroidTargetPath}/app-fdroid-armeabi-v7a-release-signed.apk
|
||||
|
||||
cp ${fdroidTargetPath}/app-fdroid-x86-release.apk \
|
||||
${fdroidTargetPath}/app-fdroid-x86-release-signed.apk
|
||||
${buildToolsPath}/apksigner sign \
|
||||
-v \
|
||||
--ks ${keyStorePath} \
|
||||
--ks-pass pass:${keyStorePassword} \
|
||||
--ks-key-alias elementx \
|
||||
--key-pass pass:${keyPassword} \
|
||||
--min-sdk-version ${minSdkVersion} \
|
||||
${fdroidTargetPath}/app-fdroid-x86-release-signed.apk
|
||||
|
||||
cp ${fdroidTargetPath}/app-fdroid-x86_64-release.apk \
|
||||
${fdroidTargetPath}/app-fdroid-x86_64-release-signed.apk
|
||||
${buildToolsPath}/apksigner sign \
|
||||
-v \
|
||||
--ks ${keyStorePath} \
|
||||
--ks-pass pass:${keyStorePassword} \
|
||||
--ks-key-alias elementx \
|
||||
--key-pass pass:${keyPassword} \
|
||||
--min-sdk-version ${minSdkVersion} \
|
||||
${fdroidTargetPath}/app-fdroid-x86_64-release-signed.apk
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Please check the information below:\n"
|
||||
|
||||
printf "File app-fdroid-arm64-v8a-release-signed.apk:\n"
|
||||
${buildToolsPath}/aapt dump badging ${fdroidTargetPath}/app-fdroid-arm64-v8a-release-signed.apk | grep package
|
||||
printf "File app-fdroid-armeabi-v7a-release-signed.apk:\n"
|
||||
${buildToolsPath}/aapt dump badging ${fdroidTargetPath}/app-fdroid-armeabi-v7a-release-signed.apk | grep package
|
||||
printf "File app-fdroid-x86-release-signed.apk:\n"
|
||||
${buildToolsPath}/aapt dump badging ${fdroidTargetPath}/app-fdroid-x86-release-signed.apk | grep package
|
||||
printf "File app-fdroid-x86_64-release-signed.apk:\n"
|
||||
${buildToolsPath}/aapt dump badging ${fdroidTargetPath}/app-fdroid-x86_64-release-signed.apk | grep package
|
||||
|
||||
printf "\n"
|
||||
read -p "Does it look correct? Press enter when it's done."
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "The APKs in ${fdroidTargetPath} have been signed!\n"
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Unzipping the Gplay artifact...\n"
|
||||
|
||||
gplayTargetPath="${targetPath}/gplay"
|
||||
unzip ${targetPath}/elementx-app-gplay-bundle-unsigned.zip -d ${gplayTargetPath}
|
||||
|
||||
unsignedBundlePath="${gplayTargetPath}/app-gplay-release.aab"
|
||||
signedBundlePath="${gplayTargetPath}/app-gplay-release-signed.aab"
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
printf "Signing file ${unsignedBundlePath} with build-tools version ${buildToolsVersion} for min SDK version ${minSdkVersion}...\n"
|
||||
@@ -274,7 +338,7 @@ doBuildApks=${doBuildApks:-yes}
|
||||
|
||||
if [ ${doBuildApks} == "yes" ]; then
|
||||
printf "Building apks...\n"
|
||||
bundletool build-apks --bundle=${signedBundlePath} --output=${targetPath}/elementx.apks \
|
||||
bundletool build-apks --bundle=${signedBundlePath} --output=${gplayTargetPath}/elementx.apks \
|
||||
--ks=./app/signature/debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --key-pass=pass:android \
|
||||
--overwrite
|
||||
|
||||
@@ -282,7 +346,7 @@ if [ ${doBuildApks} == "yes" ]; then
|
||||
doDeploy=${doDeploy:-yes}
|
||||
if [ ${doDeploy} == "yes" ]; then
|
||||
printf "Installing apk for your device...\n"
|
||||
bundletool install-apks --apks=${targetPath}/elementx.apks
|
||||
bundletool install-apks --apks=${gplayTargetPath}/elementx.apks
|
||||
read -p "Please run the application on your phone to check that the upgrade went well. Press enter to continue. "
|
||||
else
|
||||
printf "APK will not be deployed!\n"
|
||||
@@ -305,14 +369,17 @@ printf "You can then go to \"Publishing overview\" and send the new release for
|
||||
read -p "Press enter to continue. "
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
githubCreateReleaseLink="https://github.com/element-hq/element-x-android/releases/new?tag=v${version}&title=Element%20X%20Android%20v${version}&body=${changelogUrlEncoded}"
|
||||
# Url encode for "<!-- Copy paste the section of the file CHANGES.md for this release here -->"
|
||||
body="%3C%21--%20Copy%20paste%20the%20section%20of%20the%20file%20CHANGES.md%20for%20this%20release%20here%20--%3E"
|
||||
githubCreateReleaseLink="https://github.com/element-hq/element-x-android/releases/new?tag=v${version}&title=Element%20X%20Android%20v${version}&body=${body}"
|
||||
printf "Creating the release on gitHub.\n"
|
||||
printf -- "Open this link: %s\n" ${githubCreateReleaseLink}
|
||||
printf "Then\n"
|
||||
printf " - copy paste the section of the file CHANGES.md for this release (if not there yet)\n"
|
||||
printf " - click on the 'Generate releases notes' button\n"
|
||||
printf " - copy paste the section of the file CHANGES.md for this release.\n"
|
||||
printf " - click on the 'Generate releases notes' button.\n"
|
||||
printf " - Add the file ${signedBundlePath} to the GitHub release.\n"
|
||||
printf " - Add the universal APK, downloaded from the GooglePlay console to the GitHub release.\n"
|
||||
printf " - Add the 4 signed APKs for F-Droid, located at ${fdroidTargetPath} to the GitHub release.\n"
|
||||
read -p ". Press enter to continue. "
|
||||
|
||||
printf "\n================================================================================\n"
|
||||
|
||||
Reference in New Issue
Block a user