diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index ec8b315d..8043f8ee 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,5 +1,5 @@ # build-linux.yml -# Reusable workflow that builds the Linux and MacOS versions of Libation. +# Reusable workflow that builds the Linux and MacOS (x64 and xmd64) versions of Libation. --- name: build @@ -19,6 +19,7 @@ on: env: DOTNET_CONFIGURATION: 'Release' DOTNET_VERSION: '7.0.x' + RELEASE_NAME: 'chardonnay' jobs: build: @@ -26,8 +27,7 @@ jobs: strategy: matrix: os: [Linux, MacOS] - ui: [Avalonia] - release_name: [chardonnay] + arch: [x64, arm64] steps: - uses: actions/checkout@v3 - name: Setup .NET @@ -57,25 +57,50 @@ jobs: - name: Publish working-directory: ./Source run: | - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} Libation${{ matrix.ui }}/Libation${{ matrix.ui }}.csproj -p:PublishProfile=Libation${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} LoadByOS/${{ matrix.os }}ConfigApp/${{ matrix.os }}ConfigApp.csproj -p:PublishProfile=LoadByOS/Properties/${{ matrix.os }}ConfigApp/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} LibationCli/LibationCli.csproj -p:PublishProfile=LibationCli/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} Hangover${{ matrix.ui }}/Hangover${{ matrix.ui }}.csproj -p:PublishProfile=Hangover${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - - - name: Zip artifact - id: zip - working-directory: ./Source/bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} + os=${{ matrix.os }} + RUNTIME_IDENTIFIER="$(echo ${os,} | sed 's/macOS/osx/')-${{ matrix.arch }}" + echo "$RUNTIME_IDENTIFIER" + dotnet publish \ + --runtime "$RUNTIME_IDENTIFIER" \ + --configuration ${{ env.DOTNET_CONFIGURATION }} \ + --output bin/Publish/${{ matrix.os }}-${{ matrix.arch }}-${{ env.RELEASE_NAME }} \ + LibationAvalonia/LibationAvalonia.csproj \ + -p:PublishProfile=LibationAvalonia/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish \ + --runtime "$RUNTIME_IDENTIFIER" \ + --configuration ${{ env.DOTNET_CONFIGURATION }} \ + --output bin/Publish/${{ matrix.os }}-${{ matrix.arch }}-${{ env.RELEASE_NAME }} \ + LoadByOS/${{ matrix.os }}ConfigApp/${{ matrix.os }}ConfigApp.csproj \ + -p:PublishProfile=LoadByOS/Properties/${{ matrix.os }}ConfigApp/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish \ + --runtime "$RUNTIME_IDENTIFIER" \ + --configuration ${{ env.DOTNET_CONFIGURATION }} \ + --output bin/Publish/${{ matrix.os }}-${{ matrix.arch }}-${{ env.RELEASE_NAME }} \ + LibationCli/LibationCli.csproj \ + -p:PublishProfile=LibationCli/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish \ + --runtime "$RUNTIME_IDENTIFIER" \ + --configuration ${{ env.DOTNET_CONFIGURATION }} \ + --output bin/Publish/${{ matrix.os }}-${{ matrix.arch }}-${{ env.RELEASE_NAME }} \ + HangoverAvalonia/HangoverAvalonia.csproj \ + -p:PublishProfile=HangoverAvalonia/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + + - name: Build bundle + id: bundle + working-directory: ./Source/bin/Publish/${{ matrix.os }}-${{ matrix.arch }}-${{ env.RELEASE_NAME }} run: | - delfiles=("libmp3lame.x86.dll" "libmp3lame.x64.dll" "ffmpegaac.x86.dll" "ffmpegaac.x64.dll") - for n in "${delfiles[@]}"; do rm "$n"; done - osbuild="$(echo '${{ matrix.os }}' | tr '[:upper:]' '[:lower:]')" - artifact="Libation.${{ steps.get_version.outputs.version }}-${osbuild}-${{ matrix.release_name }}" + BUNDLE_DIR=$(pwd) + echo "Bundle dir: ${BUNDLE_DIR}" + cd .. + SCRIPT=../../../Scripts/Bundle_${{ matrix.os }}.sh + chmod +rx ${SCRIPT} + ${SCRIPT} "${BUNDLE_DIR}" "${{ steps.get_version.outputs.version }}" "${{ matrix.arch }}" + artifact=$(ls ./bundle) echo "artifact=${artifact}" >> "${GITHUB_OUTPUT}" - tar -zcvf "../${artifact}.tar.gz" . - - - name: Publish artifact + + - name: Publish bundle uses: actions/upload-artifact@v3 with: - name: ${{ steps.zip.outputs.artifact }}.tar.gz - path: ./Source/bin/Publish/${{ steps.zip.outputs.artifact }}.tar.gz + name: ${{ steps.bundle.outputs.artifact }} + path: ./Source/bin/Publish/bundle/${{ steps.bundle.outputs.artifact }} if-no-files-found: error diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index f82aa21e..03241154 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -60,21 +60,49 @@ jobs: - name: Publish working-directory: ./Source run: | - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} Libation${{ matrix.ui }}/Libation${{ matrix.ui }}.csproj -p:PublishProfile=Libation${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} LoadByOS/${{ matrix.os }}ConfigApp/${{ matrix.os }}ConfigApp.csproj -p:PublishProfile=LoadByOS/Properties/${{ matrix.os }}ConfigApp/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} LibationCli/LibationCli.csproj -p:PublishProfile=LibationCli/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - dotnet publish -c ${{ env.DOTNET_CONFIGURATION }} -o bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} Hangover${{ matrix.ui }}/Hangover${{ matrix.ui }}.csproj -p:PublishProfile=Hangover${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish ` + --configuration ${{ env.DOTNET_CONFIGURATION }} ` + --output bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} ` + Libation${{ matrix.ui }}/Libation${{ matrix.ui }}.csproj ` + -p:PublishProfile=Libation${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish ` + --configuration ${{ env.DOTNET_CONFIGURATION }} ` + --output bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} ` + LoadByOS/${{ matrix.os }}ConfigApp/${{ matrix.os }}ConfigApp.csproj ` + -p:PublishProfile=LoadByOS/Properties/${{ matrix.os }}ConfigApp/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish ` + --configuration ${{ env.DOTNET_CONFIGURATION }} ` + --output bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} ` + LibationCli/LibationCli.csproj ` + -p:PublishProfile=LibationCli/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml + dotnet publish ` + --configuration ${{ env.DOTNET_CONFIGURATION }} ` + --output bin/Publish/${{ matrix.os }}-${{ matrix.release_name }} ` + Hangover${{ matrix.ui }}/Hangover${{ matrix.ui }}.csproj ` + -p:PublishProfile=Hangover${{ matrix.ui }}/Properties/PublishProfiles/${{ matrix.os }}Profile.pubxml - name: Zip artifact id: zip working-directory: ./Source/bin/Publish run: | - $dir = "${{ matrix.os }}-${{ matrix.release_name }}\" - $delfiles = @("libmp3lame.so", "ffmpegaac.so", "glass-with-glow_256.svg", "Libation.desktop") - foreach ($file in $delfiles){ if (test-path $dir$file){ Remove-Item $dir$file } } + $bin_dir = "${{ matrix.os }}-${{ matrix.release_name }}\" + $delfiles = @( + "libmp3lame.x64.so", + "libmp3lame.arm64.so", + "libmp3lame.x64.dylib", + "libmp3lame.arm64.dylib", + "ffmpegaac.x64.so", + "ffmpegaac.arm64.so", + "ffmpegaac.x64.dylib", + "ffmpegaac.arm64.dylib", + "WindowsConfigApp.exe", + "WindowsConfigApp.runtimeconfig.json", + "WindowsConfigApp.deps.json" + ) + foreach ($file in $delfiles){ if (test-path $bin_dir$file){ Remove-Item $bin_dir$file } } $artifact="${{ matrix.prefix }}Libation.${{ steps.get_version.outputs.version }}-" + "${{ matrix.os }}".ToLower() + "-${{ matrix.release_name }}" "artifact=$artifact" >> $env:GITHUB_OUTPUT - Compress-Archive -Path "${dir}*" -DestinationPath "$artifact.zip" + Compress-Archive -Path "${bin_dir}*" -DestinationPath "$artifact.zip" - name: Publish artifact uses: actions/upload-artifact@v3 diff --git a/.github/workflows/bundle-linux.yml b/.github/workflows/bundle-linux.yml deleted file mode 100644 index 1a187276..00000000 --- a/.github/workflows/bundle-linux.yml +++ /dev/null @@ -1,43 +0,0 @@ -# build-linux.yml -# Reusable workflow that builds the Libation installation bundles for Linux and MacOS. ---- -name: bundle-linux - -on: - workflow_call: - inputs: - version: - type: string - description: 'Version number' - required: true - -jobs: - bundle: - runs-on: ubuntu-latest - strategy: - matrix: - os: [linux, macos] - release_name: [chardonnay] - steps: - - uses: actions/checkout@v3 - - - name: Download Artifact - uses: actions/download-artifact@v3 - with: - name: "Libation.${{ inputs.version }}-${{ matrix.os }}-${{ matrix.release_name }}.tar.gz" - - - name: Build bundle - id: build - run: | - SCRIPT=targz2${{ matrix.os }}bundle.sh - chmod +rwx ./Scripts/${SCRIPT} - ./Scripts/${SCRIPT} "Libation.${{ inputs.version }}-${{ matrix.os }}-${{ matrix.release_name }}.tar.gz" ${{ inputs.version }} - artifact=$(ls ./bundle) - echo "artifact=${artifact}" >> "${GITHUB_OUTPUT}" - - - name: Publish bundle - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.build.outputs.artifact }} - path: ./bundle/${{ steps.build.outputs.artifact }} - if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d9e5fca..8495289e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,15 +33,9 @@ jobs: with: version_override: ${{ needs.prerelease.outputs.version }} run_unit_tests: false - - bundle: - needs: [prerelease,build] - uses: ./.github/workflows/bundle-linux.yml - with: - version: ${{ needs.prerelease.outputs.version }} release: - needs: [prerelease,build,bundle] + needs: [prerelease,build] runs-on: ubuntu-latest steps: - name: Download artifacts diff --git a/.releaseindex.json b/.releaseindex.json index 870c942e..75ca6a6f 100644 --- a/.releaseindex.json +++ b/.releaseindex.json @@ -1,6 +1,8 @@ { - "WindowsClassic": "Libation\\.\\d+\\.\\d+\\.\\d+-win(dows)?-classic\\.zip", - "WindowsAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+-win(dows)?-chardonnay\\.zip", - "LinuxAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+-linux-chardonnay\\.deb", - "MacOSAvalonia": "Libation\\.app-macOS-x64-\\d+\\.\\d+\\.\\d+\\.tgz" + "WindowsClassic": "Libation\\.\\d+\\.\\d+\\.\\d+-win(dows)?-classic\\.zip", + "WindowsAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+-win(dows)?-chardonnay\\.zip", + "LinuxAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+-linux-amd64\\.deb", + "MacOSAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+-macOS-x86_64\\.tgz" + "LinuxAvalonia_Arm64": "Libation\\.\\d+\\.\\d+\\.\\d+-linux-arm64\\.deb", + "MacOSAvalonia_Arm64": "Libation\\.\\d+\\.\\d+\\.\\d+-macOS-arm64\\.tgz" } diff --git a/Images/libation_cheers.svg b/Images/libation_cheers.svg new file mode 100644 index 00000000..9b60dba2 --- /dev/null +++ b/Images/libation_cheers.svg @@ -0,0 +1,32 @@ + + + + diff --git a/Images/libation_glass.svg b/Images/libation_glass.svg new file mode 100644 index 00000000..d3a0a092 --- /dev/null +++ b/Images/libation_glass.svg @@ -0,0 +1,28 @@ + + + + + diff --git a/Images/libation_hangover.svg b/Images/libation_hangover.svg new file mode 100644 index 00000000..e1759e86 --- /dev/null +++ b/Images/libation_hangover.svg @@ -0,0 +1,30 @@ + + + + + + + diff --git a/Images/libation_slosh.svg b/Images/libation_slosh.svg new file mode 100644 index 00000000..d97b41ee --- /dev/null +++ b/Images/libation_slosh.svg @@ -0,0 +1,33 @@ + + + + diff --git a/Scripts/targz2linuxbundle.sh b/Scripts/Bundle_Linux.sh similarity index 52% rename from Scripts/targz2linuxbundle.sh rename to Scripts/Bundle_Linux.sh index b4806ad8..de1995ed 100644 --- a/Scripts/targz2linuxbundle.sh +++ b/Scripts/Bundle_Linux.sh @@ -1,17 +1,18 @@ #!/bin/bash -FILE=$1; shift +BIN_DIR=$1; shift VERSION=$1; shift +ARCH=$1; shift -if [ -z "$FILE" ] +if [ -z "$BIN_DIR" ] then - echo "This script must be called with a the Libation Linux bin zip file as an argument." + echo "This script must be called with a the Libation Linux bins directory as an argument." exit fi -if [ ! -f "$FILE" ] +if [ ! -d "$BIN_DIR" ] then - echo "The file \"$FILE\" does not exist." + echo "The directory \"$BIN_DIR\" does not exist." exit fi @@ -21,57 +22,69 @@ then exit fi +if [ -z "$ARCH" ] +then + echo "This script must be called with the Libation cpu architecture as an argument." + exit +fi + contains() { case "$1" in *"$2"*) true ;; *) false ;; esac } -if ! contains "$FILE" "$VERSION" +if ! contains "$BIN_DIR" "$ARCH" then - echo "This script must be called with a Libation version number that is present in the filename passed." + echo "This script must be called with a Libation binaries for ${ARCH}." exit fi -# remove trailing ".tar.gz" -FOLDER_MAIN=${FILE::-7} -echo "Working dir: $FOLDER_MAIN" +ARCH=$(echo $ARCH | sed 's/x64/amd64/') -if [[ -d "$FOLDER_MAIN" ]] -then - echo "$FOLDER_MAIN directory already exists, aborting." - exit -fi +DEB_DIR=./deb -FOLDER_EXEC="$FOLDER_MAIN/usr/lib/libation" +FOLDER_EXEC=$DEB_DIR/usr/lib/libation echo "Exec dir: $FOLDER_EXEC" +mkdir -p $FOLDER_EXEC -FOLDER_ICON="$FOLDER_MAIN/usr/share/icons/hicolor/scalable/apps/" -echo "Icon dir: $FOLDER_ICON" - -FOLDER_DESKTOP="$FOLDER_MAIN/usr/share/applications" -echo "Desktop dir: $FOLDER_DESKTOP" - -FOLDER_DEBIAN="$FOLDER_MAIN/DEBIAN" -echo "Debian dir: $FOLDER_DEBIAN" - -mkdir -p "$FOLDER_EXEC" -mkdir -p "$FOLDER_ICON" -mkdir -p "$FOLDER_DESKTOP" -mkdir -p "$FOLDER_DEBIAN" - -echo "Extracting $FILE to $FOLDER_EXEC..." -tar -xzf ${FILE} -C ${FOLDER_EXEC} +echo "Moving bins from $BIN_DIR to $FOLDER_EXEC" +mv "${BIN_DIR}/"* $FOLDER_EXEC if [ $? -ne 0 ] - then echo "Error extracting ${FILE}" + then echo "Error moving ${BIN_DIR} files" exit fi + +delfiles=('libmp3lame.x64.dylib' 'libmp3lame.arm64.dylib' 'ffmpegaac.x64.dylib' 'ffmpegaac.arm64.dylib' 'libmp3lame.x64.dll' 'ffmpegaac.x64.dll' 'libmp3lame.x86.dll' 'ffmpegaac.x86.dll' 'LinuxConfigApp' 'LinuxConfigApp.runtimeconfig.json' 'LinuxConfigApp.deps.json') +if [[ "$ARCH" == "arm64" ]] +then + delfiles+=('libmp3lame.x64.so' 'ffmpegaac.x64.so') +else + delfiles+=('libmp3lame.arm64.so' 'ffmpegaac.arm64.so') +fi + +for n in "${delfiles[@]}" +do + echo "Deleting $n" + rm $FOLDER_EXEC/$n +done + +FOLDER_ICON=$DEB_DIR/usr/share/icons/hicolor/scalable/apps/ +echo "Icon dir: $FOLDER_ICON" + +FOLDER_DESKTOP=$DEB_DIR/usr/share/applications +echo "Desktop dir: $FOLDER_DESKTOP" + +FOLDER_DEBIAN=$DEB_DIR/DEBIAN +echo "Debian dir: $FOLDER_DEBIAN" + +mkdir -p $FOLDER_ICON +mkdir -p $FOLDER_DESKTOP +mkdir -p $FOLDER_DEBIAN + echo "Copying icon..." -cp "$FOLDER_EXEC/glass-with-glow_256.svg" "$FOLDER_ICON/libation.svg" +cp $FOLDER_EXEC/libation_glass.svg $FOLDER_ICON/libation.svg echo "Copying desktop file..." -cp "$FOLDER_EXEC/Libation.desktop" "$FOLDER_DESKTOP/Libation.desktop" - -echo "Workaround for desktop file..." -sed -i '/^Exec=Libation/c\Exec=/usr/bin/libation' "$FOLDER_DESKTOP/Libation.desktop" +cp $FOLDER_EXEC/Libation.desktop $FOLDER_DESKTOP/Libation.desktop echo "Creating pre-install file..." echo "#!/bin/bash @@ -81,20 +94,16 @@ echo "#!/bin/bash echo \"Removing previously created symlinks...\" rm /usr/bin/libation -rm /usr/bin/Libation rm /usr/bin/hangover -rm /usr/bin/Hangover rm /usr/bin/libationcli -rm /usr/bin/LibationCli echo \"Removing previously installed Libation files...\" rm -r /usr/lib/libation -rm -r /usr/lib/Libation # making sure it won't stop installation exit 0 -" >> "$FOLDER_DEBIAN/preinst" +" >> $FOLDER_DEBIAN/preinst echo "Creating post-install file..." echo "#!/bin/bash @@ -114,29 +123,30 @@ fi # workaround until this file is moved to the user's home directory touch /usr/lib/libation/appsettings.json chmod 666 /usr/lib/libation/appsettings.json -" >> "$FOLDER_DEBIAN/postinst" +" >> $FOLDER_DEBIAN/postinst echo "Creating control file..." echo "Package: Libation Version: $VERSION -Architecture: all +Architecture: $ARCH Essential: no Priority: optional Maintainer: github.com/rmcrackan Description: liberate your audiobooks -" >> "$FOLDER_DEBIAN/control" +" >> $FOLDER_DEBIAN/control echo "Changing permissions for pre- and post-install files..." chmod +x "$FOLDER_DEBIAN/preinst" chmod +x "$FOLDER_DEBIAN/postinst" -echo "Creating .deb file..." -dpkg-deb -Zxz --build $FOLDER_MAIN +DEB_FILE="Libation.${VERSION}-linux-${ARCH}.deb" +echo "Creating $DEB_FILE" +dpkg-deb -Zxz --build $DEB_DIR ./$DEB_FILE +echo "moving to ./bundle/$DEB_FILE" mkdir bundle -echo "moving to ./bundle/$FOLDER_MAIN.deb" -mv "$FOLDER_MAIN.deb" "./bundle/$FOLDER_MAIN.deb" +mv $DEB_FILE ./bundle/$DEB_FILE -rm -r "$FOLDER_MAIN" +rm -r "$BIN_DIR" echo "Done!" diff --git a/Scripts/Bundle_MacOS.sh b/Scripts/Bundle_MacOS.sh new file mode 100644 index 00000000..5261aa2d --- /dev/null +++ b/Scripts/Bundle_MacOS.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +BIN_DIR=$1; shift +VERSION=$1; shift +ARCH=$1; shift + +if [ -z "$BIN_DIR" ] +then + echo "This script must be called with a the Libation macos bins directory as an argument." + exit +fi + +if [ ! -d "$BIN_DIR" ] +then + echo "The directory \"$BIN_DIR\" does not exist." + exit +fi + +if [ -z $VERSION ] +then + echo "This script must be called with the Libation version number as an argument." + exit +fi + +if [ -z $ARCH ] +then + echo "This script must be called with the Libation cpu architecture as an argument." + exit +fi + +contains() { case "$1" in *"$2"*) true ;; *) false ;; esac } + +if ! contains "$BIN_DIR" $ARCH +then + echo "This script must be called with a Libation binaries for ${ARCH}." + exit +fi + +ARCH=$(echo $ARCH | sed 's/x64/x86_64/') + +BUNDLE=./Libation.app +echo "Bundle dir: $BUNDLE" + +if [[ -d $BUNDLE ]] +then + echo "$BUNDLE directory already exists, aborting." + exit +fi + +BUNDLE_CONTENTS=$BUNDLE/Contents +echo "Bundle Contents dir: $BUNDLE_CONTENTS" + +BUNDLE_RESOURCES=$BUNDLE_CONTENTS/Resources +echo "Resources dir: $BUNDLE_RESOURCES" + +BUNDLE_MACOS=$BUNDLE_CONTENTS/MacOS +echo "MacOS dir: $BUNDLE_MACOS" + +mkdir -p $BUNDLE_CONTENTS +mkdir -p $BUNDLE_RESOURCES +mkdir -p $BUNDLE_MACOS + +mv "${BIN_DIR}/"* $BUNDLE_MACOS + +if [ $? -ne 0 ] + then echo "Error moving ${BIN_DIR} files" + exit +fi + +echo "Moving icon..." +mv $BUNDLE_MACOS/libation.icns $BUNDLE_RESOURCES/libation.icns + +echo "Moving Info.plist file..." +mv $BUNDLE_MACOS/Info.plist $BUNDLE_CONTENTS/Info.plist + +echo "Set LSArchitecturePriority to $ARCH" +sed -i -e "s/ARCHITECTURE_STRING/$ARCH/" $BUNDLE_CONTENTS/Info.plist + +echo "Set CFBundleVersion to $VERSION" +sed -i -e "s/VERSION_STRING/$VERSION/" $BUNDLE_CONTENTS/Info.plist + + +delfiles=('libmp3lame.x64.so' 'ffmpegaac.x64.so' 'libmp3lame.arm64.so' 'ffmpegaac.arm64.so' 'libmp3lame.x64.dll' 'ffmpegaac.x64.dll' 'libmp3lame.x86.dll' 'ffmpegaac.x86.dll' 'ffmpegaac.x86.dll' 'MacOSConfigApp' 'MacOSConfigApp.runtimeconfig.json' 'MacOSConfigApp.deps.json') +if [[ "$ARCH" == "arm64" ]] +then + delfiles+=('libmp3lame.x64.dylib' 'ffmpegaac.x64.dylib') +else + delfiles+=('libmp3lame.arm64.dylib' 'ffmpegaac.arm64.dylib') +fi + + +for n in "${delfiles[@]}" +do + echo "Deleting $n" + rm $BUNDLE_MACOS/$n +done + +APP_FILE=Libation.${VERSION}-macOS-${ARCH}.tgz + +echo "Creating app bundle: $APP_FILE" +tar -czvf $APP_FILE $BUNDLE + +mkdir bundle +echo "moving to ./bundle/$APP_FILE" +mv $APP_FILE ./bundle/$APP_FILE + +rm -r $BUNDLE + +echo "Done!" diff --git a/Scripts/targz2macosbundle.sh b/Scripts/targz2macosbundle.sh deleted file mode 100644 index e772ed31..00000000 --- a/Scripts/targz2macosbundle.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash - -FILE=$1; shift -VERSION=$1; shift - -if [ -z "$FILE" ] -then - echo "This script must be called with a the Libation macos bin zip file as an argument." - exit -fi - -if [ ! -f "$FILE" ] -then - echo "The file \"$FILE\" does not exist." - exit -fi - -if [ -z "$VERSION" ] -then - echo "This script must be called with the Libation version number as an argument." - exit -fi - -contains() { case "$1" in *"$2"*) true ;; *) false ;; esac } - -if ! contains "$FILE" "$VERSION" -then - echo "This script must be called with a Libation version number that is present in the filename passed." - exit -fi - -BUNDLE="Libation.app" -echo "Bundle dir: $BUNDLE" - -if [[ -d "$BUNDLE" ]] -then - echo "$BUNDLE directory already exists, aborting." - exit -fi - -BUNDLE_CONTENTS="$BUNDLE/Contents" -echo "Bundle Contents dir: $BUNDLE_CONTENTS" - -BUNDLE_RESOURCES="$BUNDLE_CONTENTS/Resources" -echo "Resources dir: $BUNDLE_RESOURCES" - -BUNDLE_MACOS="$BUNDLE_CONTENTS/MacOS" -echo "MacOS dir: $BUNDLE_MACOS" - -mkdir -p "$BUNDLE_CONTENTS" -mkdir -p "$BUNDLE_RESOURCES" -mkdir -p "$BUNDLE_MACOS" - -echo "Extracting $FILE to $BUNDLE_MACOS..." -tar -xzf ${FILE} -C ${BUNDLE_MACOS} - -if [ $? -ne 0 ] - then echo "Error extracting ${FILE}" - exit -fi - -echo "Copying icon..." -cp "$BUNDLE_MACOS/libation.icns" "$BUNDLE_RESOURCES/libation.icns" - -echo "Copying Info.plist file..." -cp "$BUNDLE_MACOS/Info.plist" "$BUNDLE_CONTENTS/Info.plist" - -echo "Set Libation version number..." -sed -i -e "s/VERSION_STRING/$VERSION/" "$BUNDLE_CONTENTS/Info.plist" - -echo "deleting unneeded files.." -delfiles=("libmp3lame.x64.so" "ffmpegaac.x64.so" "libation.icns" "Info.plist") -for n in "${delfiles[@]}"; do rm "$BUNDLE_MACOS/$n"; done - -echo "Creating app bundle: $BUNDLE-$VERSION.tar.gz" -tar -czvf "$BUNDLE-$VERSION.tar.gz" "$BUNDLE" - -mkdir bundle -echo "moving to ./bundle/$BUNDLE-$VERSION.tar.gz" -mv "$BUNDLE-$VERSION.tar.gz" "./bundle/$BUNDLE-macOS-x64-$VERSION.tgz" - -rm -r "$BUNDLE" - -echo "Done!" diff --git a/Source/AaxDecrypter/AaxDecrypter.csproj b/Source/AaxDecrypter/AaxDecrypter.csproj index 8b8bd394..96f2e6b5 100644 --- a/Source/AaxDecrypter/AaxDecrypter.csproj +++ b/Source/AaxDecrypter/AaxDecrypter.csproj @@ -13,7 +13,7 @@ - + diff --git a/Source/AppScaffolding/AppScaffolding.csproj b/Source/AppScaffolding/AppScaffolding.csproj index 7552b69a..f3d7499b 100644 --- a/Source/AppScaffolding/AppScaffolding.csproj +++ b/Source/AppScaffolding/AppScaffolding.csproj @@ -2,7 +2,7 @@ net7.0 - 9.3.2.1 + 9.3.1.1 diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index a44fe2d3..f7389977 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -21,7 +21,9 @@ namespace AppScaffolding WindowsClassic, WindowsAvalonia, LinuxAvalonia, - MacOSAvalonia + MacOSAvalonia, + LinuxAvalonia_Arm64, + MacOSAvalonia_Arm64 } // I know I'm taking the wine metaphor a bit far by naming this "Variety", but I don't know what else to call it @@ -35,7 +37,7 @@ namespace AppScaffolding public static ReleaseIdentifier ReleaseIdentifier { get; private set; } public static VarietyType Variety => ReleaseIdentifier == ReleaseIdentifier.WindowsClassic ? VarietyType.Classic - : ReleaseIdentifier.In(ReleaseIdentifier.WindowsAvalonia, ReleaseIdentifier.LinuxAvalonia, ReleaseIdentifier.MacOSAvalonia) ? VarietyType.Chardonnay + : Enum.IsDefined(ReleaseIdentifier) ? VarietyType.Chardonnay : VarietyType.None; public static void SetReleaseIdentifier(ReleaseIdentifier releaseID) @@ -296,8 +298,8 @@ namespace AppScaffolding } private static async System.Threading.Tasks.Task<(Octokit.Release, Octokit.ReleaseAsset)> getLatestRelease() { - var ownerAccount = "rmcrackan"; - var repoName = "Libation"; + const string ownerAccount = "rmcrackan"; + const string repoName = "Libation"; var gitHubClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(repoName)); @@ -305,12 +307,11 @@ namespace AppScaffolding var bts = await gitHubClient.Repository.Content.GetRawContent(ownerAccount, repoName, ".releaseindex.json"); var releaseIndex = JObject.Parse(System.Text.Encoding.ASCII.GetString(bts)); var regexPattern = releaseIndex.Value(ReleaseIdentifier.ToString()); - - // https://octokitnet.readthedocs.io/en/latest/releases/ - var releases = await gitHubClient.Repository.Release.GetAll(ownerAccount, repoName); - var regex = new System.Text.RegularExpressions.Regex(regexPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); - var latestRelease = releases.FirstOrDefault(r => !r.Draft && !r.Prerelease && r.Assets.Any(a => regex.IsMatch(a.Name))); + + //https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#get-the-latest-release + var latestRelease = await gitHubClient.Repository.Release.GetLatest(ownerAccount, repoName); + return (latestRelease, latestRelease?.Assets?.FirstOrDefault(a => regex.IsMatch(a.Name))); } } diff --git a/Source/LibationAvalonia/Program.cs b/Source/LibationAvalonia/Program.cs index 4c5f861b..e39a9603 100644 --- a/Source/LibationAvalonia/Program.cs +++ b/Source/LibationAvalonia/Program.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Threading.Tasks; using ApplicationServices; using Avalonia; @@ -52,12 +53,29 @@ namespace LibationAvalonia var classicLifetimeTask = Task.Run(() => new ClassicDesktopStyleApplicationLifetime()); var appBuilderTask = Task.Run(BuildAvaloniaApp); + if (Configuration.IsWindows) AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.WindowsAvalonia); else if (Configuration.IsLinux) - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.LinuxAvalonia); + { + var releaseID = RuntimeInformation.OSArchitecture switch + { + Architecture.X64 => AppScaffolding.ReleaseIdentifier.LinuxAvalonia, + Architecture.Arm64 => AppScaffolding.ReleaseIdentifier.LinuxAvalonia_Arm64, + _ => throw new PlatformNotSupportedException() + }; + AppScaffolding.LibationScaffolding.SetReleaseIdentifier(releaseID); + } else if (Configuration.IsMacOs) - AppScaffolding.LibationScaffolding.SetReleaseIdentifier(AppScaffolding.ReleaseIdentifier.MacOSAvalonia); + { + var releaseID = RuntimeInformation.OSArchitecture switch + { + Architecture.X64 => AppScaffolding.ReleaseIdentifier.MacOSAvalonia, + Architecture.Arm64 => AppScaffolding.ReleaseIdentifier.MacOSAvalonia_Arm64, + _ => throw new PlatformNotSupportedException() + }; + AppScaffolding.LibationScaffolding.SetReleaseIdentifier(releaseID); + } else return; diff --git a/Source/LibationAvalonia/Views/MainWindow.Update.cs b/Source/LibationAvalonia/Views/MainWindow.Update.cs index a6858d94..e466c41a 100644 --- a/Source/LibationAvalonia/Views/MainWindow.Update.cs +++ b/Source/LibationAvalonia/Views/MainWindow.Update.cs @@ -20,13 +20,16 @@ namespace LibationAvalonia.Views { if (upgradeProperties.ZipUrl is null) { - Serilog.Log.Logger.Information("Download link for new version not found"); + Serilog.Log.Logger.Warning("Download link for new version not found"); return null; } //Silently download the update in the background, save it to a temp file. var zipFile = Path.Combine(Path.GetTempPath(), Path.GetFileName(upgradeProperties.ZipUrl)); + + Serilog.Log.Logger.Information($"Downloading {zipFile}"); + try { System.Net.Http.HttpClient cli = new(); @@ -55,6 +58,9 @@ namespace LibationAvalonia.Views var interop = InteropFactory.Create(); + if (!interop.CanUpdate) + Serilog.Log.Logger.Information("Can't perform update automatically"); + var notificationResult = await new UpgradeNotificationDialog(upgradeProperties, interop.CanUpdate).ShowDialog(this); if (notificationResult == DialogResult.Ignore) @@ -68,7 +74,9 @@ namespace LibationAvalonia.Views if (string.IsNullOrEmpty(updateBundle) || !File.Exists(updateBundle)) return; //Install the update + Serilog.Log.Logger.Information($"Begin running auto-updater"); interop.InstallUpdate(updateBundle); + Serilog.Log.Logger.Information($"Completed running auto-updater"); } catch (Exception ex) { diff --git a/Source/LoadByOS/LinuxConfigApp/Libation.desktop b/Source/LoadByOS/LinuxConfigApp/Libation.desktop index 0b935ce8..2890481c 100644 --- a/Source/LoadByOS/LinuxConfigApp/Libation.desktop +++ b/Source/LoadByOS/LinuxConfigApp/Libation.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Name=Libation -Exec=libation +Exec=/usr/bin/libation Icon=libation Comment=Liberate your Audiobooks Terminal=false diff --git a/Source/LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj b/Source/LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj index 9d9a1b3e..855b7034 100644 --- a/Source/LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj +++ b/Source/LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj @@ -35,27 +35,15 @@ - - True - True - Resources.resx - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - + Always Always + + Always + - \ No newline at end of file + diff --git a/Source/LoadByOS/LinuxConfigApp/LinuxInterop.cs b/Source/LoadByOS/LinuxConfigApp/LinuxInterop.cs index 7c36dda8..3ff64786 100644 --- a/Source/LoadByOS/LinuxConfigApp/LinuxInterop.cs +++ b/Source/LoadByOS/LinuxConfigApp/LinuxInterop.cs @@ -1,43 +1,45 @@ using LibationFileManager; using System.Diagnostics; +using System.Reflection; namespace LinuxConfigApp { - internal class LinuxInterop : IInteropFunctions - { + internal class LinuxInterop : IInteropFunctions + { //Different terminal apps possibly installed on a linux system // [0] console executable // [1] argument to set the concole's title // [2] argument to pass a command to be executed to the terminal static readonly string[][] consoleCommands = - { - new[] {"konsole", "--title", "-e"}, - new[] {"gnome-terminal", "--title", "--"}, - new[] {"mate-terminal", "--title", "-x"}, - new[] {"xterm", "-T", "-e"}, - }; + { + new[] {"konsole", "--title", "-e"}, + new[] {"gnome-terminal", "--title", "--"}, + new[] {"mate-terminal", "--title", "-x"}, + new[] {"xterm", "-T", "-e"}, + }; public LinuxInterop() { } - public LinuxInterop(params object[] values) { } + public LinuxInterop(params object[] values) { } - public void SetFolderIcon(string image, string directory) => throw new PlatformNotSupportedException(); - public void DeleteFolderIcon(string directory) => throw new PlatformNotSupportedException(); + public void SetFolderIcon(string image, string directory) => throw new PlatformNotSupportedException(); + public void DeleteFolderIcon(string directory) => throw new PlatformNotSupportedException(); - //only run the audo updater is the current app was installed from the - //.deb package. Try to detect this by checking if the symlink exists. - public bool CanUpdate => Directory.Exists("/usr/lib/libation"); - public void InstallUpdate(string updateBundle) + //only run the auto updater if the current app was installed from the + //.deb package. Try to detect this by checking if the symlink exists. + public bool CanUpdate => Directory.Exists("/usr/lib/libation"); + public void InstallUpdate(string updateBundle) { RunAsRoot("apt", $"install '{updateBundle}'"); } public Process RunAsRoot(string exe, string args) - { + { //cribbed this script from VirtualBox's guest additions installer. //It's designed to launch the system's gui superuser password //prompt across multiple distributions and desktop environments. - const string runasroot = "/tmp/runasroot.sh"; - File.WriteAllBytes(runasroot, Properties.Resources.runasroot); + const string runasroot = "runasroot.sh"; + + var asmDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string command = $"{exe ?? ""} {args ?? ""}".Trim(); @@ -50,24 +52,23 @@ namespace LinuxConfigApp ArgumentList = { console[1], - $"Running '{exe}' as root", + $"Running '{exe}' as root", // console title console[2], "/bin/sh", - runasroot, - "Installing libation.deb", - command, - $"Please run '{command}' manually" + Path.Combine(asmDir, runasroot), //script file + "Installing libation.deb", //command title + command, // command to execute vis /bin/sh + $"Please run '{command}' manually" // error message to display in the terminal } }; - try { return Process.Start(psi); } catch { } } - return null; + throw new PlatformNotSupportedException($"Could not start any of the supported terminals: {string.Join(", ", consoleCommands.Select(c => c[0]))}"); } } } diff --git a/Source/LoadByOS/LinuxConfigApp/Properties/Resources.Designer.cs b/Source/LoadByOS/LinuxConfigApp/Properties/Resources.Designer.cs deleted file mode 100644 index b48060ab..00000000 --- a/Source/LoadByOS/LinuxConfigApp/Properties/Resources.Designer.cs +++ /dev/null @@ -1,73 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace LinuxConfigApp.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LinuxConfigApp.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] runasroot { - get { - object obj = ResourceManager.GetObject("runasroot", resourceCulture); - return ((byte[])(obj)); - } - } - } -} diff --git a/Source/LoadByOS/LinuxConfigApp/Properties/Resources.resx b/Source/LoadByOS/LinuxConfigApp/Properties/Resources.resx deleted file mode 100644 index ef269a0f..00000000 --- a/Source/LoadByOS/LinuxConfigApp/Properties/Resources.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\runasroot.sh;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Source/LoadByOS/LinuxConfigApp/glass-with-glow_256.svg b/Source/LoadByOS/LinuxConfigApp/glass-with-glow_256.svg deleted file mode 100644 index df935c14..00000000 --- a/Source/LoadByOS/LinuxConfigApp/glass-with-glow_256.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - diff --git a/Source/LoadByOS/LinuxConfigApp/libation_glass.svg b/Source/LoadByOS/LinuxConfigApp/libation_glass.svg new file mode 100644 index 00000000..db08f07f --- /dev/null +++ b/Source/LoadByOS/LinuxConfigApp/libation_glass.svg @@ -0,0 +1,28 @@ + + + + + diff --git a/Source/LoadByOS/LinuxConfigApp/Resources/runasroot.sh b/Source/LoadByOS/LinuxConfigApp/runasroot.sh similarity index 100% rename from Source/LoadByOS/LinuxConfigApp/Resources/runasroot.sh rename to Source/LoadByOS/LinuxConfigApp/runasroot.sh diff --git a/Source/LoadByOS/MacOSConfigApp/Info.plist b/Source/LoadByOS/MacOSConfigApp/Info.plist index 90cbcaf1..b9d85062 100644 --- a/Source/LoadByOS/MacOSConfigApp/Info.plist +++ b/Source/LoadByOS/MacOSConfigApp/Info.plist @@ -7,6 +7,10 @@ Libation CFBundleName Libation + LSArchitecturePriority + ARCHITECTURE_STRING + LSMinimumSystemVersion + 10.15.0 CFBundleIdentifier org.libation.macos NSHighResolutionCapable diff --git a/Source/LoadByOS/MacOSConfigApp/MacOSInterop.cs b/Source/LoadByOS/MacOSConfigApp/MacOSInterop.cs index 8bf6f9a3..a8993345 100644 --- a/Source/LoadByOS/MacOSConfigApp/MacOSInterop.cs +++ b/Source/LoadByOS/MacOSConfigApp/MacOSInterop.cs @@ -21,7 +21,7 @@ namespace MacOSConfigApp Serilog.Log.Information($"Extracting update bundle to {AppPath}"); //tar wil overwrite existing without elevated privileges - Process.Start("tar", $"-xzf \"{updateBundle}\" -C \"/Applications\"").WaitForExit(); + Process.Start("tar", $"-xf \"{updateBundle}\" -C \"/Applications\"").WaitForExit(); //For now, it seems like this step is unnecessary. We can overwrite and //run Libation without needing to re-add the exception. This is insurance.