Skip to content

Commit

Permalink
[CI] Move AppImage build script out of Github Action into a bash scri…
Browse files Browse the repository at this point in the history
…pt to facilitate local testing
  • Loading branch information
mxmlnkn committed Nov 13, 2022
1 parent 3f939be commit 98ab9a9
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 67 deletions.
72 changes: 5 additions & 67 deletions .github/workflows/appimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,80 +11,18 @@ jobs:
runs-on: ubuntu-latest
container: quay.io/pypa/manylinux2014_x86_64
env:
appbase: ratarmount-manylinux2014_x86_64
appdir: ratarmount-manylinux2014_x86_64.AppDir
APP_PYTHON_VERSION: "3.11"
steps:
- uses: actions/checkout@v3

- name: Print System Information
run: |
echo "uname -a: $( uname -a )"
cat /etc/issue
echo "Shell: $SHELL"
echo "Mount points:"; mount
- name: Install System Build Tools
run: |
ln -s /opt/python/cp39-cp39/bin/python3 /usr/local/bin/python3
export PATH="/opt/python/cp39-cp39/bin:$PATH"
python3 -m pip install python-appimage
yum install -y fuse fakeroot patchelf fuse-libs libsqlite3x strace desktop-file-utils
- name: Install AppImage Tooling
run: |
curl -L -o /usr/bin/appimagetool 'https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage'
chmod u+x /usr/bin/appimagetool
curl -L -o /usr/bin/linuxdeploy 'https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage'
chmod u+x /usr/bin/linuxdeploy
- name: Build Base Python AppImage With Ratarmount Metadata
run: |
python3 -m python_appimage build app -l manylinux2014_x86_64 -p 3.9 AppImage/
- name: Extract AppImage to AppDir for Further Modification
run: |
./ratarmount-x86_64.AppImage --appimage-extract
mv squashfs-root/ "$appdir"
- name: Install Ratarmount into AppDir
run: |
"$appdir/opt/python3.9/bin/python3.9" -I -m pip install --no-cache-dir ./core
"$appdir/opt/python3.9/bin/python3.9" -I -m pip install --no-cache-dir .
- name: Bundle System Dependencies into AppDir
run: |
# Note that manylinux2014 already has libsqlite3.so.0 inside /usr/lib.
cp -a $( repoquery -l fuse-libs | 'grep' 'lib64.*[.]so' ) "$appdir"/usr/lib/
APPIMAGE_EXTRACT_AND_RUN=1 linuxdeploy --appdir="$appdir" \
--library=/usr/lib64/libfuse.so.2 \
--library=/usr/lib64/libulockmgr.so.1 \
--executable=/usr/bin/fusermount \
--executable=/usr/bin/ulockmgr_server
- name: Clean up Unnecessary Files from AppDir
run: |
"$appdir/opt/python3.9/bin/python3.9" -s -m pip uninstall -y build setuptools wheel pip
rm -rf "$appdir/opt/python3.9/lib/python3.9/site-packages/indexed_gzip/tests" \
"$appdir/opt/python3.9/include" \
"$appdir/usr/share/tcltk" \
"$appdir/usr/lib/libtk8.5.so" \
"$appdir/usr/lib/libtcl8.5.so" \
"$appdir/opt/python3.9/lib/python3.9/ensurepip" \
"$appdir/opt/python3.9/lib/python3.9/lib2to3" \
"$appdir/opt/python3.9/lib/python3.9/tkinter" \
"$appdir/opt/python3.9/lib/python3.9/unittest"
find "$appdir" -type d -empty -print0 | xargs -0 rmdir
find "$appdir" -type d -empty -print0 | xargs -0 rmdir
find "$appdir" -name '__pycache__' -print0 | xargs -0 rm -r
- name: Create AppImage from Modified AppDir
run: |
APPIMAGE_EXTRACT_AND_RUN=1 ARCH=x86_64 appimagetool --no-appstream "$appbase".App{Dir,Image}
- name: Build AppImage
working-directory: AppImage
run: bash build-ratarmount-appimage.sh

- uses: actions/upload-artifact@v3
with:
name: ratarmount-manylinux2014_x86_64.AppImage
path: ratarmount-manylinux2014_x86_64.AppImage
path: AppImage/ratarmount-manylinux2014_x86_64.AppImage


AppImage-Tests:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ ratarmount++/
*momo*
presentation/
*.AppImage
*.AppDir/
appimagetool
linuxdeploy


# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
146 changes: 146 additions & 0 deletions AppImage/build-ratarmount-appimage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env bash

# E.g., run this cript inside the manylinux2014 container and mount the whole ratarmount git root:
# docker run -v$PWD:/project -it quay.io/pypa/manylinux2014_x86_64 bash
# cd /project/AppImage && ./build-ratarmount-appimage.sh

function commandExists()
{
command -v "$1" > /dev/null 2>&1
}

function installSystemRequirements()
{
export PATH="/opt/python/cp39-cp39/bin:$PATH"
python3 -m pip install python-appimage
yum -y install epel-release
yum install -y fuse fakeroot patchelf fuse-libs libsqlite3x strace desktop-file-utils
}

function installAppImageTools()
{
toolName='appimagetool'
if [[ ! -x $toolName ]]; then
curl -L -o "$toolName" \
'https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage'
chmod u+x "$toolName"
fi

toolName='linuxdeploy'
if [[ ! -x "$toolName" ]]; then
curl -L -o "$toolName" \
'https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage'
chmod u+x "$toolName"
fi

export PATH="$PWD:$PATH"
}

function installAppImagePythonPackages()
{
# Unfortunately, building from source only works with the same manylinux container from which the
# AppImage python binary has been stripped out from! Else, it seems to have hardcoded the path to Python.h
# and that path will not exist when running the python binary directly on a different host system.
# The compilation call will contain this: -I/opt/_internal/cpython-3.9.15/include/python3.9
# Even though it should be like this: -I<path-to-appdir>/opt/_internal/cpython-3.9.15/include/python3.9
if [[ -n "$USE_CUTTING_EDGE_BACKENDS" ]]; then
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir \
'git+https://github.com/mxmlnkn/indexed_bzip2.git@master#egginfo=indexed_bzip2&subdirectory=python/indexed_bzip2'
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir \
'git+https://github.com/mxmlnkn/indexed_bzip2.git@master#egginfo=pragzip&subdirectory=python/pragzip'
else
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir indexed_bzip2
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir pragzip
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir ../core
"$APP_PYTHON_BIN" -I -m pip install --no-cache-dir ..
fi
}

function installAppImageSystemLibraries()
{
# Note that manylinux2014 already has libsqlite3.so.0 inside /usr/lib.
if commandExists repoquery; then
'cp' -a $( repoquery -l fuse-libs | 'grep' 'lib64.*[.]so' ) "$APP_DIR"/usr/lib/
elif commandExists dnf; then
'cp' -a $( dnf repoquery -l fuse-libs | 'grep' 'lib64.*[.]so' ) "$APP_DIR"/usr/lib/
else
echo -e "\e[31mCannot gather FUSE libs into AppImage without (dnf) repoquery.\e[0m"
fi

APPIMAGE_EXTRACT_AND_RUN=1 linuxdeploy --appdir="$APP_DIR" \
--library=/usr/lib64/libfuse.so.2 \
--library=/usr/lib64/libulockmgr.so.1 \
--executable=/usr/bin/fusermount \
--executable=/usr/bin/ulockmgr_server
}

function trimAppImage()
{
APP_PYTHON_BASE="${appdir}/opt/python${APP_PYTHON_VERSION}"
APP_PYTHON_LIB="${APP_PYTHON_BASE}/lib/python${APP_PYTHON_VERSION}"
"$APP_PYTHON_BIN" -s -m pip uninstall -y build setuptools wheel pip
'rm' -rf "$APP_PYTHON_LIB/site-packages/indexed_gzip/tests" \
"$APP_PYTHON_BASE/include" \
"$APP_DIR/usr/share/tcltk" \
"$APP_PYTHON_LIB/ensurepip" \
"$APP_PYTHON_LIB/lib2to3" \
"$APP_PYTHON_LIB/tkinter" \
"$APP_PYTHON_LIB/unittest"
find "$APP_DIR/usr/lib/" -name 'libtk8*.so' -delete
find "$APP_DIR/usr/lib/" -name 'libtcl8*.so' -delete
find "$APP_DIR" -type d -empty -print0 | xargs -0 rmdir
find "$APP_DIR" -type d -empty -print0 | xargs -0 rmdir
find "$APP_DIR" -name '__pycache__' -print0 | xargs -0 rm -r
}


# Main entry

# AUDITWHEEL_ARCH is set inside the manylinux container automatically
if [[ -n $AUDITWHEEL_ARCH ]]; then
APPIMAGE_ARCH=$AUDITWHEEL_ARCH
else
APPIMAGE_ARCH=$( uname -m )
fi

if [[ -n $AUDITWHEEL_PLAT ]]; then
APPIMAGE_PLATFORM=$AUDITWHEEL_PLAT
else
APPIMAGE_PLATFORM="manylinux2014_$APPIMAGE_ARCH"
fi

APP_BASE="ratarmount-$APPIMAGE_PLATFORM"
APP_DIR="$APP_BASE.AppDir"
if [[ -z $APP_PYTHON_VERSION ]]; then
APP_PYTHON_VERSION=3.11
fi
APP_PYTHON_BIN="$APP_DIR/opt/python$APP_PYTHON_VERSION/bin/python$APP_PYTHON_VERSION"

echo "Install System Build Tools"
if [[ -n $AUDITWHEEL_ARCH ]]; then
# If manylinux container is implied as the current host system, install requirements.
installSystemRequirements
fi

echo "Install AppImage Tooling"
installAppImageTools

echo "Build Base Python AppImage With Ratarmount Metadata"
python3 -m python_appimage build app -l "$APPIMAGE_PLATFORM" -p "$APP_PYTHON_VERSION" ratarmount-metadata/

echo "Extract AppImage to AppDir for Further Modification"
./"ratarmount-$APPIMAGE_ARCH.AppImage" --appimage-extract
'rm' -rf "$APP_DIR"
mv squashfs-root/ "$APP_DIR"

echo "Install Ratarmount into AppDir"
installAppImagePythonPackages

echo "Bundle System Dependencies into AppDir"
installAppImageSystemLibraries

echo "Clean up Unnecessary Files from AppDir"
trimAppImage

echo "Create AppImage from Modified AppDir"
APPIMAGE_EXTRACT_AND_RUN=1 ARCH="$APPIMAGE_ARCH" appimagetool --no-appstream "$APP_BASE".App{Dir,Image}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes

0 comments on commit 98ab9a9

Please sign in to comment.