Skip to content

[MMCA] Add permissions external storage #45

[MMCA] Add permissions external storage

[MMCA] Add permissions external storage #45

Workflow file for this run

# make sure to generate requirements.txt with pipreqs first!
name: Build
on:
push:
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
workflow_dispatch:
jobs:
# see https://data-dive.com/multi-os-deployment-in-cloud-using-pyinstaller-and-github-actions/
# but here we build first and run our createrelease job afterwards, accessing the artifacts of our build job
build-android-MMCA:
name: Build MobileCrashAnalyzer for android
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt -y install apksigner
# Build Mobile Crash Analyzer
- name: Prepare MMCA for buildozer
run: |
REFNAME="${{ github.ref_name }}"
echo "VERSION='${REFNAME}'" >src/shared/utils/version.py
mkdir MobileCrashAnalyzer_Deploy
cp -av src/MobileCrashAnalyzer.py MobileCrashAnalyzer_Deploy/
cp -av src/MobileCrashAnalyzer MobileCrashAnalyzer_Deploy/
cp -av src/shared MobileCrashAnalyzer_Deploy/
cp -av src/MobileCrashAnalyzer/data/conf/intent_filters.xml MobileCrashAnalyzer_Deploy/
cp -av src/MobileCrashAnalyzer/data/conf/buildozer.spec MobileCrashAnalyzer_Deploy/
echo "" >>MobileCrashAnalyzer_Deploy/buildozer.spec
# buildozer does not like non-numeric version numbers
echo "version = ${REFNAME#v}" >>MobileCrashAnalyzer_Deploy/buildozer.spec
# dynamically build main.py proxy to load
echo "import os" >MobileCrashAnalyzer_Deploy/main.py
echo "os.environ['KIVY_LOG_MODE'] = 'MIXED'" >>MobileCrashAnalyzer_Deploy/main.py
echo "os.environ['KIVY_NO_FILELOG'] = '1'" >>MobileCrashAnalyzer_Deploy/main.py
echo "" >>MobileCrashAnalyzer_Deploy/main.py
echo "from importlib import util" >>MobileCrashAnalyzer_Deploy/main.py
echo "real_file = os.path.join(os.path.dirname(__file__), 'MobileCrashAnalyzer.py')" >>MobileCrashAnalyzer_Deploy/main.py
echo "if not os.path.exists(real_file):" >>MobileCrashAnalyzer_Deploy/main.py
echo " real_file = os.path.join(os.path.dirname(__file__), 'MobileCrashAnalyzer.pyc')" >>MobileCrashAnalyzer_Deploy/main.py
echo "print('Proxy loading real file: %s' % real_file)" >>MobileCrashAnalyzer_Deploy/main.py
echo "spec = util.spec_from_file_location('MobileCrashAnalyzer', real_file)" >>MobileCrashAnalyzer_Deploy/main.py
echo "print(f'{spec = }')" >>MobileCrashAnalyzer_Deploy/main.py
echo "mod = util.module_from_spec(spec)" >>MobileCrashAnalyzer_Deploy/main.py
echo "# we don't want to add our module to sys.modules to not interfere with the package path having the same name" >>MobileCrashAnalyzer_Deploy/main.py
echo "# (just like if our real_file was the real python script started)" >>MobileCrashAnalyzer_Deploy/main.py
echo "print(f'{mod = }')" >>MobileCrashAnalyzer_Deploy/main.py
echo "out = spec.loader.exec_module(mod)" >>MobileCrashAnalyzer_Deploy/main.py
echo "print(f'Proxied file returned with `{out}`, terminating...')" >>MobileCrashAnalyzer_Deploy/main.py
echo " "
echo "buildozer.spec:"
cat MobileCrashAnalyzer_Deploy/buildozer.spec
echo " "
echo "main.py:"
cat MobileCrashAnalyzer_Deploy/main.py
- name: Build with Buildozer
uses: Sobottasgithub/[email protected]
id: buildozer
with:
workdir: MobileCrashAnalyzer_Deploy
buildozer_version: stable
- name: Sign Apk
id: signer
run: |
apkinfile="${{ steps.buildozer.outputs.filename }}"
apkoutfile="$HOME/signed-$(basename "${apkinfile}")"
echo -n "${{ secrets.APK_SIGNING_KEY }}" >"$HOME/keystore.key"
openssl enc -d -chacha20 -pbkdf2 -in src/MobileCrashAnalyzer/data/conf/release.keystore.enc -out "$HOME/release.keystore" -kfile "$HOME/keystore.key"
cat "$HOME/keystore.key" | apksigner sign -ks "$HOME/release.keystore" -in "${apkinfile}" -out "${apkoutfile}"
echo "unsigned_apk=${apkinfile}" >> "$GITHUB_OUTPUT"
echo "signed_apk=${apkoutfile}" >> "$GITHUB_OUTPUT"
- name: Upload signed apk
uses: actions/upload-artifact@v4
with:
name: MobileCrashAnalyzer
path: ${{ steps.signer.outputs.signed_apk }}
build-android-MMLV:
name: Build MobileLogViewer for android
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt -y install apksigner
# Build Monal Mobile Log Viewer
- name: Prepare MMLV for buildozer
run: |
REFNAME="${{ github.ref_name }}"
echo "VERSION='${REFNAME}'" >src/shared/utils/version.py
mkdir MobileLogViewer_Deploy
cp -av src/MobileLogViewer.py MobileLogViewer_Deploy/
cp -av src/MobileLogViewer MobileLogViewer_Deploy/
cp -av src/shared MobileLogViewer_Deploy/
cp -av src/MobileLogViewer/data/conf/intent_filters.xml MobileLogViewer_Deploy/
cp -av src/MobileLogViewer/data/conf/buildozer.spec MobileLogViewer_Deploy/
echo "" >>MobileLogViewer_Deploy/buildozer.spec
# buildozer does not like non-numeric version numbers
echo "version = ${REFNAME#v}" >>MobileLogViewer_Deploy/buildozer.spec
# dynamically build main.py proxy to load
echo "import os" >MobileLogViewer_Deploy/main.py
echo "os.environ['KIVY_LOG_MODE'] = 'MIXED'" >>MobileLogViewer_Deploy/main.py
echo "os.environ['KIVY_NO_FILELOG'] = '1'" >>MobileLogViewer_Deploy/main.py
echo "" >>MobileLogViewer_Deploy/main.py
echo "from importlib import util" >>MobileLogViewer_Deploy/main.py
echo "real_file = os.path.join(os.path.dirname(__file__), 'MobileCrashAnalyzer.py')" >>MobileLogViewer_Deploy/main.py
echo "if not os.path.exists(real_file):" >>MobileLogViewer_Deploy/main.py
echo " real_file = os.path.join(os.path.dirname(__file__), 'MobileCrashAnalyzer.pyc')" >>MobileLogViewer_Deploy/main.py
echo "print('Proxy loading real file: %s' % real_file)" >>MobileLogViewer_Deploy/main.py
echo "spec = util.spec_from_file_location('MobileCrashAnalyzer', real_file)" >>MobileLogViewer_Deploy/main.py
echo "print(f'{spec = }')" >>MobileLogViewer_Deploy/main.py
echo "mod = util.module_from_spec(spec)" >>MobileLogViewer_Deploy/main.py
echo "# we don't want to add our module to sys.modules to not interfere with the package path having the same name" >>MobileLogViewer_Deploy/main.py
echo "# (just like if our real_file was the real python script started)" >>MobileLogViewer_Deploy/main.py
echo "print(f'{mod = }')" >>MobileLogViewer_Deploy/main.py
echo "out = spec.loader.exec_module(mod)" >>MobileLogViewer_Deploy/main.py
echo "print(f'Proxied file returned with `{out}`, terminating...')" >>MobileLogViewer_Deploy/main.py
echo " "
echo "buildozer.spec:"
cat MobileLogViewer_Deploy/buildozer.spec
echo " "
echo "main.py:"
cat MobileLogViewer_Deploy/main.py
- name: Build with Buildozer
uses: Sobottasgithub/[email protected]
id: buildozer
with:
workdir: MobileLogViewer_Deploy
buildozer_version: stable
- name: Sign Apk
id: signer
run: |
apkinfile="${{ steps.buildozer.outputs.filename }}"
apkoutfile="$HOME/signed-$(basename "${apkinfile}")"
echo -n "${{ secrets.APK_SIGNING_KEY }}" >"$HOME/keystore.key"
openssl enc -d -chacha20 -pbkdf2 -in src/MobileLogViewer/data/conf/release.keystore.enc -out "$HOME/release.keystore" -kfile "$HOME/keystore.key"
cat "$HOME/keystore.key" | apksigner sign -ks "$HOME/release.keystore" -in "${apkinfile}" -out "${apkoutfile}"
echo "unsigned_apk=${apkinfile}" >> "$GITHUB_OUTPUT"
echo "signed_apk=${apkoutfile}" >> "$GITHUB_OUTPUT"
- name: Upload signed apk
uses: actions/upload-artifact@v4
with:
name: MobileLogViewer
path: ${{ steps.signer.outputs.signed_apk }}
build-desktop:
name: Build ${{ matrix.OUT_FILE_NAME }} for ${{ matrix.TARGET }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
# LogViewer
- os: macos-latest
TARGET: macos
#--volicon "Hello World.icns" \
# for the dmg stuff, see https://www.pythonguis.com/tutorials/packaging-pyqt5-applications-pyinstaller-macos-dmg/
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "LogViewer" --add-data "LogViewer/data:LogViewer/data" --add-data "shared/ui/*.ui:shared/ui" --add-data "LogViewer/ui/*.ui:LogViewer/ui" --specpath src --windowed --icon LogViewer/data/art/icon.png --onefile --debug bootloader --argv-emulation src/LogViewer.py &&
cd dist/ &&
zip -r9 LogViewer LogViewer.app/ &&
brew install create-dmg &&
mkdir -p dmg &&
cp -vr "LogViewer.app" dmg/ &&
create-dmg --volname "LogViewer" --volicon LogViewer.app/Contents/Resources/generated-* --window-pos 200 120 --window-size 600 300 --icon-size 100 --icon "LogViewer.app" 175 120 --hide-extension "LogViewer.app" --app-drop-link 425 120 "LogViewer.dmg" "./dmg/"
OUT_FILE_NAME: LogViewer.dmg
ASSET_MIME: application/binary
- os: windows-latest
TARGET: windows
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "LogViewer" --add-data "LogViewer/data;LogViewer/data" --add-data "shared/ui/*.ui;shared/ui" --add-data "LogViewer/ui/*.ui;LogViewer/ui" --specpath src --windowed --icon LogViewer/data/art/icon.png --onefile --debug bootloader src/LogViewer.py
OUT_FILE_NAME: LogViewer.exe
ASSET_MIME: application/vnd.microsoft.portable-executable
- os: ubuntu-latest
TARGET: linux
#sudo apt install plasma-integration -y &&
#sudo cp -av /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/KDEPlasmaPlatformTheme.so /opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/PyQt5/Qt5/plugins/platformthemes/ -f &&
#--add-binary "/usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/KDEPlasmaPlatformTheme.so:PyQt5/Qt5/plugins/platformthemes"
#--add-binary "/lib/x86_64-linux-gnu/libz.so.1:."
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "LogViewer" --add-data "LogViewer/data:LogViewer/data" --add-data "shared/ui/*.ui:shared/ui" --add-data "LogViewer/ui/*.ui:LogViewer/ui" --specpath src --windowed --icon LogViewer/data/art/icon.png --onefile src/LogViewer.py
OUT_FILE_NAME: LogViewer
ASSET_MIME: application/x-executable
# CrashAnalyzer
- os: macos-latest
TARGET: macos
#--volicon "Hello World.icns" \
# for the dmg stuff, see https://www.pythonguis.com/tutorials/packaging-pyqt5-applications-pyinstaller-macos-dmg/
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "CrashAnalyzer" --add-data "CrashAnalyzer/data:CrashAnalyzer/data" --add-data "shared/ui/*.ui:shared/ui" --add-data "CrashAnalyzer/ui/*.ui:CrashAnalyzer/ui" --specpath src --windowed --icon CrashAnalyzer/data/art/icon.png --onefile --debug bootloader --argv-emulation src/CrashAnalyzer.py &&
cd dist/ &&
zip -r9 CrashAnalyzer CrashAnalyzer.app/ &&
brew install create-dmg &&
mkdir -p dmg &&
cp -vr "CrashAnalyzer.app" dmg/ &&
create-dmg --volname "CrashAnalyzer" --volicon CrashAnalyzer.app/Contents/Resources/generated-* --window-pos 200 120 --window-size 600 300 --icon-size 100 --icon "CrashAnalyzer.app" 175 120 --hide-extension "CrashAnalyzer.app" --app-drop-link 425 120 "CrashAnalyzer.dmg" "./dmg/"
OUT_FILE_NAME: CrashAnalyzer.dmg
ASSET_MIME: application/binary
- os: windows-latest
TARGET: windows
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "CrashAnalyzer" --add-data "CrashAnalyzer/data;CrashAnalyzer/data" --add-data "shared/ui/*.ui;shared/ui" --add-data "CrashAnalyzer/ui/*.ui;CrashAnalyzer/ui" --specpath src --windowed --icon CrashAnalyzer/data/art/icon.png --onefile --debug bootloader src/CrashAnalyzer.py
OUT_FILE_NAME: CrashAnalyzer.exe
ASSET_MIME: application/vnd.microsoft.portable-executable
- os: ubuntu-latest
TARGET: linux
#sudo apt install plasma-integration -y &&
#sudo cp -av /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/KDEPlasmaPlatformTheme.so /opt/hostedtoolcache/Python/3.11.5/x64/lib/python3.11/site-packages/PyQt5/Qt5/plugins/platformthemes/ -f &&
#--add-binary "/usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/KDEPlasmaPlatformTheme.so:PyQt5/Qt5/plugins/platformthemes"
#--add-binary "/lib/x86_64-linux-gnu/libz.so.1:."
CMD_BUILD: >
pyinstaller --clean --log-level DEBUG --name "CrashAnalyzer" --add-data "CrashAnalyzer/data:CrashAnalyzer/data" --add-data "shared/ui/*.ui:shared/ui" --add-data "CrashAnalyzer/ui/*.ui:CrashAnalyzer/ui" --specpath src --windowed --icon CrashAnalyzer/data/art/icon.png --onefile src/CrashAnalyzer.py
OUT_FILE_NAME: CrashAnalyzer
ASSET_MIME: application/x-executable
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
# requirements.txt was created using pipreqs
- name: Install common dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade pyinstaller
pip install --upgrade pyinstaller-hooks-contrib
pip install --upgrade Pillow
pip install --upgrade tk
pip install --upgrade tcl
pip install --upgrade -r src/requirements.txt
- name: Extract version string
run: echo "VERSION='${{ github.ref_name }}'" >src/shared/utils/version.py
- name: Build with pyinstaller for ${{matrix.TARGET}}
run: ${{matrix.CMD_BUILD}}
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.OUT_FILE_NAME}}
path: ./dist/${{ matrix.OUT_FILE_NAME}}
createrelease:
name: Create Release
runs-on: [ubuntu-latest]
needs: [build-desktop, build-android-MMCA, build-android-MMLV]
steps:
- name: Load build artifacts
uses: actions/download-artifact@v4
- name: Generate release notes
id: releasenotes
uses: tmolitor-stud-tu/github-releasenotes-generator@main
with:
NO_CREATE_RELEASE: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Release
uses: softprops/action-gh-release@v2
with:
name: Release ${{ github.ref_name }}
tag_name: ${{ github.ref }}
target_commitish: master
generate_release_notes: false
body: ${{ steps.releasenotes.outputs.notes }}
files: |
LogViewer*/*
CrashAnalyzer*/*
MobileCrashAnalyzer*/*
MobileLogViewer*/*
fail_on_unmatched_files: true
token: ${{ secrets.GITHUB_TOKEN }}
draft: false